enhancement
major
minor
defect
critical
major
minor
major
#30164
TL-Chat: Ein Lauf, der mit einer Ausnahme fehlschlägt, hinterlässt keinen Fehler im Chat; er verschwindet nach einem Neuladen.
Problem
Ein Lauf, bei dem das ConversationBackend oder die Agentenschleife einen Fehler auslöst, endet mit RunRecording.fail (BackendRun.run, AgentRunner). RunRecording.fail durchläuft ExecutionRecorder.completeWithLatestTranscript, das nichts aufzeichnet, solange kein RunStarted erkannt wurde (die Ausführungszeile wird erst bei RunStarted erstellt), und nichts schreibt einen Part.ErrorPart: Dies geschieht nur durch ConversationLogListener.handleProviderError bei einem AgentEvent.ProviderError. ChatProcessor.AIBackgroundTask.notifyError sendet den „provider_error“-Frame ausschließlich an die Live-Seite.
Der Live-Chat zeigt also die Fehlerkarte an (und bewusst auch den Composer-Streifen – siehe das Kartendesign in chat-store.ts: „genau so aufgezeichnet, wie es eine wiedereröffnete Sitzung aufzeichnet“), aber nach einem Neuladen bleibt die Frage des Benutzers unbeantwortet und ohne Fehlermeldung. Nach einem Server-Neustart ist die Frage ebenfalls verschwunden.
Beobachtet in tl-factory (Gitea TopLogic/tl-factory #38): Das Backend des Coding-Agents eines Arbeitsbereichs lehnt die Ausführung für einen angehaltenen Arbeitsbereich mit einer „TopLogicException“ vor „RunStarted“ ab.
Änderung
RunRecording.fail protokolliert einen Fehler wie einen Provider-Fehler: Es eröffnet die Ausführungszeile, falls noch keine vorhanden ist, und fügt dem offenen Durchlauf des Laufs einen ErrorPart hinzu, bevor das Protokoll erfasst wird. Der Typ des Teils ist entweder „ProviderException“ oder „APPLICATION_ERROR“ (aus „ChatProcessor“ in „tl-ai-core“ verschoben), seine Meldung ist der I18NFailure-Text in der Sprache des Benutzers des Laufs. Der Live-Frame bleibt erhalten, sodass die Live- und die neu geladene Ansicht übereinstimmen.
Test
Ein ConversationBackend, das vor „RunStarted“ eine „TopLogicException“ auslöst: Die über „ChatHistoryService.loadConversationJson“ geladene Konversation enthält den Benutzerzug und ein „ErrorPart“ vom Typ „APPLICATION_ERROR“ mit der deutschen Meldung. Dasselbe gilt für eine Agenten-Schleife, die einen Fehler auslöst.
Lösung
- RunRecording.fail übermittelt den Fehler als AgentEvent.ProviderError über dieselbe Listener-Kette wie jedes andere Ereignis des Laufs (kein separater Eintrag in den Gesprächsverlauf): Art einer ProviderException, andernfalls APPLICATION_ERROR; message: der I18NFailure-Text in der Sprache des Benutzers des Laufs; messageKey: der Schlüssel des Fehlers. Jeder Listener erkennt den Fehler somit als Provider-Fehler, und der Ausführungsdatensatz sowie das Konversationsprotokoll können nicht voneinander abweichen. Weder nach einem „RunCompleted“ noch zweimal für denselben Fehler.
- Die Agentenschleife, die „RunCompleted(ERROR)“ meldet, bevor sie den Fehler erneut auslöst, liefert unmittelbar vor diesem Ereignis denselben „ProviderError “.
- RunFailure (tl-ai-core) erstellt das Ereignis und enthält APPLICATION_ERROR sowie die Ableitung von „kind“ und „message“; ChatProcessor nutzt dies. Der Wire-Wert APPLICATION_ERROR bleibt unverändert.
- „ConversationLogListener.handleProviderError“ eröffnet eine Gesprächsrunde, sofern noch keine geöffnet ist, sodass die Frage des Benutzers zusammen mit dem „ErrorPart“ aufgezeichnet wird.
- ExecutionRecorder erstellt bei einem Fehler vor RunStarted die Ausführungszeile (Agent, Sitzung, übergeordneter Prozess), sodass das Transkript mit Frage und Fehler gespeichert wird.
- Die Live-Seite erhält eine Fehlerkarte: Wenn der ProviderError den Listener des Durchlaufs passiert hat, sendet notifyError keinen zweiten provider_error-Frame.
- Eine Ablehnung aufgrund des Lauflimits (RunLimitExceededException, Budget oder Parallelität vor „RunStarted“) wird nicht als Fehler protokolliert: Der Chat beantwortet dies wie bisher mit dem Grund als Text des Agenten.
- Gilt für jeden Aufrufer von `RunRecording.fail ` (`AgentRunner`, `AIScriptFunctions`, `DelegationTool`); ein Subagent, dessen Schleife einen Fehler auslöst, zeigt den Fehler auf seiner Karte an.