Skip to content

ChatPanel: layout de nivel superior y ensamblaje de herramientas

源码版本v0.73.1

ChatPanel es el customElement de nivel superior de pi-web-ui (<pi-chat-panel>). No corre la sesión; ensambla AgentInterface, ArtifactsPanel y toolsFactory: recibe el Agent externo, crea el child agent-interface y le asigna session, alterna entre layouts de artifacts "lado a lado" y "overlay" según el ancho de pantalla, y llama a toolsFactory para que el host inyecte AgentTool adicionales.

Responsabilidades

  1. Mantener agent y agentInterface: @state agent y @state agentInterface; agent lo pasa el host, agentInterface se crea con document.createElement en setAgent. Ver packages/web-ui/src/ChatPanel.ts:17-25.
  2. Ensamlar host de sesión: setAgent crea el AgentInterface, fija los callbacks enableAttachments/onApiKeyRequired/onBeforeSend y cuelga el agent como session. Ver packages/web-ui/src/ChatPanel.ts:56-85.
  3. Ensamlar panel de artifacts: new ArtifactsPanel(), inyecta sandboxUrlProvider, registra ArtifactsToolRenderer en la registry de renderers. Ver packages/web-ui/src/ChatPanel.ts:86-94.
  4. Construir runtime providers: runtimeProvidersFactory agrega los attachments del historial de sesión en un AttachmentsRuntimeProvider, más un ArtifactsRuntimeProvider readable/writable, para que las herramientas REPL los consuman. Ver packages/web-ui/src/ChatPanel.ts:96-116.
  5. Layout responsivo: si windowWidth < 800 va a overlay; si no, lado a lado 50/50; cuando artifacts está colapsado se muestra un pill flotante. Ver packages/web-ui/src/ChatPanel.ts:159-208.

Motivación de diseño

¿Por qué el ensamblaje del ArtifactsPanel está en ChatPanel y no en AgentInterface? Porque artifacts es un concepto de la dimensión "producto de sesión", desacoplado del render de la lista de mensajes: AgentInterface sólo mira el flujo de mensajes; ArtifactsPanel sólo mira los mensajes artifact y mantiene su propio Map de artifacts. Ambos comparten datos a través de agent.state, pero sus ciclos de vida y posiciones de UI son distintos. ChatPanel como capa de layout los ensambla y a la vez expone toolsFactory al host, para que el host pueda inyectar herramientas de negocio (p. ej. query_database para una app concreta) sin tocar el código de pi-web-ui.

BREAKPOINT = 800 es un valor empírico: en pantallas estrechas los artifacts cubren toda el área de chat para evitar que las dos columnas queden ilegibles; en anchas se muestran lado a lado para charlar y ver productos a la vez. overlay y collapsed los empuja ChatPanel desde render hacia ArtifactsPanel, en vez de dejar que el panel escuche el resize, para concentrar las decisiones de layout en el nivel superior.

Archivos clave

En setAgent la creación del AgentInterface y la inyección de callbacks es la juntura entre host y host de sesión:

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 permite al host inyectar herramientas adicionales, mientras que la herramienta de artifacts siempre se añade primero:

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;

Flujo de datos

setAgent es la línea principal que ensambla el Agent pasado por el host en una UI usable:

El cambio de layout lo conduce el estado evaluado en render:

Límites y fallos

  • Agent sin setear: render muestra "No agent set", evitando crashear cuando agentInterface es undefined. Ver packages/web-ui/src/ChatPanel.ts:160-164.
  • Suprime auto-expansión en reconstrucción: antes de reconstructFromMessages se pone onArtifactsChange a null temporalmente, evitando que los artifacts históricos disparen el panel automáticamente. Ver packages/web-ui/src/ChatPanel.ts:148-151.
  • Cuenta de artifacts en 0: hasArtifacts=false, showArtifactsPanel=false, el pill no se renderiza y el panel derecho se oculta.
  • Sólo auto-expande artifacts nuevos: sólo cuando count > artifactCount se pone showArtifactsPanel a true, evitando que artifacts ya presentes al reaparecer fuercen el popup. Ver packages/web-ui/src/ChatPanel.ts:118-127.
  • Limpieza del listener resize: disconnectedCallback quita el listener de window.resize para evitar leaks. Ver packages/web-ui/src/ChatPanel.ts:51-54.

Resumen

ChatPanel es la capa de layout + taller de ensamblaje: monta AgentInterface, ArtifactsPanel y toolsFactory, y alterna layout según el ancho de ventana. Hacia dentro está host de sesión AgentInterface; el mecanismo de registro de render de herramientas en registro de renderers de herramientas.