Skip to content

AgentSession: Orchestrierungsschicht des Coding-Agent

源码版本v0.73.1

AgentSession ist die schwerste Schicht in pi-coding-agent - sie betreibt weder direkt den LLM noch rendert sie direkt die UI, sondern liegt dazwischen: nach oben empfängt sie Nutzereingaben und UI-Events; nach unten treibt sie den Agent von pi-agent-core an, um die Schleife zu laufen. Modell-Registrierung, Werkzeugdefinitionen, Systemprompt-Aufbau, Kontext-Kompression, Fehler-Retry, Nachrichten-Warteschlange gehören alle zu ihr. Man kann es als eine Montage-Werkstatt verstehen, die einen generischen Agent in einen zustandsbehafteten, wiederherstellbaren, mit Skills und Werkzeugen ausgestatteten Coding-Assistenten verwandelt.

Verantwortung

AgentSession macht vier Dinge:

  1. Zusammenbau: AgentSessionConfig nimmt eine Agent-Instanz, Modell-Registry, Werkzeugdefinitionen, Extension-Runtime und Systemprompt-Builder auf; beim Konstruieren werden beforeToolCall/afterToolCall-Hooks und Event-Subscription eingehängt. Siehe packages/coding-agent/src/core/agent-session.ts:313-330.
  2. Eingaben empfangen: prompt(text) ist der Haupteingang, verarbeitet /-Slash-Befehle, klappt dateibasierte Prompt-Templates auf, wandelt Text in AgentMessage[] um und übergibt an den darunterliegenden Agent. Siehe packages/coding-agent/src/core/agent-session.ts:967-1000.
  3. Event-Weiterleitung: Abonniert den Event-Stream des Agent, verpackt ihn als AgentSessionEvent und schickt ihn an die obere UI. Siehe packages/coding-agent/src/core/agent-session.ts:330-335.
  4. Warteschlange und Retry: Wenn der Nutzer während des Streamings weiter tippt, entscheidet streamingBehavior, ob es als steer (Einwurf) oder followUp (Warteschlange) läuft, statt einfach zu verwerfen oder zu blockieren. Siehe packages/coding-agent/src/core/agent-session.ts:1181-1296.

Entwurfsmotivation

Warum nicht die UI direkt Agent.prompt aufrufen lassen? Weil ein Coding-Assistent eine Reihe von Querschnitts-Logik braucht, die "den generischen Agent nichts angeht": Slash-Befehle (/model, /settings), Prompt-Templates, Modell/API-Key-Prüfung, automatische Kompression bei zu langem Kontext, Auth und Telemetrie vor und nach Werkzeugaufrufen. Das alles in Agent zu stopfen, würde die generische Schleife schwer machen; auf die UI-Schicht zu legen, würde in print-Modus, rpc-Modus und Extensions dupliziert. AgentSession wird als einziger Eingang herausgezogen, die drei Laufmodi teilen sich dieselbe Orchestrierungslogik, die UI kümmert sich nur ums Rendern der Events.

Wichtige Dateien

Der Konstruktor hängt Hooks ein und abonniert, das ist der Startpunkt der gesamten Orchestrierung:

typescript
// packages/coding-agent/src/core/agent-session.ts:313-335
constructor(config: AgentSessionConfig) {
  // ... config speichern, Zustand initialisieren ...
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
  // ... uebersprungen ...
}

prompt macht aus Nutzertext ein AgentMessage[] und übergibt an den darunterliegenden Agent:

typescript
// packages/coding-agent/src/core/agent-session.ts:1107-1112
  try {
    await this.agent.prompt(messages);
  } catch (error) {
    // ... Fehlerbehandlung ...
  }

Datenfluss

Nutzer drückt im TUI-Editor Enter → InteractiveMode.defaultEditor.onSubmitsession.prompt(text):

Wenn der Nutzer während des Streamings weiter tippt, drückt prompt nicht einfach durch, sondern verteilt:

Grenzen und Fehler

  • Slash-Befehl-Konflikt: Ein von einer Extension registrierter Befehl kann auch während des Streamings sofort ausgeführt werden (er verwaltet seine eigene LLM-Interaktion), geht nicht durch die Warteschlange. Wenn ein Befehl nicht in eine Warteschlange kann, wird direkt ein Fehler geworfen, siehe packages/coding-agent/src/core/agent-session.ts:1255-1259.
  • Modell/Key fehlt: Der nicht-streaming Pfad prüft Modell und API-Key, bei Fehlen wird ein Fehler geworfen statt eine leere Anfrage zu senden.
  • Kompression abgebrochen: abort bricht gleichzeitig die Hauptschleife, den Kompressions-Controller und den Branch-Summary-Controller ab, siehe packages/coding-agent/src/core/agent-session.ts:1744-1752.
  • Retry: Agent.emit() ruft synchron _handleAgentEvent auf, während prompt() mit waitForRetry() wartet, nach einem Fehler entscheidet die Retry-Logik, ob ein neuer Turn gesendet wird.

Zusammenfassung

AgentSession ist die "Montage-Werkstatt plus Event-Bus" des Coding-Assistenten: baut Agent zusammen, leitet Events weiter, reiht Einwürfe ein, verwaltet Werkzeug-Hooks. Nach oben sind das die drei UI-Modi InteractiveMode/runPrintMode/runRpcMode, nach unten die generische Schleife von pi-agent-core. Zusammenbau-Details siehe createAgentSession Zusammenbau; die darunterliegende Schleife siehe Doppelte while-Hauptschleife.