import { html } from "@mariozechner/mini-lit"; import type { AgentTool, AssistantMessage as AssistantMessageType, ToolResultMessage as ToolResultMessageType, } from "@mariozechner/pi-ai"; import { LitElement, type TemplateResult } from "lit"; import { property } from "lit/decorators.js"; import { repeat } from "lit/directives/repeat.js"; import type { AppMessage } from "./Messages.js"; import { renderMessage } from "./message-renderer-registry.js"; export class MessageList extends LitElement { @property({ type: Array }) messages: AppMessage[] = []; @property({ type: Array }) tools: AgentTool[] = []; @property({ type: Object }) pendingToolCalls?: Set; @property({ type: Boolean }) isStreaming: boolean = false; protected override createRenderRoot(): HTMLElement | DocumentFragment { return this; } override connectedCallback(): void { super.connectedCallback(); this.style.display = "block"; } private buildRenderItems() { // Map tool results by call id for quick lookup const resultByCallId = new Map(); for (const message of this.messages) { if (message.role === "toolResult") { resultByCallId.set(message.toolCallId, message); } } const items: Array<{ key: string; template: TemplateResult }> = []; let index = 0; for (const msg of this.messages) { // Skip artifact messages - they're for session persistence only, not UI display if (msg.role === "artifact") { continue; } // Try custom renderer first const customTemplate = renderMessage(msg); if (customTemplate) { items.push({ key: `msg:${index}`, template: customTemplate }); index++; continue; } // Fall back to built-in renderers if (msg.role === "user") { items.push({ key: `msg:${index}`, template: html``, }); index++; } else if (msg.role === "assistant") { const amsg = msg as AssistantMessageType; items.push({ key: `msg:${index}`, template: html``, }); index++; } else { // Skip standalone toolResult messages; they are rendered via paired tool-message above // Skip unknown roles } } return items; } override render() { const items = this.buildRenderItems(); return html`
${repeat( items, (it) => it.key, (it) => it.template, )}
`; } } // Register custom element if (!customElements.get("message-list")) { customElements.define("message-list", MessageList); }