@mariozechner/pi-web-ui 0.5.44 → 0.5.46
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,16 +1,19 @@
|
|
|
1
|
-
import { html, i18n
|
|
1
|
+
import { html, i18n } from "@mariozechner/mini-lit";
|
|
2
2
|
import type { AgentTool, ToolResultMessage } from "@mariozechner/pi-ai";
|
|
3
3
|
import { type Static, Type } from "@sinclair/typebox";
|
|
4
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
5
|
+
import { Code } from "lucide";
|
|
4
6
|
import { type SandboxFile, SandboxIframe, type SandboxResult } from "../components/SandboxedIframe.js";
|
|
7
|
+
import type { SandboxRuntimeProvider } from "../components/sandbox/SandboxRuntimeProvider.js";
|
|
8
|
+
import { JAVASCRIPT_REPL_TOOL_DESCRIPTION } from "../prompts/prompts.js";
|
|
5
9
|
import type { Attachment } from "../utils/attachment-utils.js";
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import type { ToolRenderer } from "./types.js";
|
|
10
|
+
import { registerToolRenderer, renderCollapsibleHeader, renderHeader } from "./renderer-registry.js";
|
|
11
|
+
import type { ToolRenderer, ToolRenderResult } from "./types.js";
|
|
9
12
|
|
|
10
13
|
// Execute JavaScript code with attachments using SandboxedIframe
|
|
11
14
|
export async function executeJavaScript(
|
|
12
15
|
code: string,
|
|
13
|
-
|
|
16
|
+
runtimeProviders: SandboxRuntimeProvider[],
|
|
14
17
|
signal?: AbortSignal,
|
|
15
18
|
sandboxUrlProvider?: () => string,
|
|
16
19
|
): Promise<{ output: string; files?: SandboxFile[] }> {
|
|
@@ -32,31 +35,40 @@ export async function executeJavaScript(
|
|
|
32
35
|
document.body.appendChild(sandbox);
|
|
33
36
|
|
|
34
37
|
try {
|
|
35
|
-
const sandboxId = `repl-${Date.now()}`;
|
|
36
|
-
|
|
38
|
+
const sandboxId = `repl-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
39
|
+
|
|
40
|
+
// Pass providers to execute (router handles all message routing)
|
|
41
|
+
// No additional consumers needed - execute() has its own internal consumer
|
|
42
|
+
const result: SandboxResult = await sandbox.execute(sandboxId, code, runtimeProviders, [], signal);
|
|
37
43
|
|
|
38
44
|
// Remove the sandbox iframe after execution
|
|
39
45
|
sandbox.remove();
|
|
40
46
|
|
|
41
|
-
// Return plain text output
|
|
42
|
-
if (!result.success) {
|
|
43
|
-
// Return error as plain text
|
|
44
|
-
return {
|
|
45
|
-
output: `Error: ${result.error?.message || "Unknown error"}\n${result.error?.stack || ""}`,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
47
|
// Build plain text response
|
|
50
48
|
let output = "";
|
|
51
49
|
|
|
52
50
|
// Add console output - result.console contains { type: string, text: string } from sandbox.js
|
|
53
51
|
if (result.console && result.console.length > 0) {
|
|
54
52
|
for (const entry of result.console) {
|
|
55
|
-
|
|
56
|
-
output += (prefix ? `${prefix} ` : "") + entry.text + "\n";
|
|
53
|
+
output += entry.text + "\n";
|
|
57
54
|
}
|
|
58
55
|
}
|
|
59
56
|
|
|
57
|
+
// Add error if execution failed
|
|
58
|
+
if (!result.success) {
|
|
59
|
+
if (output) output += "\n";
|
|
60
|
+
output += `Error: ${result.error?.message || "Unknown error"}\n${result.error?.stack || ""}`;
|
|
61
|
+
|
|
62
|
+
// Throw error so tool call is marked as failed
|
|
63
|
+
throw new Error(output.trim());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Add return value if present
|
|
67
|
+
if (result.returnValue !== undefined) {
|
|
68
|
+
if (output) output += "\n";
|
|
69
|
+
output += `=> ${typeof result.returnValue === "object" ? JSON.stringify(result.returnValue, null, 2) : result.returnValue}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
// Add file notifications
|
|
61
73
|
if (result.files && result.files.length > 0) {
|
|
62
74
|
output += `\n[Files returned: ${result.files.length}]\n`;
|
|
@@ -92,94 +104,49 @@ export type JavaScriptReplToolResult = {
|
|
|
92
104
|
};
|
|
93
105
|
|
|
94
106
|
const javascriptReplSchema = Type.Object({
|
|
107
|
+
title: Type.String({
|
|
108
|
+
description:
|
|
109
|
+
"Brief title describing what the code snippet tries to achieve in active form, e.g. 'Calculating sum'",
|
|
110
|
+
}),
|
|
95
111
|
code: Type.String({ description: "JavaScript code to execute" }),
|
|
96
112
|
});
|
|
97
113
|
|
|
114
|
+
export type JavaScriptReplParams = Static<typeof javascriptReplSchema>;
|
|
115
|
+
|
|
116
|
+
interface JavaScriptReplResult {
|
|
117
|
+
output?: string;
|
|
118
|
+
files?: Array<{
|
|
119
|
+
fileName: string;
|
|
120
|
+
mimeType: string;
|
|
121
|
+
size: number;
|
|
122
|
+
contentBase64: string;
|
|
123
|
+
}>;
|
|
124
|
+
}
|
|
125
|
+
|
|
98
126
|
export function createJavaScriptReplTool(): AgentTool<typeof javascriptReplSchema, JavaScriptReplToolResult> & {
|
|
99
|
-
|
|
127
|
+
runtimeProvidersFactory?: () => SandboxRuntimeProvider[];
|
|
100
128
|
sandboxUrlProvider?: () => string;
|
|
101
129
|
} {
|
|
102
130
|
return {
|
|
103
131
|
label: "JavaScript REPL",
|
|
104
132
|
name: "javascript_repl",
|
|
105
|
-
|
|
133
|
+
runtimeProvidersFactory: () => [], // default to empty array
|
|
106
134
|
sandboxUrlProvider: undefined, // optional, for browser extensions
|
|
107
|
-
description
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Loading external libraries via dynamic imports (use esm.run):
|
|
115
|
-
- XLSX (Excel files): const XLSX = await import('https://esm.run/xlsx');
|
|
116
|
-
- Papa Parse (CSV): const Papa = (await import('https://esm.run/papaparse')).default;
|
|
117
|
-
- Lodash: const _ = await import('https://esm.run/lodash-es');
|
|
118
|
-
- D3.js: const d3 = await import('https://esm.run/d3');
|
|
119
|
-
- Chart.js: const Chart = (await import('https://esm.run/chart.js/auto')).default;
|
|
120
|
-
- Three.js: const THREE = await import('https://esm.run/three');
|
|
121
|
-
- Any npm package: await import('https://esm.run/package-name')
|
|
122
|
-
|
|
123
|
-
IMPORTANT for graphics/canvas:
|
|
124
|
-
- Use fixed dimensions like 400x400 or 800x600, NOT window.innerWidth/Height
|
|
125
|
-
- For Three.js: renderer.setSize(400, 400) and camera aspect ratio of 1
|
|
126
|
-
- For Chart.js: Set options: { responsive: false, animation: false } to ensure immediate rendering
|
|
127
|
-
- Web Storage (localStorage, sessionStorage, IndexedDB)
|
|
128
|
-
- Web Workers, WebAssembly, WebSockets
|
|
129
|
-
- Media APIs (Audio, Video, WebRTC)
|
|
130
|
-
- File APIs (Blob, FileReader, etc.)
|
|
131
|
-
- Crypto API for cryptography
|
|
132
|
-
- And much more - anything a modern browser supports!
|
|
133
|
-
|
|
134
|
-
Output:
|
|
135
|
-
- console.log() - All output is captured as text
|
|
136
|
-
- await returnFile(filename, content, mimeType?) - Create downloadable files (async function!)
|
|
137
|
-
* Always use await with returnFile
|
|
138
|
-
* REQUIRED: For Blob/Uint8Array binary content, you MUST supply a proper MIME type (e.g., "image/png").
|
|
139
|
-
If omitted, the REPL throws an Error with stack trace pointing to the offending line.
|
|
140
|
-
* Strings without a MIME default to text/plain.
|
|
141
|
-
* Objects are auto-JSON stringified and default to application/json unless a MIME is provided.
|
|
142
|
-
* Canvas images: Use toBlob() with await Promise wrapper
|
|
143
|
-
* Examples:
|
|
144
|
-
- await returnFile('data.txt', 'Hello World', 'text/plain')
|
|
145
|
-
- await returnFile('data.json', {key: 'value'}, 'application/json')
|
|
146
|
-
- await returnFile('data.csv', 'name,age\\nJohn,30', 'text/csv')
|
|
147
|
-
- Chart.js example:
|
|
148
|
-
const Chart = (await import('https://esm.run/chart.js/auto')).default;
|
|
149
|
-
const canvas = document.createElement('canvas');
|
|
150
|
-
canvas.width = 400; canvas.height = 300;
|
|
151
|
-
document.body.appendChild(canvas);
|
|
152
|
-
new Chart(canvas, {
|
|
153
|
-
type: 'line',
|
|
154
|
-
data: {
|
|
155
|
-
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
|
|
156
|
-
datasets: [{ label: 'Sales', data: [10, 20, 15, 25], borderColor: 'blue' }]
|
|
157
|
-
},
|
|
158
|
-
options: { responsive: false, animation: false }
|
|
159
|
-
});
|
|
160
|
-
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
|
|
161
|
-
await returnFile('chart.png', blob, 'image/png');
|
|
162
|
-
|
|
163
|
-
Global variables:
|
|
164
|
-
- attachments[] - Array of attachment objects from user messages
|
|
165
|
-
* Properties:
|
|
166
|
-
- id: string (unique identifier)
|
|
167
|
-
- fileName: string (e.g., "data.xlsx")
|
|
168
|
-
- mimeType: string (e.g., "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
169
|
-
- size: number (bytes)
|
|
170
|
-
* Helper functions:
|
|
171
|
-
- listFiles() - Returns array of {id, fileName, mimeType, size} for all attachments
|
|
172
|
-
- readTextFile(attachmentId) - Returns text content of attachment (for CSV, JSON, text files)
|
|
173
|
-
- readBinaryFile(attachmentId) - Returns Uint8Array of binary data (for images, Excel, etc.)
|
|
174
|
-
* Examples:
|
|
175
|
-
- const files = listFiles();
|
|
176
|
-
- const csvContent = readTextFile(files[0].id); // Read CSV as text
|
|
177
|
-
- const xlsxBytes = readBinaryFile(files[0].id); // Read Excel as binary
|
|
178
|
-
- All standard browser globals (window, document, fetch, etc.)`,
|
|
135
|
+
get description() {
|
|
136
|
+
const runtimeProviderDescriptions =
|
|
137
|
+
this.runtimeProvidersFactory?.()
|
|
138
|
+
.map((d) => d.getDescription())
|
|
139
|
+
.filter((d) => d.trim().length > 0) || [];
|
|
140
|
+
return JAVASCRIPT_REPL_TOOL_DESCRIPTION(runtimeProviderDescriptions);
|
|
141
|
+
},
|
|
179
142
|
parameters: javascriptReplSchema,
|
|
180
143
|
execute: async function (_toolCallId: string, args: Static<typeof javascriptReplSchema>, signal?: AbortSignal) {
|
|
181
|
-
const
|
|
182
|
-
|
|
144
|
+
const result = await executeJavaScript(
|
|
145
|
+
args.code,
|
|
146
|
+
this.runtimeProvidersFactory?.() ?? [],
|
|
147
|
+
signal,
|
|
148
|
+
this.sandboxUrlProvider,
|
|
149
|
+
);
|
|
183
150
|
// Convert files to JSON-serializable with base64 payloads
|
|
184
151
|
const files = (result.files || []).map((f) => {
|
|
185
152
|
const toBase64 = (input: string | Uint8Array): { base64: string; size: number } => {
|
|
@@ -228,80 +195,91 @@ Global variables:
|
|
|
228
195
|
// Export a default instance for backward compatibility
|
|
229
196
|
export const javascriptReplTool = createJavaScriptReplTool();
|
|
230
197
|
|
|
231
|
-
// JavaScript REPL renderer with streaming support
|
|
232
|
-
|
|
233
|
-
interface JavaScriptReplParams {
|
|
234
|
-
code: string;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
interface JavaScriptReplResult {
|
|
238
|
-
output?: string;
|
|
239
|
-
files?: Array<{
|
|
240
|
-
fileName: string;
|
|
241
|
-
mimeType: string;
|
|
242
|
-
size: number;
|
|
243
|
-
contentBase64: string;
|
|
244
|
-
}>;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
198
|
export const javascriptReplRenderer: ToolRenderer<JavaScriptReplParams, JavaScriptReplResult> = {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
199
|
+
render(
|
|
200
|
+
params: JavaScriptReplParams | undefined,
|
|
201
|
+
result: ToolResultMessage<JavaScriptReplResult> | undefined,
|
|
202
|
+
isStreaming?: boolean,
|
|
203
|
+
): ToolRenderResult {
|
|
204
|
+
// Determine status
|
|
205
|
+
const state = result ? (result.isError ? "error" : "complete") : isStreaming ? "inprogress" : "complete";
|
|
206
|
+
|
|
207
|
+
// Create refs for collapsible code section
|
|
208
|
+
const codeContentRef = createRef<HTMLDivElement>();
|
|
209
|
+
const codeChevronRef = createRef<HTMLSpanElement>();
|
|
210
|
+
|
|
211
|
+
// With result: show params + result
|
|
212
|
+
if (result && params) {
|
|
213
|
+
const output = result.output || "";
|
|
214
|
+
const files = result.details?.files || [];
|
|
215
|
+
|
|
216
|
+
const attachments: Attachment[] = files.map((f, i) => {
|
|
217
|
+
// Decode base64 content for text files to show in overlay
|
|
218
|
+
let extractedText: string | undefined;
|
|
219
|
+
const isTextBased =
|
|
220
|
+
f.mimeType?.startsWith("text/") ||
|
|
221
|
+
f.mimeType === "application/json" ||
|
|
222
|
+
f.mimeType === "application/javascript" ||
|
|
223
|
+
f.mimeType?.includes("xml");
|
|
224
|
+
|
|
225
|
+
if (isTextBased && f.contentBase64) {
|
|
226
|
+
try {
|
|
227
|
+
extractedText = atob(f.contentBase64);
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.warn("Failed to decode base64 content for", f.fileName);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
263
232
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
233
|
+
return {
|
|
234
|
+
id: `repl-${Date.now()}-${i}`,
|
|
235
|
+
type: f.mimeType?.startsWith("image/") ? "image" : "document",
|
|
236
|
+
fileName: f.fileName || `file-${i}`,
|
|
237
|
+
mimeType: f.mimeType || "application/octet-stream",
|
|
238
|
+
size: f.size ?? 0,
|
|
239
|
+
content: f.contentBase64,
|
|
240
|
+
preview: f.mimeType?.startsWith("image/") ? f.contentBase64 : undefined,
|
|
241
|
+
extractedText,
|
|
242
|
+
};
|
|
243
|
+
});
|
|
272
244
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
245
|
+
return {
|
|
246
|
+
content: html`
|
|
247
|
+
<div>
|
|
248
|
+
${renderCollapsibleHeader(state, Code, params.title ? params.title : i18n("Executing JavaScript"), codeContentRef, codeChevronRef, false)}
|
|
249
|
+
<div ${ref(codeContentRef)} class="max-h-0 overflow-hidden transition-all duration-300 space-y-3">
|
|
250
|
+
<code-block .code=${params.code || ""} language="javascript"></code-block>
|
|
251
|
+
${output ? html`<console-block .content=${output} .variant=${result.isError ? "error" : "default"}></console-block>` : ""}
|
|
252
|
+
</div>
|
|
253
|
+
${
|
|
254
|
+
attachments.length
|
|
255
|
+
? html`<div class="flex flex-wrap gap-2 mt-3">
|
|
256
|
+
${attachments.map((att) => html`<attachment-tile .attachment=${att}></attachment-tile>`)}
|
|
257
|
+
</div>`
|
|
258
|
+
: ""
|
|
259
|
+
}
|
|
260
|
+
</div>
|
|
261
|
+
`,
|
|
262
|
+
isCustom: false,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
280
265
|
|
|
266
|
+
// Just params (streaming or waiting for result)
|
|
267
|
+
if (params) {
|
|
281
268
|
return {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
269
|
+
content: html`
|
|
270
|
+
<div>
|
|
271
|
+
${renderCollapsibleHeader(state, Code, params.title ? params.title : i18n("Executing JavaScript"), codeContentRef, codeChevronRef, false)}
|
|
272
|
+
<div ${ref(codeContentRef)} class="max-h-0 overflow-hidden transition-all duration-300">
|
|
273
|
+
${params.code ? html`<code-block .code=${params.code} language="javascript"></code-block>` : ""}
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
`,
|
|
277
|
+
isCustom: false,
|
|
290
278
|
};
|
|
291
|
-
}
|
|
279
|
+
}
|
|
292
280
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
${output ? html`<console-block .content=${output}></console-block>` : ""}
|
|
296
|
-
${
|
|
297
|
-
attachments.length
|
|
298
|
-
? html`<div class="flex flex-wrap gap-2">
|
|
299
|
-
${attachments.map((att) => html`<attachment-tile .attachment=${att}></attachment-tile>`)}
|
|
300
|
-
</div>`
|
|
301
|
-
: ""
|
|
302
|
-
}
|
|
303
|
-
</div>
|
|
304
|
-
`;
|
|
281
|
+
// No params or result yet
|
|
282
|
+
return { content: renderHeader(state, Code, i18n("Preparing JavaScript...")), isCustom: false };
|
|
305
283
|
},
|
|
306
284
|
};
|
|
307
285
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { html, icon, type TemplateResult } from "@mariozechner/mini-lit";
|
|
2
|
+
import type { Ref } from "lit/directives/ref.js";
|
|
3
|
+
import { ref } from "lit/directives/ref.js";
|
|
4
|
+
import { ChevronRight, Loader } from "lucide";
|
|
1
5
|
import type { ToolRenderer } from "./types.js";
|
|
2
6
|
|
|
3
7
|
// Registry of tool renderers
|
|
@@ -16,3 +20,97 @@ export function registerToolRenderer(toolName: string, renderer: ToolRenderer):
|
|
|
16
20
|
export function getToolRenderer(toolName: string): ToolRenderer | undefined {
|
|
17
21
|
return toolRenderers.get(toolName);
|
|
18
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Helper to render a header for tool renderers
|
|
26
|
+
* Shows icon on left when complete/error, spinner on right when in progress
|
|
27
|
+
*/
|
|
28
|
+
export function renderHeader(
|
|
29
|
+
state: "inprogress" | "complete" | "error",
|
|
30
|
+
toolIcon: any,
|
|
31
|
+
text: string | TemplateResult,
|
|
32
|
+
): TemplateResult {
|
|
33
|
+
const statusIcon = (iconComponent: any, color: string) =>
|
|
34
|
+
html`<span class="inline-block ${color}">${icon(iconComponent, "sm")}</span>`;
|
|
35
|
+
|
|
36
|
+
switch (state) {
|
|
37
|
+
case "inprogress":
|
|
38
|
+
return html`
|
|
39
|
+
<div class="flex items-center justify-between gap-2 text-sm text-muted-foreground">
|
|
40
|
+
<div class="flex items-center gap-2">
|
|
41
|
+
${statusIcon(toolIcon, "text-foreground")}
|
|
42
|
+
${text}
|
|
43
|
+
</div>
|
|
44
|
+
${statusIcon(Loader, "text-foreground animate-spin")}
|
|
45
|
+
</div>
|
|
46
|
+
`;
|
|
47
|
+
case "complete":
|
|
48
|
+
return html`
|
|
49
|
+
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
|
50
|
+
${statusIcon(toolIcon, "text-green-600 dark:text-green-500")}
|
|
51
|
+
${text}
|
|
52
|
+
</div>
|
|
53
|
+
`;
|
|
54
|
+
case "error":
|
|
55
|
+
return html`
|
|
56
|
+
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
|
57
|
+
${statusIcon(toolIcon, "text-destructive")}
|
|
58
|
+
${text}
|
|
59
|
+
</div>
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Helper to render a collapsible header for tool renderers
|
|
66
|
+
* Same as renderHeader but with a chevron button that toggles visibility of content
|
|
67
|
+
*/
|
|
68
|
+
export function renderCollapsibleHeader(
|
|
69
|
+
state: "inprogress" | "complete" | "error",
|
|
70
|
+
toolIcon: any,
|
|
71
|
+
text: string | TemplateResult,
|
|
72
|
+
contentRef: Ref<HTMLElement>,
|
|
73
|
+
chevronRef: Ref<HTMLElement>,
|
|
74
|
+
defaultExpanded = false,
|
|
75
|
+
): TemplateResult {
|
|
76
|
+
const statusIcon = (iconComponent: any, color: string) =>
|
|
77
|
+
html`<span class="inline-block ${color}">${icon(iconComponent, "sm")}</span>`;
|
|
78
|
+
|
|
79
|
+
const toggleContent = (e: Event) => {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
const content = contentRef.value;
|
|
82
|
+
const chevron = chevronRef.value;
|
|
83
|
+
if (content && chevron) {
|
|
84
|
+
const isCollapsed = content.classList.contains("max-h-0");
|
|
85
|
+
if (isCollapsed) {
|
|
86
|
+
content.classList.remove("max-h-0");
|
|
87
|
+
content.classList.add("max-h-[2000px]", "mt-3");
|
|
88
|
+
chevron.classList.add("rotate-90");
|
|
89
|
+
} else {
|
|
90
|
+
content.classList.remove("max-h-[2000px]", "mt-3");
|
|
91
|
+
content.classList.add("max-h-0");
|
|
92
|
+
chevron.classList.remove("rotate-90");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const toolIconColor =
|
|
98
|
+
state === "complete"
|
|
99
|
+
? "text-green-600 dark:text-green-500"
|
|
100
|
+
: state === "error"
|
|
101
|
+
? "text-destructive"
|
|
102
|
+
: "text-foreground";
|
|
103
|
+
|
|
104
|
+
return html`
|
|
105
|
+
<button @click=${toggleContent} class="flex items-center justify-between gap-2 text-sm text-muted-foreground w-full text-left hover:text-foreground transition-colors cursor-pointer">
|
|
106
|
+
<div class="flex items-center gap-2">
|
|
107
|
+
${state === "inprogress" ? statusIcon(Loader, "text-foreground animate-spin") : ""}
|
|
108
|
+
${statusIcon(toolIcon, toolIconColor)}
|
|
109
|
+
${text}
|
|
110
|
+
</div>
|
|
111
|
+
<span class="inline-block text-muted-foreground transition-transform duration-300 ${defaultExpanded ? "rotate-90" : ""}" ${ref(chevronRef)}>
|
|
112
|
+
${icon(ChevronRight, "sm")}
|
|
113
|
+
</span>
|
|
114
|
+
</button>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { html
|
|
1
|
+
import { html } from "@mariozechner/mini-lit";
|
|
2
2
|
import type { ToolResultMessage } from "@mariozechner/pi-ai";
|
|
3
|
+
import { SquareTerminal } from "lucide";
|
|
3
4
|
import { i18n } from "../../utils/i18n.js";
|
|
4
|
-
import
|
|
5
|
+
import { renderHeader } from "../renderer-registry.js";
|
|
6
|
+
import type { ToolRenderer, ToolRenderResult } from "../types.js";
|
|
5
7
|
|
|
6
8
|
interface BashParams {
|
|
7
9
|
command: string;
|
|
@@ -9,37 +11,38 @@ interface BashParams {
|
|
|
9
11
|
|
|
10
12
|
// Bash tool has undefined details (only uses output)
|
|
11
13
|
export class BashRenderer implements ToolRenderer<BashParams, undefined> {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return html`<div class="text-sm text-muted-foreground">${i18n("Writing command...")}</div>`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return html`
|
|
18
|
-
<div class="text-sm text-muted-foreground">
|
|
19
|
-
<span>${i18n("Running command:")}</span>
|
|
20
|
-
<code class="ml-1 px-1.5 py-0.5 bg-muted rounded text-xs font-mono">${params.command}</code>
|
|
21
|
-
</div>
|
|
22
|
-
`;
|
|
23
|
-
}
|
|
14
|
+
render(params: BashParams | undefined, result: ToolResultMessage<undefined> | undefined): ToolRenderResult {
|
|
15
|
+
const state = result ? (result.isError ? "error" : "complete") : "inprogress";
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
// With result: show command + output
|
|
18
|
+
if (result && params?.command) {
|
|
19
|
+
const output = result.output || "";
|
|
20
|
+
const combined = output ? `> ${params.command}\n\n${output}` : `> ${params.command}`;
|
|
21
|
+
return {
|
|
22
|
+
content: html`
|
|
23
|
+
<div class="space-y-3">
|
|
24
|
+
${renderHeader(state, SquareTerminal, i18n("Running command..."))}
|
|
25
|
+
<console-block .content=${combined} .variant=${result.isError ? "error" : "default"}></console-block>
|
|
26
|
+
</div>
|
|
27
|
+
`,
|
|
28
|
+
isCustom: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Just params (streaming or waiting)
|
|
33
|
+
if (params?.command) {
|
|
34
|
+
return {
|
|
35
|
+
content: html`
|
|
36
|
+
<div class="space-y-3">
|
|
37
|
+
${renderHeader(state, SquareTerminal, i18n("Running command..."))}
|
|
38
|
+
<console-block .content=${`> ${params.command}`}></console-block>
|
|
39
|
+
</div>
|
|
40
|
+
`,
|
|
41
|
+
isCustom: false,
|
|
42
|
+
};
|
|
36
43
|
}
|
|
37
44
|
|
|
38
|
-
//
|
|
39
|
-
return
|
|
40
|
-
<div class="text-sm">
|
|
41
|
-
<pre class="text-xs font-mono text-foreground bg-muted/50 p-2 rounded overflow-x-auto">${output}</pre>
|
|
42
|
-
</div>
|
|
43
|
-
`;
|
|
45
|
+
// No params yet
|
|
46
|
+
return { content: renderHeader(state, SquareTerminal, i18n("Waiting for command...")), isCustom: false };
|
|
44
47
|
}
|
|
45
48
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { html
|
|
1
|
+
import { html } from "@mariozechner/mini-lit";
|
|
2
2
|
import type { ToolResultMessage } from "@mariozechner/pi-ai";
|
|
3
|
+
import { Calculator } from "lucide";
|
|
3
4
|
import { i18n } from "../../utils/i18n.js";
|
|
4
|
-
import
|
|
5
|
+
import { renderHeader } from "../renderer-registry.js";
|
|
6
|
+
import type { ToolRenderer, ToolRenderResult } from "../types.js";
|
|
5
7
|
|
|
6
8
|
interface CalculateParams {
|
|
7
9
|
expression: string;
|
|
@@ -9,41 +11,44 @@ interface CalculateParams {
|
|
|
9
11
|
|
|
10
12
|
// Calculate tool has undefined details (only uses output)
|
|
11
13
|
export class CalculateRenderer implements ToolRenderer<CalculateParams, undefined> {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return html`<div class="text-sm text-muted-foreground">${i18n("Writing expression...")}</div>`;
|
|
15
|
-
}
|
|
14
|
+
render(params: CalculateParams | undefined, result: ToolResultMessage<undefined> | undefined): ToolRenderResult {
|
|
15
|
+
const state = result ? (result.isError ? "error" : "complete") : "inprogress";
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<code class="mx-1 px-1.5 py-0.5 bg-muted rounded text-xs font-mono">${params.expression}</code>
|
|
21
|
-
</div>
|
|
22
|
-
`;
|
|
23
|
-
}
|
|
17
|
+
// Full params + full result
|
|
18
|
+
if (result && params?.expression) {
|
|
19
|
+
const output = result.output || "";
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
// Error: show expression in header, error below
|
|
22
|
+
if (result.isError) {
|
|
23
|
+
return {
|
|
24
|
+
content: html`
|
|
25
|
+
<div class="space-y-3">
|
|
26
|
+
${renderHeader(state, Calculator, params.expression)}
|
|
27
|
+
<div class="text-sm text-destructive">${output}</div>
|
|
28
|
+
</div>
|
|
29
|
+
`,
|
|
30
|
+
isCustom: false,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Success: show expression = result in header
|
|
35
|
+
return { content: renderHeader(state, Calculator, `${params.expression} = ${output}`), isCustom: false };
|
|
36
|
+
}
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
// Full params, no result: just show header with expression in it
|
|
39
|
+
if (params?.expression) {
|
|
40
|
+
return {
|
|
41
|
+
content: renderHeader(state, Calculator, `${i18n("Calculating")} ${params.expression}`),
|
|
42
|
+
isCustom: false,
|
|
43
|
+
};
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return html`
|
|
38
|
-
<div class="text-sm font-mono">
|
|
39
|
-
<span class="text-muted-foreground">${parts[0]}</span>
|
|
40
|
-
<span class="text-muted-foreground mx-1">=</span>
|
|
41
|
-
<span class="text-foreground font-semibold">${parts[1]}</span>
|
|
42
|
-
</div>
|
|
43
|
-
`;
|
|
46
|
+
// Partial params (empty expression), no result
|
|
47
|
+
if (params && !params.expression) {
|
|
48
|
+
return { content: renderHeader(state, Calculator, i18n("Writing expression...")), isCustom: false };
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
//
|
|
47
|
-
return
|
|
51
|
+
// No params, no result
|
|
52
|
+
return { content: renderHeader(state, Calculator, i18n("Waiting for expression...")), isCustom: false };
|
|
48
53
|
}
|
|
49
54
|
}
|