Wie es funktioniert
AgentRuntimeInterface ist die öffentliche Schnittstelle. run() führt synchron aus. enqueue() speichert eine QUEUED-Zeile mit dem serialisierten Request und verschickt eine AgentRunQueuedMessage. approve(), submitInput() und cancel() wirken auf einen Lauf anhand seiner UUID. Weder run() noch approve() werfen eine Exception für das Ergebnis eines Laufs: Das AgentRunResult ist bereits abgeschlossen und meldet COMPLETED, AWAITING_APPROVAL, AWAITING_INPUT, FAILED und weitere Fälle. AgentRunQueuedHandler ruft runQueued() auf. Diese Methode übernimmt die Zeile atomar, sodass genau ein Worker den Lauf bekommt. Der Lauf wird unter der Identität der Person ausgeführt, die ihn gestartet hat – auch auf einem Worker.
Ein Worker hält eine Lease von AgentRuntime::LEASE_SECONDS (900) und erneuert sie an jeder Schrittgrenze. Bevor ein schreibendes Tool läuft, vermerkt der Executor dessen Wirkung an der Zeile des Laufs. Ein Lauf, der mitten in einem NON_IDEMPOTENT_WRITE gefunden wird, landet als Dead Letter und wird nie wiederholt. Andere wiederholbare Fehler gehen mit exponentiellem Backoff zurück in die Queue, höchstens AgentRuntime::MAX_REQUEUES-mal. Der Abbruch ist kooperativ: Der Executor liest die Zeile an jeder Schrittgrenze und hält an, sobald sie CANCELLED ist. Ein MCP-Aufruf über HTTP lässt sich zusätzlich mitten in der Übertragung über AgentRunCancellationSignal abbrechen, wenn der nr-vault-Client das unterstützt.
ToolApprovalRule entscheidet, ob ein Aufruf einen Menschen braucht: der Marker RequiresApprovalInterface oder eine deklarierte Schreibwirkung aus ToolEffectInterface. MCP-Tools werden stattdessen nach der Angabe des Betreibers am Server-Datensatz beurteilt. Beim Anhalten speichert die Schleife die Zeilen aus ToolPreviewInterface für jeden offenen Aufruf mit dem Zustand. ResumeCoordinator::approve() übernimmt dann den Lauf und prüft drei Gates, bevor etwas ausgeführt wird: Der Turn-Digest der Entscheidung muss zu den offenen Aufrufen passen. Wer freigibt, muss jeden offenen Schreibvorgang ausführen dürfen. Und bei einem Turn, der einen Schreibvorgang deklariert, muss das APPROVAL-Ereignis gespeichert sein. Schlägt ein Gate fehl, steht der Lauf wieder auf WAITING_FOR_APPROVAL.
Bevor ein freigegebener Aufruf läuft, erzeugt ApprovalPreviewComparator seine Vorschau neu. Weichen die Zeilen von dem ab, was die freigebende Person gesehen hat, wird nichts geschrieben, und der Lauf hält erneut an – mit der aktuellen Vorschau. Ein schreibendes Tool gibt ToolResult::withWriteTarget() zurück. Das benennt den Datensatz, die WriteKind (CREATED, UPDATED, DELETED) und ob der Schreibvorgang vollständig war. Der Executor speichert das als Schritt tool_write. Lässt sich dieser Audit-Schritt nicht speichern, schlägt der Lauf fehl. Die Writer schreiben über ToolDataHandler: Ein Hook, der erst nach dem Schreiben aller Datensätze eine Exception wirft, macht aus einem fertigen Schreibvorgang keinen Fehler.
Netresearch\NrLlm\Service\Agent\AgentRuntimeInterface
Öffentlicher Lebenszyklus eines Laufs: run(), enqueue(), runQueued(), approve(), submitInput(), cancel(), status() und events(). Liefert abgeschlossene AgentRunResult-Werte, statt für Ergebnisse eine Exception zu werfen.
Netresearch\NrLlm\Service\Agent\Queue\AgentRunQueuedHandler
#[AsMessageHandler] für AgentRunQueuedMessage. Ruft runQueued() auf; die Methode übernimmt die QUEUED-Zeile atomar und stellt den gespeicherten Request wieder her.
Netresearch\NrLlm\Command\ReapStaleAgentRunsCommand
nrllm:agent:reap. Findet Läufe im Status RUNNING mit abgelaufener Lease, stellt solche mit gespeichertem Request und verbleibendem Budget zurück in die Queue und legt den Rest als Dead Letter ab.
Netresearch\NrLlm\Service\Agent\ResumeCoordinator
Entscheidet über einen wartenden Lauf: Zugriffs- und Vier-Augen-Prüfung vor der Übernahme, danach Turn-Digest, Berechtigung der freigebenden Person und Audit-Gate vor der Ausführung unter der Identität des Besitzers.
Netresearch\NrLlm\Service\Tool\ToolApprovalRule
Die eine Regel, wann ein Aufruf eine Freigabe braucht: Marker RequiresApprovalInterface oder deklarierte Schreibwirkung; Remote-Tools nach der Angabe am Server-Datensatz.
Netresearch\NrLlm\Service\Tool\ToolPreviewInterface
Opt-in für Tools: previewCall() beschreibt, was ein Aufruf tun würde; mayViewerReadPreview() entscheidet, ob die Person vor der Karte die Vorschau sehen darf. Vorschauen müssen deterministisch sein.
Netresearch\NrLlm\Service\Tool\ApprovalPreviewComparator
Erzeugt beim Fortsetzen die Vorschauen eines freigegebenen Turns neu. Bei einer geänderten Vorschau liefert sie einen erneut angehaltenen Zustand mit den aktuellen Zeilen, statt auszuführen.
Netresearch\NrLlm\Domain\ValueObject\ToolResult
Die Antwort eines Tools. withWriteTarget() nennt für den Audit-Stream des Laufs den geschriebenen Datensatz (RecordReference), seine WriteKind und seine WriteCompleteness.