diff --git a/packages/web-ui/src/ChatPanel.ts b/packages/web-ui/src/ChatPanel.ts index 507c4192..e8c728ab 100644 --- a/packages/web-ui/src/ChatPanel.ts +++ b/packages/web-ui/src/ChatPanel.ts @@ -79,7 +79,7 @@ export class ChatPanel extends LitElement { this.artifactsPanel.sandboxUrlProvider = this.sandboxUrlProvider; } // Register the standalone tool renderer (not the panel itself) - registerToolRenderer("artifacts", new ArtifactsToolRenderer()); + registerToolRenderer("artifacts", new ArtifactsToolRenderer(this.artifactsPanel)); // Attachments provider const getAttachments = () => { diff --git a/packages/web-ui/src/tools/artifacts/ArtifactPill.ts b/packages/web-ui/src/tools/artifacts/ArtifactPill.ts new file mode 100644 index 00000000..b57157fd --- /dev/null +++ b/packages/web-ui/src/tools/artifacts/ArtifactPill.ts @@ -0,0 +1,23 @@ +import { html, icon, type TemplateResult } from "@mariozechner/mini-lit"; +import { FileCode2 } from "lucide"; +import type { ArtifactsPanel } from "./artifacts.js"; + +export function ArtifactPill(filename: string, artifactsPanel?: ArtifactsPanel): TemplateResult { + const handleClick = () => { + if (!artifactsPanel) return; + // openArtifact will show the artifact and call onOpen() to open the panel if needed + (artifactsPanel as any).openArtifact(filename); + }; + + return html` +
+ ${icon(FileCode2, "sm")} + ${filename} +
+ `; +} diff --git a/packages/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts b/packages/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts index 83591dc1..3e7ec337 100644 --- a/packages/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts +++ b/packages/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts @@ -7,7 +7,8 @@ import "../../components/ConsoleBlock.js"; import { i18n } from "../../utils/i18n.js"; import { renderCollapsibleHeader, renderHeader } from "../renderer-registry.js"; import type { ToolRenderer } from "../types.js"; -import type { ArtifactsParams } from "./artifacts.js"; +import { ArtifactPill } from "./ArtifactPill.js"; +import type { ArtifactsPanel, ArtifactsParams } from "./artifacts.js"; // Helper to determine language for syntax highlighting function getLanguageFromFilename(filename?: string): string { @@ -47,6 +48,8 @@ function getLanguageFromFilename(filename?: string): string { } export class ArtifactsToolRenderer implements ToolRenderer { + constructor(public artifactsPanel?: ArtifactsPanel) {} + render( params: ArtifactsParams | undefined, result: ToolResultMessage | undefined, @@ -71,6 +74,11 @@ export class ArtifactsToolRenderer implements ToolRenderer { + return filename ? ArtifactPill(filename, this.artifactsPanel) : ""; + }; + // Error handling if (result?.isError) { const command = params?.command; @@ -78,7 +86,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
${content ? html`` : ""} ${ @@ -116,7 +125,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
@@ -137,6 +147,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
@@ -153,6 +164,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
${codeContent ? html`` : ""} ${isHtml && logs ? html`` : ""} @@ -165,6 +177,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderHeader(state, FileCode2, headerText)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
`; } @@ -179,7 +192,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
${ content @@ -202,6 +216,7 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
${ old_str !== undefined && new_str !== undefined @@ -217,13 +232,19 @@ export class ArtifactsToolRenderer implements ToolRenderer ${renderCollapsibleHeader(state, FileCode2, headerText, contentRef, chevronRef, false)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""}
`; case "delete": default: - return renderHeader(state, FileCode2, headerText); + return html` +
+ ${renderHeader(state, FileCode2, headerText)} + ${renderPill(filename) ? html`
${renderPill(filename)}
` : ""} +
+ `; } }