@mariozechner/pi-web-ui 0.5.44 → 0.5.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -99
- package/dist/ChatPanel.d.ts +15 -10
- package/dist/ChatPanel.d.ts.map +1 -1
- package/dist/ChatPanel.js +68 -100
- package/dist/ChatPanel.js.map +1 -1
- package/dist/{state/agent-session.d.ts → agent/agent.d.ts} +23 -19
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/{state/agent-session.js → agent/agent.js} +50 -32
- package/dist/agent/agent.js.map +1 -0
- package/dist/{state → agent}/transports/AppTransport.d.ts +1 -3
- package/dist/agent/transports/AppTransport.d.ts.map +1 -0
- package/dist/{state → agent}/transports/AppTransport.js +5 -4
- package/dist/{state → agent}/transports/AppTransport.js.map +1 -1
- package/dist/{state → agent}/transports/ProviderTransport.d.ts +1 -3
- package/dist/agent/transports/ProviderTransport.d.ts.map +1 -0
- package/dist/{state → agent}/transports/ProviderTransport.js +6 -7
- package/dist/agent/transports/ProviderTransport.js.map +1 -0
- package/dist/{state → agent}/transports/index.d.ts.map +1 -1
- package/dist/agent/transports/index.js.map +1 -0
- package/dist/{state → agent}/transports/proxy-types.d.ts.map +1 -1
- package/dist/agent/transports/proxy-types.js.map +1 -0
- package/dist/agent/transports/types.d.ts +12 -0
- package/dist/agent/transports/types.d.ts.map +1 -0
- package/dist/{state → agent}/transports/types.js.map +1 -1
- package/dist/{state → agent}/types.d.ts.map +1 -1
- package/dist/{state → agent}/types.js.map +1 -1
- package/dist/app.css +1 -1
- package/dist/components/AgentInterface.d.ts +7 -4
- package/dist/components/AgentInterface.d.ts.map +1 -1
- package/dist/components/AgentInterface.js +29 -17
- package/dist/components/AgentInterface.js.map +1 -1
- package/dist/components/ConsoleBlock.d.ts +1 -0
- package/dist/components/ConsoleBlock.d.ts.map +1 -1
- package/dist/components/ConsoleBlock.js +7 -1
- package/dist/components/ConsoleBlock.js.map +1 -1
- package/dist/components/ExpandableSection.d.ts +15 -0
- package/dist/components/ExpandableSection.d.ts.map +1 -0
- package/dist/components/ExpandableSection.js +63 -0
- package/dist/components/ExpandableSection.js.map +1 -0
- package/dist/components/MessageEditor.d.ts +8 -1
- package/dist/components/MessageEditor.d.ts.map +1 -1
- package/dist/components/MessageEditor.js +149 -6
- package/dist/components/MessageEditor.js.map +1 -1
- package/dist/components/MessageList.d.ts +3 -2
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +14 -1
- package/dist/components/MessageList.js.map +1 -1
- package/dist/components/Messages.d.ts +15 -6
- package/dist/components/Messages.d.ts.map +1 -1
- package/dist/components/Messages.js +17 -83
- package/dist/components/Messages.js.map +1 -1
- package/dist/components/ProviderKeyInput.d.ts.map +1 -1
- package/dist/components/ProviderKeyInput.js +6 -5
- package/dist/components/ProviderKeyInput.js.map +1 -1
- package/dist/components/SandboxedIframe.d.ts +29 -7
- package/dist/components/SandboxedIframe.d.ts.map +1 -1
- package/dist/components/SandboxedIframe.js +350 -282
- package/dist/components/SandboxedIframe.js.map +1 -1
- package/dist/components/message-renderer-registry.d.ts +12 -0
- package/dist/components/message-renderer-registry.d.ts.map +1 -0
- package/dist/components/message-renderer-registry.js +12 -0
- package/dist/components/message-renderer-registry.js.map +1 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +35 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js +189 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +17 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js +64 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +42 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.js +161 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +30 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js +97 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/RuntimeMessageBridge.d.ts +19 -0
- package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -0
- package/dist/components/sandbox/RuntimeMessageBridge.js +74 -0
- package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -0
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts +65 -0
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -0
- package/dist/components/sandbox/RuntimeMessageRouter.js +168 -0
- package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +33 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.js +2 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.js.map +1 -0
- package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -1
- package/dist/dialogs/ApiKeyPromptDialog.js +2 -5
- package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -1
- package/dist/dialogs/ModelSelector.js.map +1 -1
- package/dist/dialogs/PersistentStorageDialog.d.ts +17 -0
- package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -0
- package/dist/dialogs/PersistentStorageDialog.js +144 -0
- package/dist/dialogs/PersistentStorageDialog.js.map +1 -0
- package/dist/dialogs/SessionListDialog.d.ts +19 -0
- package/dist/dialogs/SessionListDialog.d.ts.map +1 -0
- package/dist/dialogs/SessionListDialog.js +152 -0
- package/dist/dialogs/SessionListDialog.js.map +1 -0
- package/dist/dialogs/SettingsDialog.d.ts.map +1 -1
- package/dist/dialogs/SettingsDialog.js +1 -0
- package/dist/dialogs/SettingsDialog.js.map +1 -1
- package/dist/index.d.ts +34 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -14
- package/dist/index.js.map +1 -1
- package/dist/prompts/prompts.d.ts +11 -0
- package/dist/prompts/prompts.d.ts.map +1 -0
- package/dist/prompts/prompts.js +272 -0
- package/dist/prompts/prompts.js.map +1 -0
- package/dist/storage/app-storage.d.ts +17 -12
- package/dist/storage/app-storage.d.ts.map +1 -1
- package/dist/storage/app-storage.js +13 -20
- package/dist/storage/app-storage.js.map +1 -1
- package/dist/storage/backends/indexeddb-storage-backend.d.ts +27 -0
- package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -0
- package/dist/storage/backends/indexeddb-storage-backend.js +166 -0
- package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -0
- package/dist/storage/store.d.ts +23 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +26 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/stores/provider-keys-store.d.ts +14 -0
- package/dist/storage/stores/provider-keys-store.d.ts.map +1 -0
- package/dist/storage/stores/provider-keys-store.js +27 -0
- package/dist/storage/stores/provider-keys-store.js.map +1 -0
- package/dist/storage/stores/sessions-store.d.ts +31 -0
- package/dist/storage/stores/sessions-store.d.ts.map +1 -0
- package/dist/storage/stores/sessions-store.js +113 -0
- package/dist/storage/stores/sessions-store.js.map +1 -0
- package/dist/storage/stores/settings-store.d.ts +14 -0
- package/dist/storage/stores/settings-store.d.ts.map +1 -0
- package/dist/storage/stores/settings-store.js +28 -0
- package/dist/storage/stores/settings-store.js.map +1 -0
- package/dist/storage/types.d.ts +156 -22
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.d.ts +0 -1
- package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.js +0 -1
- package/dist/tools/artifacts/ArtifactElement.js.map +1 -1
- package/dist/tools/artifacts/ArtifactPill.d.ts +4 -0
- package/dist/tools/artifacts/ArtifactPill.d.ts.map +1 -0
- package/dist/tools/artifacts/ArtifactPill.js +22 -0
- package/dist/tools/artifacts/ArtifactPill.js.map +1 -0
- package/dist/tools/artifacts/Console.d.ts +18 -0
- package/dist/tools/artifacts/Console.d.ts.map +1 -0
- package/dist/tools/artifacts/Console.js +95 -0
- package/dist/tools/artifacts/Console.js.map +1 -0
- package/dist/tools/artifacts/DocxArtifact.d.ts +22 -0
- package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/DocxArtifact.js +208 -0
- package/dist/tools/artifacts/DocxArtifact.js.map +1 -0
- package/dist/tools/artifacts/ExcelArtifact.d.ts +24 -0
- package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/ExcelArtifact.js +216 -0
- package/dist/tools/artifacts/ExcelArtifact.js.map +1 -0
- package/dist/tools/artifacts/GenericArtifact.d.ts +19 -0
- package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/GenericArtifact.js +117 -0
- package/dist/tools/artifacts/GenericArtifact.js.map +1 -0
- package/dist/tools/artifacts/HtmlArtifact.d.ts +8 -11
- package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/HtmlArtifact.js +56 -88
- package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
- package/dist/tools/artifacts/ImageArtifact.d.ts +20 -0
- package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/ImageArtifact.js +120 -0
- package/dist/tools/artifacts/ImageArtifact.js.map +1 -0
- package/dist/tools/artifacts/MarkdownArtifact.d.ts +0 -1
- package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/MarkdownArtifact.js +0 -4
- package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.d.ts +25 -0
- package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/PdfArtifact.js +184 -0
- package/dist/tools/artifacts/PdfArtifact.js.map +1 -0
- package/dist/tools/artifacts/SvgArtifact.d.ts +0 -1
- package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/SvgArtifact.js +0 -4
- package/dist/tools/artifacts/SvgArtifact.js.map +1 -1
- package/dist/tools/artifacts/TextArtifact.d.ts +0 -1
- package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/TextArtifact.js +0 -4
- package/dist/tools/artifacts/TextArtifact.js.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts +11 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.js +262 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -0
- package/dist/tools/artifacts/artifacts.d.ts +10 -13
- package/dist/tools/artifacts/artifacts.d.ts.map +1 -1
- package/dist/tools/artifacts/artifacts.js +166 -344
- package/dist/tools/artifacts/artifacts.js.map +1 -1
- package/dist/tools/artifacts/index.d.ts +1 -0
- package/dist/tools/artifacts/index.d.ts.map +1 -1
- package/dist/tools/artifacts/index.js +1 -0
- package/dist/tools/artifacts/index.js.map +1 -1
- package/dist/tools/extract-document.d.ts +24 -0
- package/dist/tools/extract-document.d.ts.map +1 -0
- package/dist/tools/extract-document.js +193 -0
- package/dist/tools/extract-document.js.map +1 -0
- package/dist/tools/index.d.ts +9 -7
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +17 -13
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/javascript-repl.d.ts +16 -15
- package/dist/tools/javascript-repl.d.ts.map +1 -1
- package/dist/tools/javascript-repl.js +101 -133
- package/dist/tools/javascript-repl.js.map +1 -1
- package/dist/tools/renderer-registry.d.ts +12 -0
- package/dist/tools/renderer-registry.d.ts.map +1 -1
- package/dist/tools/renderer-registry.js +78 -0
- package/dist/tools/renderer-registry.js.map +1 -1
- package/dist/tools/renderers/BashRenderer.d.ts +2 -4
- package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/BashRenderer.js +30 -26
- package/dist/tools/renderers/BashRenderer.js.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.d.ts +2 -4
- package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.js +32 -28
- package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.d.ts +2 -4
- package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.js +78 -18
- package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts +2 -4
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.js +57 -21
- package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
- package/dist/tools/types.d.ts +5 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/i18n.d.ts +424 -1
- package/dist/utils/i18n.d.ts.map +1 -1
- package/dist/utils/i18n.js +131 -7
- package/dist/utils/i18n.js.map +1 -1
- package/example/package.json +2 -1
- package/example/src/custom-messages.ts +112 -0
- package/example/src/main.ts +391 -38
- package/package.json +48 -43
- package/scripts/count-prompt-tokens.ts +88 -0
- package/src/ChatPanel.ts +93 -101
- package/src/{state/agent-session.ts → agent/agent.ts} +80 -55
- package/src/{state → agent}/transports/AppTransport.ts +6 -6
- package/src/{state → agent}/transports/ProviderTransport.ts +13 -7
- package/src/{state → agent}/transports/types.ts +8 -2
- package/src/components/AgentInterface.ts +32 -16
- package/src/components/ConsoleBlock.ts +5 -1
- package/src/components/ExpandableSection.ts +46 -0
- package/src/components/MessageEditor.ts +159 -5
- package/src/components/MessageList.ts +18 -3
- package/src/components/Messages.ts +48 -89
- package/src/components/ProviderKeyInput.ts +6 -5
- package/src/components/SandboxedIframe.ts +412 -321
- package/src/components/message-renderer-registry.ts +28 -0
- package/src/components/sandbox/ArtifactsRuntimeProvider.ts +219 -0
- package/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
- package/src/components/sandbox/ConsoleRuntimeProvider.ts +187 -0
- package/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
- package/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
- package/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
- package/src/components/sandbox/SandboxRuntimeProvider.ts +35 -0
- package/src/dialogs/ApiKeyPromptDialog.ts +2 -5
- package/src/dialogs/ModelSelector.ts +2 -2
- package/src/dialogs/PersistentStorageDialog.ts +141 -0
- package/src/dialogs/SessionListDialog.ts +148 -0
- package/src/dialogs/SettingsDialog.ts +1 -0
- package/src/index.ts +61 -20
- package/src/prompts/prompts.ts +282 -0
- package/src/storage/app-storage.ts +27 -24
- package/src/storage/backends/indexeddb-storage-backend.ts +193 -0
- package/src/storage/store.ts +33 -0
- package/src/storage/stores/provider-keys-store.ts +33 -0
- package/src/storage/stores/sessions-store.ts +130 -0
- package/src/storage/stores/settings-store.ts +34 -0
- package/src/storage/types.ts +182 -22
- package/src/tools/artifacts/ArtifactElement.ts +0 -1
- package/src/tools/artifacts/ArtifactPill.ts +25 -0
- package/src/tools/artifacts/Console.ts +93 -0
- package/src/tools/artifacts/DocxArtifact.ts +213 -0
- package/src/tools/artifacts/ExcelArtifact.ts +231 -0
- package/src/tools/artifacts/GenericArtifact.ts +117 -0
- package/src/tools/artifacts/HtmlArtifact.ts +64 -94
- package/src/tools/artifacts/ImageArtifact.ts +116 -0
- package/src/tools/artifacts/MarkdownArtifact.ts +0 -1
- package/src/tools/artifacts/PdfArtifact.ts +201 -0
- package/src/tools/artifacts/SvgArtifact.ts +0 -1
- package/src/tools/artifacts/TextArtifact.ts +0 -1
- package/src/tools/artifacts/artifacts-tool-renderer.ts +298 -0
- package/src/tools/artifacts/artifacts.ts +190 -366
- package/src/tools/artifacts/index.ts +1 -0
- package/src/tools/extract-document.ts +250 -0
- package/src/tools/index.ts +25 -14
- package/src/tools/javascript-repl.ts +138 -160
- package/src/tools/renderer-registry.ts +98 -0
- package/src/tools/renderers/BashRenderer.ts +33 -30
- package/src/tools/renderers/CalculateRenderer.ts +36 -31
- package/src/tools/renderers/DefaultRenderer.ts +84 -21
- package/src/tools/renderers/GetCurrentTimeRenderer.ts +68 -23
- package/src/tools/types.ts +10 -2
- package/src/utils/i18n.ts +203 -8
- package/dist/state/agent-session.d.ts.map +0 -1
- package/dist/state/agent-session.js.map +0 -1
- package/dist/state/transports/AppTransport.d.ts.map +0 -1
- package/dist/state/transports/ProviderTransport.d.ts.map +0 -1
- package/dist/state/transports/ProviderTransport.js.map +0 -1
- package/dist/state/transports/index.js.map +0 -1
- package/dist/state/transports/proxy-types.js.map +0 -1
- package/dist/state/transports/types.d.ts +0 -11
- package/dist/state/transports/types.d.ts.map +0 -1
- package/dist/storage/backends/chrome-storage-backend.d.ts +0 -18
- package/dist/storage/backends/chrome-storage-backend.d.ts.map +0 -1
- package/dist/storage/backends/chrome-storage-backend.js +0 -67
- package/dist/storage/backends/chrome-storage-backend.js.map +0 -1
- package/dist/storage/backends/indexeddb-backend.d.ts +0 -20
- package/dist/storage/backends/indexeddb-backend.d.ts.map +0 -1
- package/dist/storage/backends/indexeddb-backend.js +0 -89
- package/dist/storage/backends/indexeddb-backend.js.map +0 -1
- package/dist/storage/backends/local-storage-backend.d.ts +0 -18
- package/dist/storage/backends/local-storage-backend.d.ts.map +0 -1
- package/dist/storage/backends/local-storage-backend.js +0 -69
- package/dist/storage/backends/local-storage-backend.js.map +0 -1
- package/dist/storage/repositories/provider-keys-repository.d.ts +0 -34
- package/dist/storage/repositories/provider-keys-repository.d.ts.map +0 -1
- package/dist/storage/repositories/provider-keys-repository.js +0 -50
- package/dist/storage/repositories/provider-keys-repository.js.map +0 -1
- package/dist/storage/repositories/settings-repository.d.ts +0 -34
- package/dist/storage/repositories/settings-repository.d.ts.map +0 -1
- package/dist/storage/repositories/settings-repository.js +0 -46
- package/dist/storage/repositories/settings-repository.js.map +0 -1
- package/src/storage/backends/chrome-storage-backend.ts +0 -82
- package/src/storage/backends/indexeddb-backend.ts +0 -107
- package/src/storage/backends/local-storage-backend.ts +0 -74
- package/src/storage/repositories/provider-keys-repository.ts +0 -55
- package/src/storage/repositories/settings-repository.ts +0 -51
- /package/dist/{state → agent}/transports/index.d.ts +0 -0
- /package/dist/{state → agent}/transports/index.js +0 -0
- /package/dist/{state → agent}/transports/proxy-types.d.ts +0 -0
- /package/dist/{state → agent}/transports/proxy-types.js +0 -0
- /package/dist/{state → agent}/transports/types.js +0 -0
- /package/dist/{state → agent}/types.d.ts +0 -0
- /package/dist/{state → agent}/types.js +0 -0
- /package/src/{state → agent}/transports/index.ts +0 -0
- /package/src/{state → agent}/transports/proxy-types.ts +0 -0
- /package/src/{state → agent}/types.ts +0 -0
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
import { Button,
|
|
2
|
-
import
|
|
1
|
+
import { Button, icon } from "@mariozechner/mini-lit";
|
|
2
|
+
import "@mariozechner/mini-lit/dist/MarkdownBlock.js";
|
|
3
|
+
import { type AgentTool, type Message, StringEnum, type ToolCall } from "@mariozechner/pi-ai";
|
|
3
4
|
import { type Static, Type } from "@sinclair/typebox";
|
|
4
5
|
import { html, LitElement, type TemplateResult } from "lit";
|
|
5
6
|
import { customElement, property, state } from "lit/decorators.js";
|
|
6
7
|
import { createRef, type Ref, ref } from "lit/directives/ref.js";
|
|
7
8
|
import { X } from "lucide";
|
|
9
|
+
import type { Agent } from "../../agent/agent.js";
|
|
10
|
+
import type { ArtifactMessage } from "../../components/Messages.js";
|
|
11
|
+
import { ArtifactsRuntimeProvider } from "../../components/sandbox/ArtifactsRuntimeProvider.js";
|
|
12
|
+
import { AttachmentsRuntimeProvider } from "../../components/sandbox/AttachmentsRuntimeProvider.js";
|
|
13
|
+
import type { SandboxRuntimeProvider } from "../../components/sandbox/SandboxRuntimeProvider.js";
|
|
14
|
+
import {
|
|
15
|
+
ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
|
|
16
|
+
ARTIFACTS_TOOL_DESCRIPTION,
|
|
17
|
+
ATTACHMENTS_RUNTIME_DESCRIPTION,
|
|
18
|
+
} from "../../prompts/prompts.js";
|
|
8
19
|
import type { Attachment } from "../../utils/attachment-utils.js";
|
|
9
20
|
import { i18n } from "../../utils/i18n.js";
|
|
10
|
-
import type { ToolRenderer } from "../types.js";
|
|
11
21
|
import type { ArtifactElement } from "./ArtifactElement.js";
|
|
22
|
+
import { DocxArtifact } from "./DocxArtifact.js";
|
|
23
|
+
import { ExcelArtifact } from "./ExcelArtifact.js";
|
|
24
|
+
import { GenericArtifact } from "./GenericArtifact.js";
|
|
12
25
|
import { HtmlArtifact } from "./HtmlArtifact.js";
|
|
26
|
+
import { ImageArtifact } from "./ImageArtifact.js";
|
|
13
27
|
import { MarkdownArtifact } from "./MarkdownArtifact.js";
|
|
28
|
+
import { PdfArtifact } from "./PdfArtifact.js";
|
|
14
29
|
import { SvgArtifact } from "./SvgArtifact.js";
|
|
15
30
|
import { TextArtifact } from "./TextArtifact.js";
|
|
16
|
-
import "@mariozechner/mini-lit/dist/MarkdownBlock.js";
|
|
17
|
-
import "@mariozechner/mini-lit/dist/CodeBlock.js";
|
|
18
31
|
|
|
19
32
|
// Simple artifact model
|
|
20
33
|
export interface Artifact {
|
|
21
34
|
filename: string;
|
|
22
|
-
title: string;
|
|
23
35
|
content: string;
|
|
24
36
|
createdAt: Date;
|
|
25
37
|
updatedAt: Date;
|
|
@@ -31,20 +43,14 @@ const artifactsParamsSchema = Type.Object({
|
|
|
31
43
|
description: "The operation to perform",
|
|
32
44
|
}),
|
|
33
45
|
filename: Type.String({ description: "Filename including extension (e.g., 'index.html', 'script.js')" }),
|
|
34
|
-
title: Type.Optional(Type.String({ description: "Display title for the tab (defaults to filename)" })),
|
|
35
46
|
content: Type.Optional(Type.String({ description: "File content" })),
|
|
36
47
|
old_str: Type.Optional(Type.String({ description: "String to replace (for update command)" })),
|
|
37
48
|
new_str: Type.Optional(Type.String({ description: "Replacement string (for update command)" })),
|
|
38
49
|
});
|
|
39
50
|
export type ArtifactsParams = Static<typeof artifactsParamsSchema>;
|
|
40
51
|
|
|
41
|
-
// Minimal helper to render plain text outputs consistently
|
|
42
|
-
function plainOutput(text: string): TemplateResult {
|
|
43
|
-
return html`<div class="text-xs text-muted-foreground whitespace-pre-wrap font-mono">${text}</div>`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
52
|
@customElement("artifacts-panel")
|
|
47
|
-
export class ArtifactsPanel extends LitElement
|
|
53
|
+
export class ArtifactsPanel extends LitElement {
|
|
48
54
|
@state() private _artifacts = new Map<string, Artifact>();
|
|
49
55
|
@state() private _activeFilename: string | null = null;
|
|
50
56
|
|
|
@@ -52,8 +58,8 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
52
58
|
private artifactElements = new Map<string, ArtifactElement>();
|
|
53
59
|
private contentRef: Ref<HTMLDivElement> = createRef();
|
|
54
60
|
|
|
55
|
-
//
|
|
56
|
-
@property({ attribute: false })
|
|
61
|
+
// Agent reference (needed to get attachments for HTML artifacts)
|
|
62
|
+
@property({ attribute: false }) agent?: Agent;
|
|
57
63
|
// Sandbox URL provider for browser extensions (optional)
|
|
58
64
|
@property({ attribute: false }) sandboxUrlProvider?: () => string;
|
|
59
65
|
// Callbacks
|
|
@@ -70,6 +76,29 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
70
76
|
return this._artifacts;
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
// Get runtime providers for HTML artifacts (read-only: attachments + artifacts)
|
|
80
|
+
private getHtmlArtifactRuntimeProviders(): SandboxRuntimeProvider[] {
|
|
81
|
+
const providers: SandboxRuntimeProvider[] = [];
|
|
82
|
+
|
|
83
|
+
// Get attachments from agent messages
|
|
84
|
+
if (this.agent) {
|
|
85
|
+
const attachments: Attachment[] = [];
|
|
86
|
+
for (const message of this.agent.state.messages) {
|
|
87
|
+
if (message.role === "user" && message.attachments) {
|
|
88
|
+
attachments.push(...message.attachments);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (attachments.length > 0) {
|
|
92
|
+
providers.push(new AttachmentsRuntimeProvider(attachments));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Add read-only artifacts provider
|
|
97
|
+
providers.push(new ArtifactsRuntimeProvider(this, this.agent, false));
|
|
98
|
+
|
|
99
|
+
return providers;
|
|
100
|
+
}
|
|
101
|
+
|
|
73
102
|
protected override createRenderRoot(): HTMLElement | DocumentFragment {
|
|
74
103
|
return this; // light DOM for shared styles
|
|
75
104
|
}
|
|
@@ -99,60 +128,63 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
99
128
|
}
|
|
100
129
|
|
|
101
130
|
// Helper to determine file type from extension
|
|
102
|
-
private getFileType(
|
|
131
|
+
private getFileType(
|
|
132
|
+
filename: string,
|
|
133
|
+
): "html" | "svg" | "markdown" | "image" | "pdf" | "excel" | "docx" | "text" | "generic" {
|
|
103
134
|
const ext = filename.split(".").pop()?.toLowerCase();
|
|
104
135
|
if (ext === "html") return "html";
|
|
105
136
|
if (ext === "svg") return "svg";
|
|
106
137
|
if (ext === "md" || ext === "markdown") return "markdown";
|
|
107
|
-
return "
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
if (ext === "pdf") return "pdf";
|
|
139
|
+
if (ext === "xlsx" || ext === "xls") return "excel";
|
|
140
|
+
if (ext === "docx") return "docx";
|
|
141
|
+
if (
|
|
142
|
+
ext === "png" ||
|
|
143
|
+
ext === "jpg" ||
|
|
144
|
+
ext === "jpeg" ||
|
|
145
|
+
ext === "gif" ||
|
|
146
|
+
ext === "webp" ||
|
|
147
|
+
ext === "bmp" ||
|
|
148
|
+
ext === "ico"
|
|
149
|
+
)
|
|
150
|
+
return "image";
|
|
151
|
+
// Text files
|
|
152
|
+
if (
|
|
153
|
+
ext === "txt" ||
|
|
154
|
+
ext === "json" ||
|
|
155
|
+
ext === "xml" ||
|
|
156
|
+
ext === "yaml" ||
|
|
157
|
+
ext === "yml" ||
|
|
158
|
+
ext === "csv" ||
|
|
159
|
+
ext === "js" ||
|
|
160
|
+
ext === "ts" ||
|
|
161
|
+
ext === "jsx" ||
|
|
162
|
+
ext === "tsx" ||
|
|
163
|
+
ext === "py" ||
|
|
164
|
+
ext === "java" ||
|
|
165
|
+
ext === "c" ||
|
|
166
|
+
ext === "cpp" ||
|
|
167
|
+
ext === "h" ||
|
|
168
|
+
ext === "css" ||
|
|
169
|
+
ext === "scss" ||
|
|
170
|
+
ext === "sass" ||
|
|
171
|
+
ext === "less" ||
|
|
172
|
+
ext === "sh"
|
|
173
|
+
)
|
|
174
|
+
return "text";
|
|
175
|
+
// Everything else gets generic fallback
|
|
176
|
+
return "generic";
|
|
145
177
|
}
|
|
146
178
|
|
|
147
179
|
// Get or create artifact element
|
|
148
|
-
private getOrCreateArtifactElement(filename: string, content: string
|
|
180
|
+
private getOrCreateArtifactElement(filename: string, content: string): ArtifactElement {
|
|
149
181
|
let element = this.artifactElements.get(filename);
|
|
150
182
|
|
|
151
183
|
if (!element) {
|
|
152
184
|
const type = this.getFileType(filename);
|
|
153
185
|
if (type === "html") {
|
|
154
186
|
element = new HtmlArtifact();
|
|
155
|
-
(element as HtmlArtifact).
|
|
187
|
+
(element as HtmlArtifact).runtimeProviders = this.getHtmlArtifactRuntimeProviders();
|
|
156
188
|
if (this.sandboxUrlProvider) {
|
|
157
189
|
(element as HtmlArtifact).sandboxUrlProvider = this.sandboxUrlProvider;
|
|
158
190
|
}
|
|
@@ -160,11 +192,20 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
160
192
|
element = new SvgArtifact();
|
|
161
193
|
} else if (type === "markdown") {
|
|
162
194
|
element = new MarkdownArtifact();
|
|
163
|
-
} else {
|
|
195
|
+
} else if (type === "image") {
|
|
196
|
+
element = new ImageArtifact();
|
|
197
|
+
} else if (type === "pdf") {
|
|
198
|
+
element = new PdfArtifact();
|
|
199
|
+
} else if (type === "excel") {
|
|
200
|
+
element = new ExcelArtifact();
|
|
201
|
+
} else if (type === "docx") {
|
|
202
|
+
element = new DocxArtifact();
|
|
203
|
+
} else if (type === "text") {
|
|
164
204
|
element = new TextArtifact();
|
|
205
|
+
} else {
|
|
206
|
+
element = new GenericArtifact();
|
|
165
207
|
}
|
|
166
208
|
element.filename = filename;
|
|
167
|
-
element.displayTitle = title;
|
|
168
209
|
element.content = content;
|
|
169
210
|
element.style.display = "none";
|
|
170
211
|
element.style.height = "100%";
|
|
@@ -186,9 +227,8 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
186
227
|
} else {
|
|
187
228
|
// Just update content
|
|
188
229
|
element.content = content;
|
|
189
|
-
element.displayTitle = title;
|
|
190
230
|
if (element instanceof HtmlArtifact) {
|
|
191
|
-
element.
|
|
231
|
+
element.runtimeProviders = this.getHtmlArtifactRuntimeProviders();
|
|
192
232
|
}
|
|
193
233
|
}
|
|
194
234
|
|
|
@@ -208,10 +248,18 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
208
248
|
});
|
|
209
249
|
this._activeFilename = filename;
|
|
210
250
|
this.requestUpdate(); // Only for tab bar update
|
|
251
|
+
|
|
252
|
+
// Scroll the active tab into view after render
|
|
253
|
+
requestAnimationFrame(() => {
|
|
254
|
+
const activeButton = this.querySelector(`button[data-filename="${filename}"]`);
|
|
255
|
+
if (activeButton) {
|
|
256
|
+
activeButton.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
|
|
257
|
+
}
|
|
258
|
+
});
|
|
211
259
|
}
|
|
212
260
|
|
|
213
261
|
// Open panel and focus an artifact tab by filename
|
|
214
|
-
|
|
262
|
+
public openArtifact(filename: string) {
|
|
215
263
|
if (this._artifacts.has(filename)) {
|
|
216
264
|
this.showArtifact(filename);
|
|
217
265
|
// Ask host to open panel (AgentInterface demo listens to onOpen)
|
|
@@ -224,103 +272,14 @@ export class ArtifactsPanel extends LitElement implements ToolRenderer<Artifacts
|
|
|
224
272
|
return {
|
|
225
273
|
label: "Artifacts",
|
|
226
274
|
name: "artifacts",
|
|
227
|
-
description
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- content: File content (required)
|
|
236
|
-
|
|
237
|
-
2. update: Update part of an existing file
|
|
238
|
-
- filename: File to update (required)
|
|
239
|
-
- old_str: Exact string to replace (required)
|
|
240
|
-
- new_str: Replacement string (required)
|
|
241
|
-
|
|
242
|
-
3. rewrite: Completely replace a file's content
|
|
243
|
-
- filename: File to rewrite (required)
|
|
244
|
-
- content: New content (required)
|
|
245
|
-
- title: Optionally update display title
|
|
246
|
-
|
|
247
|
-
4. get: Retrieve the full content of a file
|
|
248
|
-
- filename: File to retrieve (required)
|
|
249
|
-
- Returns the complete file content
|
|
250
|
-
|
|
251
|
-
5. delete: Delete a file
|
|
252
|
-
- filename: File to delete (required)
|
|
253
|
-
|
|
254
|
-
6. logs: Get console logs and errors (HTML files only)
|
|
255
|
-
- filename: HTML file to get logs for (required)
|
|
256
|
-
- Returns all console output and runtime errors
|
|
257
|
-
|
|
258
|
-
For text/html artifacts with attachments:
|
|
259
|
-
- HTML artifacts automatically have access to user attachments via JavaScript
|
|
260
|
-
- Available global functions in HTML artifacts:
|
|
261
|
-
* listFiles() - Returns array of {id, fileName, mimeType, size} for all attachments
|
|
262
|
-
* readTextFile(attachmentId) - Returns text content of attachment (for CSV, JSON, text files)
|
|
263
|
-
* readBinaryFile(attachmentId) - Returns Uint8Array of binary data (for images, Excel, etc.)
|
|
264
|
-
- Example HTML artifact that processes a CSV attachment:
|
|
265
|
-
<script>
|
|
266
|
-
// List available files
|
|
267
|
-
const files = listFiles();
|
|
268
|
-
console.log('Available files:', files);
|
|
269
|
-
|
|
270
|
-
// Find CSV file
|
|
271
|
-
const csvFile = files.find(f => f.mimeType === 'text/csv');
|
|
272
|
-
if (csvFile) {
|
|
273
|
-
const csvContent = readTextFile(csvFile.id);
|
|
274
|
-
// Process CSV data...
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Display image
|
|
278
|
-
const imageFile = files.find(f => f.mimeType.startsWith('image/'));
|
|
279
|
-
if (imageFile) {
|
|
280
|
-
const bytes = readBinaryFile(imageFile.id);
|
|
281
|
-
const blob = new Blob([bytes], {type: imageFile.mimeType});
|
|
282
|
-
const url = URL.createObjectURL(blob);
|
|
283
|
-
document.body.innerHTML = '<img src="' + url + '">';
|
|
284
|
-
}
|
|
285
|
-
</script>
|
|
286
|
-
|
|
287
|
-
For text/html artifacts:
|
|
288
|
-
- Must be a single self-contained file
|
|
289
|
-
- External scripts: Use CDNs like https://esm.sh, https://unpkg.com, or https://cdnjs.cloudflare.com
|
|
290
|
-
- Preferred: Use https://esm.sh for npm packages (e.g., https://esm.sh/three for Three.js)
|
|
291
|
-
- For ES modules, use: <script type="module">import * as THREE from 'https://esm.sh/three';</script>
|
|
292
|
-
- For Three.js specifically: import from 'https://esm.sh/three' or 'https://esm.sh/three@0.160.0'
|
|
293
|
-
- For addons: import from 'https://esm.sh/three/examples/jsm/controls/OrbitControls.js'
|
|
294
|
-
- No localStorage/sessionStorage - use in-memory variables only
|
|
295
|
-
- CSS should be included inline
|
|
296
|
-
- CRITICAL REMINDER FOR HTML ARTIFACTS:
|
|
297
|
-
- ALWAYS set a background color inline in <style> or directly on body element
|
|
298
|
-
- Failure to set a background color is a COMPLIANCE ERROR
|
|
299
|
-
- Background color MUST be explicitly defined to ensure visibility and proper rendering
|
|
300
|
-
- Can embed base64 images directly in img tags
|
|
301
|
-
- Ensure the layout is responsive as the iframe might be resized
|
|
302
|
-
- Note: Network errors (404s) for external scripts may not be captured in logs due to browser security
|
|
303
|
-
|
|
304
|
-
For application/vnd.ant.code artifacts:
|
|
305
|
-
- Include the language parameter for syntax highlighting
|
|
306
|
-
- Supports all major programming languages
|
|
307
|
-
|
|
308
|
-
For text/markdown:
|
|
309
|
-
- Standard markdown syntax
|
|
310
|
-
- Will be rendered with full formatting
|
|
311
|
-
- Can include base64 images using markdown syntax
|
|
312
|
-
|
|
313
|
-
For image/svg+xml:
|
|
314
|
-
- Complete SVG markup
|
|
315
|
-
- Will be rendered inline
|
|
316
|
-
- Can embed raster images as base64 in SVG
|
|
317
|
-
|
|
318
|
-
CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
319
|
-
- Prefer to update existing files rather than creating new ones
|
|
320
|
-
- Keep filenames consistent and descriptive
|
|
321
|
-
- Use appropriate file extensions
|
|
322
|
-
- Ensure HTML artifacts have a defined background color
|
|
323
|
-
`,
|
|
275
|
+
get description() {
|
|
276
|
+
// HTML artifacts have read-only access to attachments and artifacts
|
|
277
|
+
const runtimeProviderDescriptions = [
|
|
278
|
+
ATTACHMENTS_RUNTIME_DESCRIPTION,
|
|
279
|
+
ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO,
|
|
280
|
+
];
|
|
281
|
+
return ARTIFACTS_TOOL_DESCRIPTION(runtimeProviderDescriptions);
|
|
282
|
+
},
|
|
324
283
|
parameters: artifactsParamsSchema,
|
|
325
284
|
// Execute mutates our local store and returns a plain output
|
|
326
285
|
execute: async (_toolCallId: string, args: Static<typeof artifactsParamsSchema>, _signal?: AbortSignal) => {
|
|
@@ -330,155 +289,10 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
330
289
|
};
|
|
331
290
|
}
|
|
332
291
|
|
|
333
|
-
// ToolRenderer implementation
|
|
334
|
-
renderParams(params: ArtifactsParams, isStreaming?: boolean): TemplateResult {
|
|
335
|
-
if (isStreaming && !params.command) {
|
|
336
|
-
return html`<div class="text-sm text-muted-foreground">${i18n("Processing artifact...")}</div>`;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
let commandLabel = i18n("Processing");
|
|
340
|
-
if (params.command) {
|
|
341
|
-
switch (params.command) {
|
|
342
|
-
case "create":
|
|
343
|
-
commandLabel = i18n("Create");
|
|
344
|
-
break;
|
|
345
|
-
case "update":
|
|
346
|
-
commandLabel = i18n("Update");
|
|
347
|
-
break;
|
|
348
|
-
case "rewrite":
|
|
349
|
-
commandLabel = i18n("Rewrite");
|
|
350
|
-
break;
|
|
351
|
-
case "get":
|
|
352
|
-
commandLabel = i18n("Get");
|
|
353
|
-
break;
|
|
354
|
-
case "delete":
|
|
355
|
-
commandLabel = i18n("Delete");
|
|
356
|
-
break;
|
|
357
|
-
case "logs":
|
|
358
|
-
commandLabel = i18n("Get logs");
|
|
359
|
-
break;
|
|
360
|
-
default:
|
|
361
|
-
commandLabel = params.command.charAt(0).toUpperCase() + params.command.slice(1);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
const filename = params.filename || "";
|
|
365
|
-
|
|
366
|
-
switch (params.command) {
|
|
367
|
-
case "create":
|
|
368
|
-
return html`
|
|
369
|
-
<div
|
|
370
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
371
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
372
|
-
>
|
|
373
|
-
<div>
|
|
374
|
-
<span class="font-medium">${i18n("Create")}</span>
|
|
375
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
376
|
-
</div>
|
|
377
|
-
${
|
|
378
|
-
params.content
|
|
379
|
-
? html`<code-block
|
|
380
|
-
.code=${params.content}
|
|
381
|
-
language=${this.getLanguageFromFilename(params.filename)}
|
|
382
|
-
class="mt-2"
|
|
383
|
-
></code-block>`
|
|
384
|
-
: ""
|
|
385
|
-
}
|
|
386
|
-
</div>
|
|
387
|
-
`;
|
|
388
|
-
case "update":
|
|
389
|
-
return html`
|
|
390
|
-
<div
|
|
391
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
392
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
393
|
-
>
|
|
394
|
-
<div>
|
|
395
|
-
<span class="font-medium">${i18n("Update")}</span>
|
|
396
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
397
|
-
</div>
|
|
398
|
-
${
|
|
399
|
-
params.old_str !== undefined && params.new_str !== undefined
|
|
400
|
-
? Diff({ oldText: params.old_str, newText: params.new_str, className: "mt-2" })
|
|
401
|
-
: ""
|
|
402
|
-
}
|
|
403
|
-
</div>
|
|
404
|
-
`;
|
|
405
|
-
case "rewrite":
|
|
406
|
-
return html`
|
|
407
|
-
<div
|
|
408
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
409
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
410
|
-
>
|
|
411
|
-
<div>
|
|
412
|
-
<span class="font-medium">${i18n("Rewrite")}</span>
|
|
413
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
414
|
-
</div>
|
|
415
|
-
${
|
|
416
|
-
params.content
|
|
417
|
-
? html`<code-block
|
|
418
|
-
.code=${params.content}
|
|
419
|
-
language=${this.getLanguageFromFilename(params.filename)}
|
|
420
|
-
class="mt-2"
|
|
421
|
-
></code-block>`
|
|
422
|
-
: ""
|
|
423
|
-
}
|
|
424
|
-
</div>
|
|
425
|
-
`;
|
|
426
|
-
case "get":
|
|
427
|
-
return html`
|
|
428
|
-
<div
|
|
429
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
430
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
431
|
-
>
|
|
432
|
-
<span class="font-medium">${i18n("Get")}</span>
|
|
433
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
434
|
-
</div>
|
|
435
|
-
`;
|
|
436
|
-
case "delete":
|
|
437
|
-
return html`
|
|
438
|
-
<div
|
|
439
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
440
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
441
|
-
>
|
|
442
|
-
<span class="font-medium">${i18n("Delete")}</span>
|
|
443
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
444
|
-
</div>
|
|
445
|
-
`;
|
|
446
|
-
case "logs":
|
|
447
|
-
return html`
|
|
448
|
-
<div
|
|
449
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
450
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
451
|
-
>
|
|
452
|
-
<span class="font-medium">${i18n("Get logs")}</span>
|
|
453
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
454
|
-
</div>
|
|
455
|
-
`;
|
|
456
|
-
default:
|
|
457
|
-
// Fallback for any command not yet handled during streaming
|
|
458
|
-
return html`
|
|
459
|
-
<div
|
|
460
|
-
class="text-sm cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1"
|
|
461
|
-
@click=${() => this.openArtifact(params.filename)}
|
|
462
|
-
>
|
|
463
|
-
<span class="font-medium">${commandLabel}</span>
|
|
464
|
-
<span class="text-muted-foreground ml-1">${filename}</span>
|
|
465
|
-
</div>
|
|
466
|
-
`;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
renderResult(params: ArtifactsParams, result: ToolResultMessage<undefined>): TemplateResult {
|
|
471
|
-
// Make result clickable to focus the referenced file when applicable
|
|
472
|
-
const content = result.output || i18n("(no output)");
|
|
473
|
-
return html`
|
|
474
|
-
<div class="cursor-pointer hover:bg-muted/50 rounded-sm px-2 py-1" @click=${() => this.openArtifact(params.filename)}>
|
|
475
|
-
${plainOutput(content)}
|
|
476
|
-
</div>
|
|
477
|
-
`;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
292
|
// Re-apply artifacts by scanning a message list (optional utility)
|
|
481
|
-
public async reconstructFromMessages(
|
|
293
|
+
public async reconstructFromMessages(
|
|
294
|
+
messages: Array<Message | { role: "aborted" } | { role: "artifact" }>,
|
|
295
|
+
): Promise<void> {
|
|
482
296
|
const toolCalls = new Map<string, ToolCall>();
|
|
483
297
|
const artifactToolName = "artifacts";
|
|
484
298
|
|
|
@@ -496,7 +310,33 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
496
310
|
// 2) Build an ordered list of successful artifact operations
|
|
497
311
|
const operations: Array<ArtifactsParams> = [];
|
|
498
312
|
for (const m of messages) {
|
|
499
|
-
if ((m as any).role === "
|
|
313
|
+
if ((m as any).role === "artifact") {
|
|
314
|
+
const artifactMsg = m as ArtifactMessage;
|
|
315
|
+
switch (artifactMsg.action) {
|
|
316
|
+
case "create":
|
|
317
|
+
operations.push({
|
|
318
|
+
command: "create",
|
|
319
|
+
filename: artifactMsg.filename,
|
|
320
|
+
content: artifactMsg.content,
|
|
321
|
+
});
|
|
322
|
+
break;
|
|
323
|
+
case "update":
|
|
324
|
+
operations.push({
|
|
325
|
+
command: "rewrite",
|
|
326
|
+
filename: artifactMsg.filename,
|
|
327
|
+
content: artifactMsg.content,
|
|
328
|
+
});
|
|
329
|
+
break;
|
|
330
|
+
case "delete":
|
|
331
|
+
operations.push({
|
|
332
|
+
command: "delete",
|
|
333
|
+
filename: artifactMsg.filename,
|
|
334
|
+
});
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Handle tool result messages (from artifacts tool calls)
|
|
339
|
+
else if ((m as any).role === "toolResult" && (m as any).toolName === artifactToolName && !(m as any).isError) {
|
|
500
340
|
const toolCallId = (m as any).toolCallId as string;
|
|
501
341
|
const call = toolCalls.get(toolCallId);
|
|
502
342
|
if (!call) continue;
|
|
@@ -507,30 +347,27 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
507
347
|
}
|
|
508
348
|
|
|
509
349
|
// 3) Compute final state per filename by simulating operations in-memory
|
|
510
|
-
|
|
511
|
-
const finalArtifacts = new Map<string, FinalArtifact>();
|
|
350
|
+
const finalArtifacts = new Map<string, string>();
|
|
512
351
|
for (const op of operations) {
|
|
513
352
|
const filename = op.filename;
|
|
514
353
|
switch (op.command) {
|
|
515
354
|
case "create": {
|
|
516
355
|
if (op.content) {
|
|
517
|
-
finalArtifacts.set(filename,
|
|
356
|
+
finalArtifacts.set(filename, op.content);
|
|
518
357
|
}
|
|
519
358
|
break;
|
|
520
359
|
}
|
|
521
360
|
case "rewrite": {
|
|
522
361
|
if (op.content) {
|
|
523
|
-
|
|
524
|
-
const existing = finalArtifacts.get(filename);
|
|
525
|
-
finalArtifacts.set(filename, { title: op.title || existing?.title || filename, content: op.content });
|
|
362
|
+
finalArtifacts.set(filename, op.content);
|
|
526
363
|
}
|
|
527
364
|
break;
|
|
528
365
|
}
|
|
529
366
|
case "update": {
|
|
530
|
-
|
|
367
|
+
let existing = finalArtifacts.get(filename);
|
|
531
368
|
if (!existing) break; // skip invalid update (shouldn't happen for successful results)
|
|
532
369
|
if (op.old_str !== undefined && op.new_str !== undefined) {
|
|
533
|
-
existing
|
|
370
|
+
existing = existing.replace(op.old_str, op.new_str);
|
|
534
371
|
finalArtifacts.set(filename, existing);
|
|
535
372
|
}
|
|
536
373
|
break;
|
|
@@ -556,8 +393,8 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
556
393
|
this._artifacts = new Map(this._artifacts);
|
|
557
394
|
|
|
558
395
|
// 5) Create artifacts in a single pass without waiting for iframe execution or tab switching
|
|
559
|
-
for (const [filename,
|
|
560
|
-
const createParams: ArtifactsParams = { command: "create", filename,
|
|
396
|
+
for (const [filename, content] of finalArtifacts.entries()) {
|
|
397
|
+
const createParams: ArtifactsParams = { command: "create", filename, content } as const;
|
|
561
398
|
try {
|
|
562
399
|
await this.createArtifact(createParams, { skipWait: true, silent: true });
|
|
563
400
|
} catch {
|
|
@@ -605,50 +442,27 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
605
442
|
}
|
|
606
443
|
|
|
607
444
|
return new Promise((resolve) => {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
// Listen for the execution-complete message
|
|
611
|
-
const messageHandler = (event: MessageEvent) => {
|
|
612
|
-
if (event.data?.type === "execution-complete" && event.data?.artifactId === filename) {
|
|
613
|
-
if (!resolved) {
|
|
614
|
-
resolved = true;
|
|
615
|
-
window.removeEventListener("message", messageHandler);
|
|
616
|
-
|
|
617
|
-
// Get the logs from the element
|
|
618
|
-
const logs = element.getLogs();
|
|
619
|
-
if (logs.includes("[error]")) {
|
|
620
|
-
resolve(`\n\nExecution completed with errors:\n${logs}`);
|
|
621
|
-
} else if (logs !== `No logs for ${filename}`) {
|
|
622
|
-
resolve(`\n\nExecution logs:\n${logs}`);
|
|
623
|
-
} else {
|
|
624
|
-
resolve("");
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
window.addEventListener("message", messageHandler);
|
|
631
|
-
|
|
632
|
-
// Fallback timeout in case the message never arrives
|
|
445
|
+
// Fallback timeout - just get logs after execution should complete
|
|
633
446
|
setTimeout(() => {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
// Get whatever logs we have so far
|
|
639
|
-
const logs = element.getLogs();
|
|
640
|
-
if (logs.includes("[error]")) {
|
|
641
|
-
resolve(`\n\nExecution timed out with errors:\n${logs}`);
|
|
642
|
-
} else if (logs !== `No logs for ${filename}`) {
|
|
643
|
-
resolve(`\n\nExecution timed out. Partial logs:\n${logs}`);
|
|
644
|
-
} else {
|
|
645
|
-
resolve("");
|
|
646
|
-
}
|
|
647
|
-
}
|
|
447
|
+
// Get whatever logs we have
|
|
448
|
+
const logs = element.getLogs();
|
|
449
|
+
resolve(logs);
|
|
648
450
|
}, 1500);
|
|
649
451
|
});
|
|
650
452
|
}
|
|
651
453
|
|
|
454
|
+
// Reload all HTML artifacts (called when any artifact changes)
|
|
455
|
+
private reloadAllHtmlArtifacts() {
|
|
456
|
+
this.artifactElements.forEach((element) => {
|
|
457
|
+
if (element instanceof HtmlArtifact && element.sandboxIframeRef.value) {
|
|
458
|
+
// Update runtime providers with latest artifact state
|
|
459
|
+
element.runtimeProviders = this.getHtmlArtifactRuntimeProviders();
|
|
460
|
+
// Re-execute the HTML content
|
|
461
|
+
element.executeContent(element.content);
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
652
466
|
private async createArtifact(
|
|
653
467
|
params: ArtifactsParams,
|
|
654
468
|
options: { skipWait?: boolean; silent?: boolean } = {},
|
|
@@ -660,10 +474,8 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
660
474
|
return `Error: File ${params.filename} already exists`;
|
|
661
475
|
}
|
|
662
476
|
|
|
663
|
-
const title = params.title || params.filename;
|
|
664
477
|
const artifact: Artifact = {
|
|
665
478
|
filename: params.filename,
|
|
666
|
-
title: title,
|
|
667
479
|
content: params.content,
|
|
668
480
|
createdAt: new Date(),
|
|
669
481
|
updatedAt: new Date(),
|
|
@@ -672,18 +484,21 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
672
484
|
this._artifacts = new Map(this._artifacts);
|
|
673
485
|
|
|
674
486
|
// Create or update element
|
|
675
|
-
this.getOrCreateArtifactElement(params.filename, params.content
|
|
487
|
+
this.getOrCreateArtifactElement(params.filename, params.content);
|
|
676
488
|
if (!options.silent) {
|
|
677
489
|
this.showArtifact(params.filename);
|
|
678
490
|
this.onArtifactsChange?.();
|
|
679
491
|
this.requestUpdate();
|
|
680
492
|
}
|
|
681
493
|
|
|
494
|
+
// Reload all HTML artifacts since they might depend on this new artifact
|
|
495
|
+
this.reloadAllHtmlArtifacts();
|
|
496
|
+
|
|
682
497
|
// For HTML files, wait for execution
|
|
683
498
|
let result = `Created file ${params.filename}`;
|
|
684
499
|
if (this.getFileType(params.filename) === "html" && !options.skipWait) {
|
|
685
500
|
const logs = await this.waitForHtmlExecution(params.filename);
|
|
686
|
-
result += logs
|
|
501
|
+
result += `\n${logs}`;
|
|
687
502
|
}
|
|
688
503
|
|
|
689
504
|
return result;
|
|
@@ -711,7 +526,7 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
711
526
|
this._artifacts.set(params.filename, artifact);
|
|
712
527
|
|
|
713
528
|
// Update element
|
|
714
|
-
this.getOrCreateArtifactElement(params.filename, artifact.content
|
|
529
|
+
this.getOrCreateArtifactElement(params.filename, artifact.content);
|
|
715
530
|
if (!options.silent) {
|
|
716
531
|
this.onArtifactsChange?.();
|
|
717
532
|
this.requestUpdate();
|
|
@@ -720,11 +535,14 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
720
535
|
// Show the artifact
|
|
721
536
|
this.showArtifact(params.filename);
|
|
722
537
|
|
|
538
|
+
// Reload all HTML artifacts since they might depend on this updated artifact
|
|
539
|
+
this.reloadAllHtmlArtifacts();
|
|
540
|
+
|
|
723
541
|
// For HTML files, wait for execution
|
|
724
542
|
let result = `Updated file ${params.filename}`;
|
|
725
543
|
if (this.getFileType(params.filename) === "html" && !options.skipWait) {
|
|
726
544
|
const logs = await this.waitForHtmlExecution(params.filename);
|
|
727
|
-
result += logs
|
|
545
|
+
result += `\n${logs}`;
|
|
728
546
|
}
|
|
729
547
|
|
|
730
548
|
return result;
|
|
@@ -745,12 +563,11 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
745
563
|
}
|
|
746
564
|
|
|
747
565
|
artifact.content = params.content;
|
|
748
|
-
if (params.title) artifact.title = params.title;
|
|
749
566
|
artifact.updatedAt = new Date();
|
|
750
567
|
this._artifacts.set(params.filename, artifact);
|
|
751
568
|
|
|
752
569
|
// Update element
|
|
753
|
-
this.getOrCreateArtifactElement(params.filename, artifact.content
|
|
570
|
+
this.getOrCreateArtifactElement(params.filename, artifact.content);
|
|
754
571
|
if (!options.silent) {
|
|
755
572
|
this.onArtifactsChange?.();
|
|
756
573
|
}
|
|
@@ -758,11 +575,14 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
758
575
|
// Show the artifact
|
|
759
576
|
this.showArtifact(params.filename);
|
|
760
577
|
|
|
578
|
+
// Reload all HTML artifacts since they might depend on this rewritten artifact
|
|
579
|
+
this.reloadAllHtmlArtifacts();
|
|
580
|
+
|
|
761
581
|
// For HTML files, wait for execution
|
|
762
|
-
let result =
|
|
582
|
+
let result = "";
|
|
763
583
|
if (this.getFileType(params.filename) === "html" && !options.skipWait) {
|
|
764
584
|
const logs = await this.waitForHtmlExecution(params.filename);
|
|
765
|
-
result += logs
|
|
585
|
+
result += `\n${logs}`;
|
|
766
586
|
}
|
|
767
587
|
|
|
768
588
|
return result;
|
|
@@ -809,6 +629,9 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
809
629
|
this.onArtifactsChange?.();
|
|
810
630
|
this.requestUpdate();
|
|
811
631
|
|
|
632
|
+
// Reload all HTML artifacts since they might have depended on this deleted artifact
|
|
633
|
+
this.reloadAllHtmlArtifacts();
|
|
634
|
+
|
|
812
635
|
return `Deleted file ${params.filename}`;
|
|
813
636
|
}
|
|
814
637
|
|
|
@@ -852,6 +675,7 @@ CRITICAL REMINDER FOR ALL ARTIFACTS:
|
|
|
852
675
|
return html`
|
|
853
676
|
<button
|
|
854
677
|
class="px-3 py-2 whitespace-nowrap border-b-2 ${activeClass}"
|
|
678
|
+
data-filename="${a.filename}"
|
|
855
679
|
@click=${() => this.showArtifact(a.filename)}
|
|
856
680
|
>
|
|
857
681
|
<span class="font-mono text-xs">${a.filename}</span>
|