@elyracode/web-ui 0.9.9 → 0.9.11
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/CHANGELOG.md +10 -0
- package/dist/ChatPanel.d.ts +1 -1
- package/dist/ChatPanel.d.ts.map +1 -1
- package/dist/app.css +2 -2
- package/dist/components/AgentInterface.d.ts +1 -1
- package/dist/components/AgentInterface.d.ts.map +1 -1
- package/dist/components/AgentInterface.js +1 -1
- package/dist/components/AgentInterface.js.map +1 -1
- package/dist/components/MessageEditor.d.ts +2 -2
- package/dist/components/MessageEditor.d.ts.map +1 -1
- package/dist/components/Messages.d.ts +3 -3
- package/dist/components/Messages.d.ts.map +1 -1
- package/dist/components/Messages.js.map +1 -1
- package/dist/components/ProviderKeyInput.js +2 -2
- package/dist/components/ProviderKeyInput.js.map +1 -1
- package/dist/components/SandboxedIframe.d.ts +1 -1
- package/dist/components/SandboxedIframe.d.ts.map +1 -1
- package/dist/components/SandboxedIframe.js +1 -1
- package/dist/components/SandboxedIframe.js.map +1 -1
- package/dist/components/message-renderer-registry.js.map +1 -1
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +4 -3
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js +31 -31
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +1 -1
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js +6 -5
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +3 -2
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/ConsoleRuntimeProvider.js +12 -11
- package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +3 -2
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js +6 -4
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts +2 -1
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -1
- package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -1
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +3 -2
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/runtime-messages.d.ts +140 -0
- package/dist/components/sandbox/runtime-messages.d.ts.map +1 -0
- package/dist/components/sandbox/runtime-messages.js +9 -0
- package/dist/components/sandbox/runtime-messages.js.map +1 -0
- package/dist/dialogs/AttachmentOverlay.d.ts.map +1 -1
- package/dist/dialogs/AttachmentOverlay.js +4 -4
- package/dist/dialogs/AttachmentOverlay.js.map +1 -1
- package/dist/dialogs/ModelSelector.d.ts +3 -3
- package/dist/dialogs/ModelSelector.d.ts.map +1 -1
- package/dist/dialogs/ModelSelector.js.map +1 -1
- package/dist/storage/stores/custom-providers-store.d.ts +2 -2
- package/dist/storage/stores/custom-providers-store.d.ts.map +1 -1
- package/dist/storage/types.d.ts +2 -2
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/tools/artifacts/DocxArtifact.js +1 -1
- package/dist/tools/artifacts/DocxArtifact.js.map +1 -1
- package/dist/tools/artifacts/ExcelArtifact.js +1 -1
- package/dist/tools/artifacts/ExcelArtifact.js.map +1 -1
- package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.js +1 -1
- package/dist/tools/artifacts/PdfArtifact.js.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -1
- package/dist/tools/artifacts/artifacts.js.map +1 -1
- package/dist/tools/extract-document.js +1 -1
- package/dist/tools/extract-document.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/javascript-repl.js.map +1 -1
- package/dist/tools/renderer-registry.d.ts +4 -3
- package/dist/tools/renderer-registry.d.ts.map +1 -1
- package/dist/tools/renderer-registry.js.map +1 -1
- package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/BashRenderer.js.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.d.ts +1 -1
- package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
- package/dist/tools/types.d.ts +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/attachment-utils.js +1 -1
- package/dist/utils/attachment-utils.js.map +1 -1
- package/dist/utils/format.d.ts +2 -2
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/model-discovery.d.ts +6 -6
- package/dist/utils/model-discovery.d.ts.map +1 -1
- package/dist/utils/model-discovery.js +3 -3
- package/dist/utils/model-discovery.js.map +1 -1
- package/dist/utils/proxy-utils.d.ts +1 -1
- package/example/package.json +23 -23
- package/example/src/css-modules.d.ts +3 -0
- package/package.json +6 -6
- package/src/ChatPanel.ts +1 -1
- package/src/components/AgentInterface.ts +5 -5
- package/src/components/MessageEditor.ts +2 -2
- package/src/components/Messages.ts +6 -6
- package/src/components/ProviderKeyInput.ts +3 -3
- package/src/components/SandboxedIframe.ts +7 -6
- package/src/components/message-renderer-registry.ts +1 -1
- package/src/components/sandbox/ArtifactsRuntimeProvider.ts +40 -44
- package/src/components/sandbox/AttachmentsRuntimeProvider.ts +9 -7
- package/src/components/sandbox/ConsoleRuntimeProvider.ts +19 -17
- package/src/components/sandbox/FileDownloadRuntimeProvider.ts +11 -7
- package/src/components/sandbox/RuntimeMessageRouter.ts +7 -8
- package/src/components/sandbox/SandboxRuntimeProvider.ts +4 -2
- package/src/components/sandbox/runtime-messages.ts +146 -0
- package/src/dialogs/AttachmentOverlay.ts +12 -11
- package/src/dialogs/CustomProviderDialog.ts +2 -2
- package/src/dialogs/ModelSelector.ts +11 -11
- package/src/storage/stores/custom-providers-store.ts +2 -2
- package/src/storage/types.ts +2 -2
- package/src/tools/artifacts/DocxArtifact.ts +2 -2
- package/src/tools/artifacts/ExcelArtifact.ts +3 -3
- package/src/tools/artifacts/HtmlArtifact.ts +1 -1
- package/src/tools/artifacts/PdfArtifact.ts +5 -4
- package/src/tools/artifacts/artifacts-tool-renderer.ts +4 -4
- package/src/tools/artifacts/artifacts.ts +4 -4
- package/src/tools/extract-document.ts +6 -6
- package/src/tools/index.ts +1 -1
- package/src/tools/javascript-repl.ts +3 -3
- package/src/tools/renderer-registry.ts +5 -5
- package/src/tools/renderers/BashRenderer.ts +3 -3
- package/src/tools/renderers/CalculateRenderer.ts +3 -3
- package/src/tools/renderers/DefaultRenderer.ts +5 -5
- package/src/tools/renderers/GetCurrentTimeRenderer.ts +5 -5
- package/src/tools/types.ts +1 -1
- package/src/utils/attachment-utils.ts +10 -3
- package/src/utils/format.ts +2 -2
- package/src/utils/model-discovery.ts +35 -22
- package/src/utils/proxy-utils.ts +1 -1
|
@@ -5,6 +5,7 @@ import { renderAsync } from "docx-preview";
|
|
|
5
5
|
import { html, LitElement } from "lit";
|
|
6
6
|
import { state } from "lit/decorators.js";
|
|
7
7
|
import { Download, X } from "lucide";
|
|
8
|
+
import type { PDFDocumentLoadingTask, PDFDocumentProxy } from "pdfjs-dist";
|
|
8
9
|
import * as pdfjsLib from "pdfjs-dist";
|
|
9
10
|
import * as XLSX from "xlsx";
|
|
10
11
|
import type { Attachment } from "../utils/attachment-utils.js";
|
|
@@ -18,7 +19,7 @@ export class AttachmentOverlay extends LitElement {
|
|
|
18
19
|
@state() private error: string | null = null;
|
|
19
20
|
|
|
20
21
|
// Track current loading task to cancel if needed
|
|
21
|
-
private currentLoadingTask:
|
|
22
|
+
private currentLoadingTask: PDFDocumentLoadingTask | null = null;
|
|
22
23
|
private onCloseCallback?: () => void;
|
|
23
24
|
private boundHandleKeyDown?: (e: KeyboardEvent) => void;
|
|
24
25
|
|
|
@@ -304,7 +305,7 @@ export class AttachmentOverlay extends LitElement {
|
|
|
304
305
|
const container = this.querySelector("#pdf-container");
|
|
305
306
|
if (!container || !this.attachment) return;
|
|
306
307
|
|
|
307
|
-
let pdf:
|
|
308
|
+
let pdf: PDFDocumentProxy | null = null;
|
|
308
309
|
|
|
309
310
|
try {
|
|
310
311
|
// Convert base64 to ArrayBuffer
|
|
@@ -370,9 +371,9 @@ export class AttachmentOverlay extends LitElement {
|
|
|
370
371
|
|
|
371
372
|
wrapper.appendChild(pageContainer);
|
|
372
373
|
}
|
|
373
|
-
} catch (error
|
|
374
|
+
} catch (error) {
|
|
374
375
|
console.error("Error rendering PDF:", error);
|
|
375
|
-
this.error = error
|
|
376
|
+
this.error = (error instanceof Error ? error.message : undefined) || i18n("Failed to load PDF");
|
|
376
377
|
} finally {
|
|
377
378
|
if (pdf) {
|
|
378
379
|
pdf.destroy();
|
|
@@ -475,9 +476,9 @@ export class AttachmentOverlay extends LitElement {
|
|
|
475
476
|
}
|
|
476
477
|
`;
|
|
477
478
|
container.appendChild(style);
|
|
478
|
-
} catch (error
|
|
479
|
+
} catch (error) {
|
|
479
480
|
console.error("Error rendering DOCX:", error);
|
|
480
|
-
this.error = error
|
|
481
|
+
this.error = (error instanceof Error ? error.message : undefined) || i18n("Failed to load document");
|
|
481
482
|
}
|
|
482
483
|
}
|
|
483
484
|
|
|
@@ -550,13 +551,13 @@ export class AttachmentOverlay extends LitElement {
|
|
|
550
551
|
const sheetName = workbook.SheetNames[0];
|
|
551
552
|
wrapper.appendChild(this.renderExcelSheet(workbook.Sheets[sheetName], sheetName));
|
|
552
553
|
}
|
|
553
|
-
} catch (error
|
|
554
|
+
} catch (error) {
|
|
554
555
|
console.error("Error rendering Excel:", error);
|
|
555
|
-
this.error = error
|
|
556
|
+
this.error = (error instanceof Error ? error.message : undefined) || i18n("Failed to load spreadsheet");
|
|
556
557
|
}
|
|
557
558
|
}
|
|
558
559
|
|
|
559
|
-
private renderExcelSheet(worksheet:
|
|
560
|
+
private renderExcelSheet(worksheet: XLSX.WorkSheet, sheetName: string): HTMLElement {
|
|
560
561
|
const sheetDiv = document.createElement("div");
|
|
561
562
|
|
|
562
563
|
// Generate HTML table
|
|
@@ -623,9 +624,9 @@ export class AttachmentOverlay extends LitElement {
|
|
|
623
624
|
|
|
624
625
|
wrapper.appendChild(pre);
|
|
625
626
|
container.appendChild(wrapper);
|
|
626
|
-
} catch (error
|
|
627
|
+
} catch (error) {
|
|
627
628
|
console.error("Error rendering extracted text:", error);
|
|
628
|
-
this.error = error
|
|
629
|
+
this.error = (error instanceof Error ? error.message : undefined) || i18n("Failed to display text content");
|
|
629
630
|
}
|
|
630
631
|
}
|
|
631
632
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Model } from "@elyracode/ai";
|
|
1
|
+
import type { Api, Model } from "@elyracode/ai";
|
|
2
2
|
import { i18n } from "@elyracode/mini-lit";
|
|
3
3
|
import { Button } from "@elyracode/mini-lit/dist/Button.js";
|
|
4
4
|
import { DialogBase } from "@elyracode/mini-lit/dist/DialogBase.js";
|
|
@@ -22,7 +22,7 @@ export class CustomProviderDialog extends DialogBase {
|
|
|
22
22
|
@state() private apiKey = "";
|
|
23
23
|
@state() private testing = false;
|
|
24
24
|
@state() private testError = "";
|
|
25
|
-
@state() private discoveredModels: Model<
|
|
25
|
+
@state() private discoveredModels: Model<Api>[] = [];
|
|
26
26
|
|
|
27
27
|
protected modalWidth = "min(800px, 90vw)";
|
|
28
28
|
protected modalHeight = "min(700px, 90vh)";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getModels, getProviders, type Model, modelsAreEqual } from "@elyracode/ai";
|
|
1
|
+
import { type Api, getModels, getProviders, type Model, modelsAreEqual } from "@elyracode/ai";
|
|
2
2
|
import { icon } from "@elyracode/mini-lit";
|
|
3
3
|
import { Badge } from "@elyracode/mini-lit/dist/Badge.js";
|
|
4
4
|
import { Button } from "@elyracode/mini-lit/dist/Button.js";
|
|
@@ -48,16 +48,16 @@ function subsequenceScore(query: string, text: string): number {
|
|
|
48
48
|
|
|
49
49
|
@customElement("agent-model-selector")
|
|
50
50
|
export class ModelSelector extends DialogBase {
|
|
51
|
-
@state() currentModel: Model<
|
|
51
|
+
@state() currentModel: Model<Api> | null = null;
|
|
52
52
|
@state() searchQuery = "";
|
|
53
53
|
@state() filterThinking = false;
|
|
54
54
|
@state() filterVision = false;
|
|
55
55
|
@state() customProvidersLoading = false;
|
|
56
56
|
@state() selectedIndex = 0;
|
|
57
57
|
@state() private navigationMode: "mouse" | "keyboard" = "mouse";
|
|
58
|
-
@state() private customProviderModels: Model<
|
|
58
|
+
@state() private customProviderModels: Model<Api>[] = [];
|
|
59
59
|
|
|
60
|
-
private onSelectCallback?: (model: Model<
|
|
60
|
+
private onSelectCallback?: (model: Model<Api>) => void;
|
|
61
61
|
private allowedProviders?: Set<string>;
|
|
62
62
|
private scrollContainerRef = createRef<HTMLDivElement>();
|
|
63
63
|
private searchInputRef = createRef<HTMLInputElement>();
|
|
@@ -66,8 +66,8 @@ export class ModelSelector extends DialogBase {
|
|
|
66
66
|
protected override modalWidth = "min(400px, 90vw)";
|
|
67
67
|
|
|
68
68
|
static async open(
|
|
69
|
-
currentModel: Model<
|
|
70
|
-
onSelect: (model: Model<
|
|
69
|
+
currentModel: Model<Api> | null,
|
|
70
|
+
onSelect: (model: Model<Api>) => void,
|
|
71
71
|
allowedProviders?: string[],
|
|
72
72
|
) {
|
|
73
73
|
const selector = new ModelSelector();
|
|
@@ -140,7 +140,7 @@ export class ModelSelector extends DialogBase {
|
|
|
140
140
|
|
|
141
141
|
private async loadCustomProviders() {
|
|
142
142
|
this.customProvidersLoading = true;
|
|
143
|
-
const allCustomModels: Model<
|
|
143
|
+
const allCustomModels: Model<Api>[] = [];
|
|
144
144
|
|
|
145
145
|
try {
|
|
146
146
|
const storage = getAppStorage();
|
|
@@ -191,20 +191,20 @@ export class ModelSelector extends DialogBase {
|
|
|
191
191
|
return String(tokens);
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
private handleSelect(model: Model<
|
|
194
|
+
private handleSelect(model: Model<Api>) {
|
|
195
195
|
if (model) {
|
|
196
196
|
this.onSelectCallback?.(model);
|
|
197
197
|
this.close();
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
private getFilteredModels(): Array<{ provider: string; id: string; model:
|
|
201
|
+
private getFilteredModels(): Array<{ provider: string; id: string; model: Model<Api> }> {
|
|
202
202
|
// Collect all models from known providers
|
|
203
|
-
const allModels: Array<{ provider: string; id: string; model:
|
|
203
|
+
const allModels: Array<{ provider: string; id: string; model: Model<Api> }> = [];
|
|
204
204
|
const knownProviders = getProviders();
|
|
205
205
|
|
|
206
206
|
for (const provider of knownProviders) {
|
|
207
|
-
const models = getModels(provider
|
|
207
|
+
const models = getModels(provider);
|
|
208
208
|
for (const model of models) {
|
|
209
209
|
allModels.push({ provider, id: model.id, model });
|
|
210
210
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Model } from "@elyracode/ai";
|
|
1
|
+
import type { Api, Model } from "@elyracode/ai";
|
|
2
2
|
import { Store } from "../store.js";
|
|
3
3
|
import type { StoreConfig } from "../types.js";
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ export interface CustomProvider {
|
|
|
19
19
|
|
|
20
20
|
// For manual types ONLY - models stored directly on provider
|
|
21
21
|
// Auto-discovery types: models fetched on-demand, never stored
|
|
22
|
-
models?: Model<
|
|
22
|
+
models?: Model<Api>[];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
package/src/storage/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentMessage, ThinkingLevel } from "@elyracode/agent-core";
|
|
2
|
-
import type { Model } from "@elyracode/ai";
|
|
2
|
+
import type { Api, Model } from "@elyracode/ai";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Transaction interface for atomic operations across stores.
|
|
@@ -152,7 +152,7 @@ export interface SessionData {
|
|
|
152
152
|
title: string;
|
|
153
153
|
|
|
154
154
|
/** Last selected model */
|
|
155
|
-
model: Model<
|
|
155
|
+
model: Model<Api>;
|
|
156
156
|
|
|
157
157
|
/** Last selected thinking level */
|
|
158
158
|
thinkingLevel: ThinkingLevel;
|
|
@@ -180,9 +180,9 @@ export class DocxArtifact extends ArtifactElement {
|
|
|
180
180
|
}
|
|
181
181
|
`;
|
|
182
182
|
container.appendChild(style);
|
|
183
|
-
} catch (error
|
|
183
|
+
} catch (error) {
|
|
184
184
|
console.error("Error rendering DOCX:", error);
|
|
185
|
-
this.error = error
|
|
185
|
+
this.error = error instanceof Error ? error.message : i18n("Failed to load document");
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -157,13 +157,13 @@ export class ExcelArtifact extends ArtifactElement {
|
|
|
157
157
|
const sheetName = workbook.SheetNames[0];
|
|
158
158
|
wrapper.appendChild(this.renderExcelSheet(workbook.Sheets[sheetName], sheetName));
|
|
159
159
|
}
|
|
160
|
-
} catch (error
|
|
160
|
+
} catch (error) {
|
|
161
161
|
console.error("Error rendering Excel:", error);
|
|
162
|
-
this.error = error
|
|
162
|
+
this.error = error instanceof Error ? error.message : i18n("Failed to load spreadsheet");
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
private renderExcelSheet(worksheet:
|
|
166
|
+
private renderExcelSheet(worksheet: XLSX.WorkSheet, sheetName: string): HTMLElement {
|
|
167
167
|
const sheetDiv = document.createElement("div");
|
|
168
168
|
|
|
169
169
|
// Generate HTML table
|
|
@@ -104,7 +104,7 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
104
104
|
|
|
105
105
|
// Create consumer for console messages
|
|
106
106
|
const consumer: MessageConsumer = {
|
|
107
|
-
handleMessage: async (message
|
|
107
|
+
handleMessage: async (message): Promise<void> => {
|
|
108
108
|
if (message.type === "console") {
|
|
109
109
|
// Create new array reference for Lit reactivity
|
|
110
110
|
this.logs = [
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DownloadButton } from "@elyracode/mini-lit/dist/DownloadButton.js";
|
|
2
2
|
import { html, type TemplateResult } from "lit";
|
|
3
3
|
import { customElement, property, state } from "lit/decorators.js";
|
|
4
|
+
import type { PDFDocumentLoadingTask, PDFDocumentProxy } from "pdfjs-dist";
|
|
4
5
|
import * as pdfjsLib from "pdfjs-dist";
|
|
5
6
|
import { i18n } from "../../utils/i18n.js";
|
|
6
7
|
import { ArtifactElement } from "./ArtifactElement.js";
|
|
@@ -12,7 +13,7 @@ pdfjsLib.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.mi
|
|
|
12
13
|
export class PdfArtifact extends ArtifactElement {
|
|
13
14
|
@property({ type: String }) private _content = "";
|
|
14
15
|
@state() private error: string | null = null;
|
|
15
|
-
private currentLoadingTask:
|
|
16
|
+
private currentLoadingTask: PDFDocumentLoadingTask | null = null;
|
|
16
17
|
|
|
17
18
|
get content(): string {
|
|
18
19
|
return this._content;
|
|
@@ -106,7 +107,7 @@ export class PdfArtifact extends ArtifactElement {
|
|
|
106
107
|
const container = this.querySelector("#pdf-container");
|
|
107
108
|
if (!container || !this._content) return;
|
|
108
109
|
|
|
109
|
-
let pdf:
|
|
110
|
+
let pdf: PDFDocumentProxy | null = null;
|
|
110
111
|
|
|
111
112
|
try {
|
|
112
113
|
const arrayBuffer = this.base64ToArrayBuffer(this._content);
|
|
@@ -164,9 +165,9 @@ export class PdfArtifact extends ArtifactElement {
|
|
|
164
165
|
|
|
165
166
|
wrapper.appendChild(pageContainer);
|
|
166
167
|
}
|
|
167
|
-
} catch (error
|
|
168
|
+
} catch (error) {
|
|
168
169
|
console.error("Error rendering PDF:", error);
|
|
169
|
-
this.error = error
|
|
170
|
+
this.error = error instanceof Error ? error.message : i18n("Failed to load PDF");
|
|
170
171
|
} finally {
|
|
171
172
|
if (pdf) {
|
|
172
173
|
pdf.destroy();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "@elyracode/mini-lit/dist/CodeBlock.js";
|
|
2
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
2
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
3
3
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
4
4
|
import { FileCode2 } from "lucide";
|
|
5
5
|
import "../../components/ConsoleBlock.js";
|
|
@@ -12,12 +12,12 @@ import { ArtifactPill } from "./ArtifactPill.js";
|
|
|
12
12
|
import type { ArtifactsPanel, ArtifactsParams } from "./artifacts.js";
|
|
13
13
|
|
|
14
14
|
// Helper to extract text from content blocks
|
|
15
|
-
function getTextOutput(result: ToolResultMessage<
|
|
15
|
+
function getTextOutput(result: ToolResultMessage<unknown> | undefined): string {
|
|
16
16
|
if (!result) return "";
|
|
17
17
|
return (
|
|
18
18
|
result.content
|
|
19
|
-
?.filter((c) => c.type === "text")
|
|
20
|
-
.map((c
|
|
19
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
20
|
+
.map((c) => c.text)
|
|
21
21
|
.join("\n") || ""
|
|
22
22
|
);
|
|
23
23
|
}
|
|
@@ -311,7 +311,7 @@ export class ArtifactsPanel extends LitElement {
|
|
|
311
311
|
// 2) Build an ordered list of successful artifact operations
|
|
312
312
|
const operations: Array<ArtifactsParams> = [];
|
|
313
313
|
for (const m of messages) {
|
|
314
|
-
if (
|
|
314
|
+
if (m.role === "artifact") {
|
|
315
315
|
const artifactMsg = m as ArtifactMessage;
|
|
316
316
|
switch (artifactMsg.action) {
|
|
317
317
|
case "create":
|
|
@@ -337,8 +337,8 @@ export class ArtifactsPanel extends LitElement {
|
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
// Handle tool result messages (from artifacts tool calls)
|
|
340
|
-
else if (
|
|
341
|
-
const toolCallId =
|
|
340
|
+
else if (m.role === "toolResult" && m.toolName === artifactToolName && !m.isError) {
|
|
341
|
+
const toolCallId = m.toolCallId;
|
|
342
342
|
const call = toolCalls.get(toolCallId);
|
|
343
343
|
if (!call) continue;
|
|
344
344
|
const params = call.arguments as ArtifactsParams;
|
|
@@ -431,7 +431,7 @@ export class ArtifactsPanel extends LitElement {
|
|
|
431
431
|
return this.getLogs(params);
|
|
432
432
|
default:
|
|
433
433
|
// Should never happen with TypeBox validation
|
|
434
|
-
return `Error: Unknown command ${(params as
|
|
434
|
+
return `Error: Unknown command ${(params as { command: string }).command}`;
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentTool } from "@elyracode/agent-core";
|
|
2
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
2
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
3
3
|
import { html } from "lit";
|
|
4
4
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
5
5
|
import { FileText } from "lucide";
|
|
@@ -103,17 +103,17 @@ export function createExtractDocumentTool(): AgentTool<typeof extractDocumentSch
|
|
|
103
103
|
try {
|
|
104
104
|
// Attempt direct fetch first
|
|
105
105
|
arrayBuffer = await fetchAndProcess(url);
|
|
106
|
-
} catch (directError
|
|
106
|
+
} catch (directError) {
|
|
107
107
|
// If CORS error and proxy is available, retry with proxy
|
|
108
108
|
if (isCorsError(directError) && tool.corsProxyUrl) {
|
|
109
109
|
try {
|
|
110
110
|
const proxiedUrl = tool.corsProxyUrl + encodeURIComponent(url);
|
|
111
111
|
arrayBuffer = await fetchAndProcess(proxiedUrl);
|
|
112
|
-
} catch (proxyError
|
|
112
|
+
} catch (proxyError) {
|
|
113
113
|
// Proxy fetch also failed - throw helpful message
|
|
114
114
|
throw new Error(
|
|
115
115
|
`TELL USER: Unable to fetch the document due to CORS restrictions.\n\n` +
|
|
116
|
-
`Tried with proxy but it also failed: ${proxyError.message}\n\n` +
|
|
116
|
+
`Tried with proxy but it also failed: ${proxyError instanceof Error ? proxyError.message : String(proxyError)}\n\n` +
|
|
117
117
|
`INSTRUCT USER: Please download the file manually and attach it to your message using the attachment button (paperclip icon) in the message input area. I can then extract the text from the attached file.`,
|
|
118
118
|
);
|
|
119
119
|
}
|
|
@@ -213,8 +213,8 @@ export const extractDocumentRenderer: ToolRenderer<ExtractDocumentParams, Extrac
|
|
|
213
213
|
|
|
214
214
|
const output =
|
|
215
215
|
result.content
|
|
216
|
-
?.filter((c) => c.type === "text")
|
|
217
|
-
.map((c
|
|
216
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
217
|
+
.map((c) => c.text)
|
|
218
218
|
.join("\n") || "";
|
|
219
219
|
|
|
220
220
|
return {
|
package/src/tools/index.ts
CHANGED
|
@@ -27,7 +27,7 @@ export function setShowJsonMode(enabled: boolean): void {
|
|
|
27
27
|
*/
|
|
28
28
|
export function renderTool(
|
|
29
29
|
toolName: string,
|
|
30
|
-
params:
|
|
30
|
+
params: unknown | undefined,
|
|
31
31
|
result: ToolResultMessage | undefined,
|
|
32
32
|
isStreaming?: boolean,
|
|
33
33
|
): ToolRenderResult {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentTool } from "@elyracode/agent-core";
|
|
2
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
2
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
3
3
|
import { i18n } from "@elyracode/mini-lit";
|
|
4
4
|
import { html } from "lit";
|
|
5
5
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
@@ -214,8 +214,8 @@ export const javascriptReplRenderer: ToolRenderer<JavaScriptReplParams, JavaScri
|
|
|
214
214
|
if (result && params) {
|
|
215
215
|
const output =
|
|
216
216
|
result.content
|
|
217
|
-
?.filter((c) => c.type === "text")
|
|
218
|
-
.map((c
|
|
217
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
218
|
+
.map((c) => c.text)
|
|
219
219
|
.join("\n") || "";
|
|
220
220
|
const files = result.details?.files || [];
|
|
221
221
|
|
|
@@ -2,7 +2,7 @@ import { icon } from "@elyracode/mini-lit";
|
|
|
2
2
|
import { html, type TemplateResult } from "lit";
|
|
3
3
|
import type { Ref } from "lit/directives/ref.js";
|
|
4
4
|
import { ref } from "lit/directives/ref.js";
|
|
5
|
-
import { ChevronsUpDown, ChevronUp, Loader } from "lucide";
|
|
5
|
+
import { ChevronsUpDown, ChevronUp, type IconNode, Loader } from "lucide";
|
|
6
6
|
import type { ToolRenderer } from "./types.js";
|
|
7
7
|
|
|
8
8
|
// Registry of tool renderers
|
|
@@ -28,10 +28,10 @@ export function getToolRenderer(toolName: string): ToolRenderer | undefined {
|
|
|
28
28
|
*/
|
|
29
29
|
export function renderHeader(
|
|
30
30
|
state: "inprogress" | "complete" | "error",
|
|
31
|
-
toolIcon:
|
|
31
|
+
toolIcon: IconNode,
|
|
32
32
|
text: string | TemplateResult,
|
|
33
33
|
): TemplateResult {
|
|
34
|
-
const statusIcon = (iconComponent:
|
|
34
|
+
const statusIcon = (iconComponent: IconNode, color: string) =>
|
|
35
35
|
html`<span class="inline-block ${color}">${icon(iconComponent, "sm")}</span>`;
|
|
36
36
|
|
|
37
37
|
switch (state) {
|
|
@@ -68,13 +68,13 @@ export function renderHeader(
|
|
|
68
68
|
*/
|
|
69
69
|
export function renderCollapsibleHeader(
|
|
70
70
|
state: "inprogress" | "complete" | "error",
|
|
71
|
-
toolIcon:
|
|
71
|
+
toolIcon: IconNode,
|
|
72
72
|
text: string | TemplateResult,
|
|
73
73
|
contentRef: Ref<HTMLElement>,
|
|
74
74
|
chevronRef: Ref<HTMLElement>,
|
|
75
75
|
defaultExpanded = false,
|
|
76
76
|
): TemplateResult {
|
|
77
|
-
const statusIcon = (iconComponent:
|
|
77
|
+
const statusIcon = (iconComponent: IconNode, color: string) =>
|
|
78
78
|
html`<span class="inline-block ${color}">${icon(iconComponent, "sm")}</span>`;
|
|
79
79
|
|
|
80
80
|
const toggleContent = (e: Event) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
1
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { SquareTerminal } from "lucide";
|
|
4
4
|
import { i18n } from "../../utils/i18n.js";
|
|
@@ -18,8 +18,8 @@ export class BashRenderer implements ToolRenderer<BashParams, undefined> {
|
|
|
18
18
|
if (result && params?.command) {
|
|
19
19
|
const output =
|
|
20
20
|
result.content
|
|
21
|
-
?.filter((c) => c.type === "text")
|
|
22
|
-
.map((c
|
|
21
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
22
|
+
.map((c) => c.text)
|
|
23
23
|
.join("\n") || "";
|
|
24
24
|
const combined = output ? `> ${params.command}\n\n${output}` : `> ${params.command}`;
|
|
25
25
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
1
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { Calculator } from "lucide";
|
|
4
4
|
import { i18n } from "../../utils/i18n.js";
|
|
@@ -18,8 +18,8 @@ export class CalculateRenderer implements ToolRenderer<CalculateParams, undefine
|
|
|
18
18
|
if (result && params?.expression) {
|
|
19
19
|
const output =
|
|
20
20
|
result.content
|
|
21
|
-
?.filter((c) => c.type === "text")
|
|
22
|
-
.map((c
|
|
21
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
22
|
+
.map((c) => c.text)
|
|
23
23
|
.join("\n") || "";
|
|
24
24
|
|
|
25
25
|
// Error: show expression in header, error below
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
1
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { Code } from "lucide";
|
|
4
4
|
import { i18n } from "../../utils/i18n.js";
|
|
@@ -6,14 +6,14 @@ import { renderHeader } from "../renderer-registry.js";
|
|
|
6
6
|
import type { ToolRenderer, ToolRenderResult } from "../types.js";
|
|
7
7
|
|
|
8
8
|
export class DefaultRenderer implements ToolRenderer {
|
|
9
|
-
render(params:
|
|
9
|
+
render(params: unknown | undefined, result: ToolResultMessage | undefined, isStreaming?: boolean): ToolRenderResult {
|
|
10
10
|
const state = result ? (result.isError ? "error" : "complete") : isStreaming ? "inprogress" : "complete";
|
|
11
11
|
|
|
12
12
|
// Format params as JSON
|
|
13
13
|
let paramsJson = "";
|
|
14
14
|
if (params) {
|
|
15
15
|
try {
|
|
16
|
-
paramsJson = JSON.stringify(JSON.parse(params), null, 2);
|
|
16
|
+
paramsJson = JSON.stringify(JSON.parse(params as string), null, 2);
|
|
17
17
|
} catch {
|
|
18
18
|
try {
|
|
19
19
|
paramsJson = JSON.stringify(params, null, 2);
|
|
@@ -27,8 +27,8 @@ export class DefaultRenderer implements ToolRenderer {
|
|
|
27
27
|
if (result) {
|
|
28
28
|
let outputJson =
|
|
29
29
|
result.content
|
|
30
|
-
?.filter((c) => c.type === "text")
|
|
31
|
-
.map((c
|
|
30
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
31
|
+
.map((c) => c.text)
|
|
32
32
|
.join("\n") || i18n("(no output)");
|
|
33
33
|
let outputLanguage = "text";
|
|
34
34
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultMessage } from "@elyracode/ai";
|
|
1
|
+
import type { TextContent, ToolResultMessage } from "@elyracode/ai";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { Clock } from "lucide";
|
|
4
4
|
import { i18n } from "../../utils/i18n.js";
|
|
@@ -21,8 +21,8 @@ export class GetCurrentTimeRenderer implements ToolRenderer<GetCurrentTimeParams
|
|
|
21
21
|
if (result && params) {
|
|
22
22
|
const output =
|
|
23
23
|
result.content
|
|
24
|
-
?.filter((c) => c.type === "text")
|
|
25
|
-
.map((c
|
|
24
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
25
|
+
.map((c) => c.text)
|
|
26
26
|
.join("\n") || "";
|
|
27
27
|
const headerText = params.timezone
|
|
28
28
|
? `${i18n("Getting current time in")} ${params.timezone}`
|
|
@@ -49,8 +49,8 @@ export class GetCurrentTimeRenderer implements ToolRenderer<GetCurrentTimeParams
|
|
|
49
49
|
if (result) {
|
|
50
50
|
const output =
|
|
51
51
|
result.content
|
|
52
|
-
?.filter((c) => c.type === "text")
|
|
53
|
-
.map((c
|
|
52
|
+
?.filter((c): c is TextContent => c.type === "text")
|
|
53
|
+
.map((c) => c.text)
|
|
54
54
|
.join("\n") || "";
|
|
55
55
|
|
|
56
56
|
// Error: show header, error below
|
package/src/tools/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface ToolRenderResult {
|
|
|
6
6
|
isCustom: boolean; // true = no card wrapper, false = wrap in card
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export interface ToolRenderer<TParams =
|
|
9
|
+
export interface ToolRenderer<TParams = unknown, TDetails = unknown> {
|
|
10
10
|
render(
|
|
11
11
|
params: TParams | undefined,
|
|
12
12
|
result: ToolResultMessage<TDetails> | undefined,
|
|
@@ -214,8 +214,8 @@ async function processPdf(
|
|
|
214
214
|
const page = await pdf.getPage(i);
|
|
215
215
|
const textContent = await page.getTextContent();
|
|
216
216
|
const pageText = textContent.items
|
|
217
|
-
.map((item
|
|
218
|
-
.filter((str
|
|
217
|
+
.map((item) => ("str" in item ? item.str : ""))
|
|
218
|
+
.filter((str) => str.trim())
|
|
219
219
|
.join(" ");
|
|
220
220
|
extractedText += `\n<page number="${i}">\n${pageText}\n</page>`;
|
|
221
221
|
}
|
|
@@ -298,7 +298,14 @@ async function processDocx(arrayBuffer: ArrayBuffer, fileName: string): Promise<
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
/** Structural shape of a docx-preview document tree node (the library types its tree as `any`). */
|
|
302
|
+
interface DocxElement {
|
|
303
|
+
type?: string;
|
|
304
|
+
text?: string;
|
|
305
|
+
children?: DocxElement[];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function extractTextFromElement(element: DocxElement): string {
|
|
302
309
|
let text = "";
|
|
303
310
|
|
|
304
311
|
// Check type with lowercase
|
package/src/utils/format.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Usage } from "@elyracode/ai";
|
|
1
|
+
import type { Api, Model, Usage } from "@elyracode/ai";
|
|
2
2
|
import { i18n } from "@elyracode/mini-lit";
|
|
3
3
|
|
|
4
4
|
export function formatCost(cost: number): string {
|
|
5
5
|
return `$${cost.toFixed(4)}`;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export function formatModelCost(cost:
|
|
8
|
+
export function formatModelCost(cost: Model<Api>["cost"] | undefined): string {
|
|
9
9
|
if (!cost) return i18n("Free");
|
|
10
10
|
const input = cost.input || 0;
|
|
11
11
|
const output = cost.output || 0;
|