Skip to content

ChatPanel: Top-Level-Layout und Tool-Verdrahtung

源码版本v0.73.1

ChatPanel ist das Top-Level-customElement (<pi-chat-panel>) von pi-web-ui. Es treibt selbst keine Konversation, sondern setzt AgentInterface, ArtifactsPanel und toolsFactory zusammen: Es nimmt den von außen übergebenen Agent, erzeugt ein agent-interface-Kindelement und weist ihm die session zu, schaltet je nach Bildschirmbreite zwischen „Side-by-side" und „Overlay"-Layout für die Artifacts um und ruft toolsFactory auf, damit der Host zusätzliche AgentTool injizieren kann.

Zuständigkeiten

  1. agent und agentInterface halten: Die Felder @state agent und @state agentInterface. agent wird vom Host übergeben, agentInterface in setAgent per document.createElement erzeugt. Siehe packages/web-ui/src/ChatPanel.ts:17-25.
  2. Session-Host verdrahten: setAgent erzeugt das AgentInterface, setzt die Callbacks enableAttachments/onApiKeyRequired/onBeforeSend und hängt den agent als session an. Siehe packages/web-ui/src/ChatPanel.ts:56-85.
  3. Artifacts-Panel verdrahten: new ArtifactsPanel(), injiziert sandboxUrlProvider, registriert den ArtifactsToolRenderer in der renderer registry. Siehe packages/web-ui/src/ChatPanel.ts:86-94.
  4. Runtime providers aufbauen: runtimeProvidersFactory fasst die Anhänge aus der Konversationshistorie in einem AttachmentsRuntimeProvider zusammen und fügt den read-write ArtifactsRuntimeProvider hinzu, damit REPL-Tools sie konsumieren können. Siehe packages/web-ui/src/ChatPanel.ts:96-116.
  5. Responsive Layout: windowWidth < 800 schaltet auf Overlay, sonst Side-by-side 50/50; bei eingeklappten Artifacts wird ein schwebendes Pill angezeigt. Siehe packages/web-ui/src/ChatPanel.ts:159-208.

Designmotivation

Warum wird die Verdrahtung des ArtifactsPanel in ChatPanel statt in AgentInterface gemacht? Weil Artifacts ein Konzept der Dimension „Konversationsprodukte" sind und von der Nachrichtenliste entkoppelt sind: AgentInterface sieht nur den Nachrichtenstrom, ArtifactsPanel sieht nur Artifact-Nachrichten und pflegt seine eigene artifacts-Map. Beide teilen Daten über agent.state, haben aber unterschiedliche Lebensdauer und UI-Position. ChatPanel baut sie als Layout-Schicht zusammen und gibt toolsFactory an den Host weiter, damit dieser fachliche Werkzeuge (z. B. query_database einer App) injizieren kann, ohne pi-web-ui-Quelle ändern zu müssen.

BREAKPOINT = 800 ist ein Erfahrungswert: Auf schmalen Bildschirmen überlagert das Artifacts-Panel den Chat vollflächig, damit nicht beide Spalten unleserlich zusammengedrückt werden; auf breiten Bildschirmen stehen sie Seite an Seite, damit man beim Chatten gleichzeitig die Produkte sieht. overlay und collapsed werden von ChatPanel in render an das ArtifactsPanel geschoben, anstatt das Panel selbst auf Window-Events zu hören — Layout-Entscheidungen bleiben an der Spitze konzentriert.

Wichtige Dateien

In setAgent sind Erzeugung des AgentInterface und Injektion der Callbacks die Naht zwischen Host und Session-Host:

typescript
// packages/web-ui/src/ChatPanel.ts:74-84
this.agentInterface = document.createElement("agent-interface") as AgentInterface;
this.agentInterface.session = agent;
this.agentInterface.enableAttachments = true;
this.agentInterface.enableModelSelector = true;
this.agentInterface.enableThinkingSelector = true;
this.agentInterface.showThemeToggle = false;
this.agentInterface.onApiKeyRequired = config?.onApiKeyRequired;
this.agentInterface.onModelSelect = config?.onModelSelect;
this.agentInterface.onBeforeSend = config?.onBeforeSend;
this.agentInterface.onCostClick = config?.onCostClick;

toolsFactory lässt den Host weitere Tools injizieren; das artifacts-Tool wird immer als erstes eingefügt:

typescript
// packages/web-ui/src/ChatPanel.ts:141-144
const additionalTools =
    config?.toolsFactory?.(agent, this.agentInterface, this.artifactsPanel, runtimeProvidersFactory) || [];
const tools = [this.artifactsPanel.tool, ...additionalTools];
this.agent.state.tools = tools;

Datenfluss

setAgent ist eine Hauptlinie, die den vom Host übergebenen Agent zu einer funktionierenden UI verdrahtet:

Der Layout-Wechsel wird von den Zustandsprüfungen in render angetrieben:

Randbedingungen und Fehler

  • agent nicht gesetzt: render zeigt direkt „No agent set", damit bei undefined agentInterface nichts crasht. Siehe packages/web-ui/src/ChatPanel.ts:160-164.
  • Auto-Aufklappen beim Wiederherstellen unterdrücken: Vor reconstructFromMessages wird onArtifactsChange temporär auf null gesetzt, damit historische Artifacts nicht das Panel automatisch aufklappen. Siehe packages/web-ui/src/ChatPanel.ts:148-151.
  • Artifacts-Anzahl ist 0: hasArtifacts=false, showArtifactsPanel=false, das Pill wird nicht gerendert, das rechte Panel versteckt.
  • Nur neue Artifact klappen auf: Nur wenn count > artifactCount, wird showArtifactsPanel auf true gesetzt, damit ein wieder auftauchendes, bereits bekanntes Artifact nicht das Panel aufzwingt. Siehe packages/web-ui/src/ChatPanel.ts:118-127.
  • resize-Listener aufräumen: disconnectedCallback entfernt den window.resize-Listener, kein Leak. Siehe packages/web-ui/src/ChatPanel.ts:51-54.

Zusammenfassung

ChatPanel ist Layout-Schicht und Verdrahtungswerkstatt: setzt AgentInterface, ArtifactsPanel und toolsFactory zusammen und schaltet das Layout nach Fensterbreite um. Nach innen liegt der AgentInterface Session-Host; wie das Render-Interface für Tools registriert wird, steht in Tool-Renderer-Registry.