@tylertech/forge-ai 0.15.2 → 0.15.3-dev.1
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/custom-elements.json +4501 -1781
- package/dist/ai-artifact-card/ai-artifact-card.d.ts +75 -0
- package/dist/ai-artifact-card/ai-artifact-card.mjs +142 -0
- package/dist/ai-artifact-card/ai-artifact-card.scss.mjs +283 -0
- package/dist/ai-artifact-card/index.d.ts +1 -0
- package/dist/ai-artifact-card/index.mjs +5 -0
- package/dist/ai-artifact-card-group/ai-artifact-card-group.d.ts +57 -0
- package/dist/ai-artifact-card-group/ai-artifact-card-group.mjs +137 -0
- package/dist/ai-artifact-card-group/ai-artifact-card-group.scss.mjs +173 -0
- package/dist/ai-artifact-card-group/index.d.ts +1 -0
- package/dist/ai-artifact-card-group/index.mjs +5 -0
- package/dist/ai-assistant-response/ai-assistant-response.d.ts +2 -2
- package/dist/ai-assistant-response/ai-assistant-response.mjs +26 -2
- package/dist/ai-canvas/ai-canvas.d.ts +43 -0
- package/dist/ai-canvas/ai-canvas.mjs +95 -0
- package/dist/ai-canvas/ai-canvas.scss.mjs +4 -0
- package/dist/ai-canvas/index.d.ts +1 -0
- package/dist/ai-canvas/index.mjs +5 -0
- package/dist/ai-chatbot/ag-ui-adapter.d.ts +2 -2
- package/dist/ai-chatbot/ag-ui-adapter.mjs +1 -1
- package/dist/ai-chatbot/agent-adapter.d.ts +111 -4
- package/dist/ai-chatbot/agent-adapter.mjs +22 -0
- package/dist/ai-chatbot/agent-runner.d.ts +2 -2
- package/dist/ai-chatbot/ai-chatbot-base.d.ts +29 -2
- package/dist/ai-chatbot/ai-chatbot-base.mjs +147 -3
- package/dist/ai-chatbot/ai-chatbot-tool-call.d.ts +2 -2
- package/dist/ai-chatbot/ai-chatbot-tool-call.mjs +88 -10
- package/dist/ai-chatbot/ai-chatbot.d.ts +24 -1
- package/dist/ai-chatbot/ai-chatbot.mjs +102 -2
- package/dist/ai-chatbot/ai-chatbot.scss.mjs +1 -1
- package/dist/ai-chatbot/create-tool-renderer.d.ts +5 -5
- package/dist/ai-chatbot/index.d.ts +3 -2
- package/dist/ai-chatbot/index.mjs +3 -0
- package/dist/ai-chatbot/message-state-controller.d.ts +10 -1
- package/dist/ai-chatbot/message-state-controller.mjs +78 -20
- package/dist/ai-chatbot/tool-canvas.d.ts +60 -0
- package/dist/ai-chatbot/tool-canvas.mjs +128 -0
- package/dist/ai-chatbot/types.d.ts +325 -15
- package/dist/ai-chatbot/utils.d.ts +8 -3
- package/dist/ai-chatbot/utils.mjs +7 -1
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +40 -2
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +224 -7
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.scss.mjs +1 -1
- package/dist/ai-embedded-chat/ai-embedded-chat.mjs +1 -0
- package/dist/ai-message-thread/ai-message-thread.d.ts +3 -2
- package/dist/ai-message-thread/ai-message-thread.mjs +36 -3
- package/dist/ai-steps/ai-steps.d.ts +67 -0
- package/dist/ai-steps/ai-steps.mjs +163 -0
- package/dist/ai-steps/ai-steps.scss.mjs +4 -0
- package/dist/ai-steps/index.d.ts +1 -0
- package/dist/ai-steps/index.mjs +5 -0
- package/dist/ai-tool-call-indicator/ai-tool-call-indicator.d.ts +2 -2
- package/dist/ai-tool-call-indicator/ai-tool-call-indicator.mjs +1 -1
- package/dist/core/canvas-controller.d.ts +81 -0
- package/dist/core/canvas-controller.mjs +221 -0
- package/dist/core/chatbot-core-controller.d.ts +4 -2
- package/dist/core/chatbot-core-controller.mjs +121 -4
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.mjs +2 -0
- package/dist/core/resize-controller.d.ts +5 -0
- package/dist/core/resize-controller.mjs +7 -5
- package/dist/index.d.ts +4 -0
- package/dist/index.mjs +15 -0
- package/dist/tools/ai-data-table/ai-data-table-definition.mjs +1 -0
- package/dist/tools/ai-mcp-app/ai-mcp-app.d.ts +70 -0
- package/dist/tools/ai-mcp-app/ai-mcp-app.mjs +589 -0
- package/dist/tools/ai-mcp-app/ai-mcp-app.scss.mjs +4 -0
- package/dist/tools/ai-mcp-app/index.d.ts +3 -0
- package/dist/tools/ai-mcp-app/index.mjs +6 -0
- package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.d.ts +60 -0
- package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.mjs +147 -0
- package/dist/tools/ai-mcp-app/mcp-app-bridge-types.d.ts +124 -0
- package/dist/tools/ai-mcp-app/mcp-app-bridge.d.ts +41 -0
- package/dist/tools/ai-mcp-app/mcp-app-bridge.mjs +293 -0
- package/dist/tools/ai-mcp-app/mcp-app-context.d.ts +46 -0
- package/dist/tools/ai-mcp-app/mcp-app-context.mjs +5 -0
- package/dist/tools/ai-steps/ai-steps-definition.d.ts +2 -0
- package/dist/tools/ai-steps/ai-steps-definition.mjs +51 -0
- package/dist/tools/ai-steps/ai-steps.d.ts +28 -0
- package/dist/tools/ai-steps/ai-steps.mjs +49 -0
- package/dist/tools/ai-steps/ai-steps.scss.mjs +4 -0
- package/dist/tools/ai-steps/index.d.ts +2 -0
- package/dist/tools/ai-steps/index.mjs +6 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.mjs +5 -1
- package/dist/utils/inert-outside.d.ts +7 -0
- package/dist/utils/inert-outside.mjs +28 -0
- package/package.json +4 -1
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { generateId } from "./utils.mjs";
|
|
2
|
+
function withoutMcpAppResource(toolCall) {
|
|
3
|
+
if (!toolCall.uiResource && !toolCall.uiResourceStatus) {
|
|
4
|
+
return toolCall;
|
|
5
|
+
}
|
|
6
|
+
const { uiResource: _uiResource, uiResourceStatus: _uiResourceStatus, ...rest } = toolCall;
|
|
7
|
+
return rest;
|
|
8
|
+
}
|
|
9
|
+
function responseItemWithoutMcpAppResource(item) {
|
|
10
|
+
return item.type === "toolCall" ? { type: "toolCall", data: withoutMcpAppResource(item.data) } : item;
|
|
11
|
+
}
|
|
2
12
|
class MessageStateController {
|
|
3
13
|
constructor(_host, _config) {
|
|
4
14
|
this._host = _host;
|
|
@@ -103,33 +113,61 @@ class MessageStateController {
|
|
|
103
113
|
this.#updateResponseInItems();
|
|
104
114
|
this.#notifyStateChange();
|
|
105
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Applies `updates` to a tool call wherever it is rendered: the in-progress response,
|
|
118
|
+
* an already finalized/restored response, or a top-level tool-call item.
|
|
119
|
+
*/
|
|
106
120
|
updateToolCallInResponse(toolCallId, updates) {
|
|
107
121
|
const toolCall = this._toolCalls.get(toolCallId);
|
|
108
122
|
if (!toolCall) {
|
|
109
123
|
return;
|
|
110
124
|
}
|
|
111
|
-
const
|
|
125
|
+
const isFinishing = updates.status === "complete" || updates.status === "error" || updates.status === "cancelled";
|
|
112
126
|
const updated = {
|
|
113
127
|
...toolCall,
|
|
114
128
|
...updates,
|
|
115
|
-
...
|
|
129
|
+
...isFinishing && !toolCall.endTimestamp ? { endTimestamp: Date.now() } : {}
|
|
116
130
|
};
|
|
117
131
|
this._toolCalls.set(toolCallId, updated);
|
|
118
|
-
|
|
119
|
-
for (const child of this._activeResponse.children) {
|
|
120
|
-
if (child.type === "toolCall" && child.data.id === toolCallId) {
|
|
121
|
-
child.data = updated;
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
this.#updateResponseInItems();
|
|
132
|
+
this.#replaceToolCall(updated);
|
|
127
133
|
this.#notifyStateChange();
|
|
128
134
|
}
|
|
129
135
|
completeToolCallInResponse(toolCallId, result, event) {
|
|
130
136
|
this.updateToolCallInResponse(toolCallId, {
|
|
131
137
|
result,
|
|
132
|
-
status: event
|
|
138
|
+
status: this.#resultStatus(event),
|
|
139
|
+
...event ? {
|
|
140
|
+
structuredContent: event.structuredContent,
|
|
141
|
+
structuredContentOmitted: event.structuredContentOmitted,
|
|
142
|
+
mcpResult: event.mcpResult,
|
|
143
|
+
mcpResultOmitted: event.mcpResultOmitted
|
|
144
|
+
} : {}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
#resultStatus(event) {
|
|
148
|
+
if (event?.cancelled) {
|
|
149
|
+
return "cancelled";
|
|
150
|
+
}
|
|
151
|
+
return event?.isError ? "error" : "complete";
|
|
152
|
+
}
|
|
153
|
+
#replaceToolCall(updated) {
|
|
154
|
+
const matches = (child) => child.type === "toolCall" && child.data.id === updated.id;
|
|
155
|
+
const replace = (children) => children.map((child) => matches(child) ? { type: "toolCall", data: updated } : child);
|
|
156
|
+
const activeResponse = this._activeResponse;
|
|
157
|
+
if (activeResponse?.children.some(matches)) {
|
|
158
|
+
activeResponse.children = replace(activeResponse.children);
|
|
159
|
+
}
|
|
160
|
+
this._messageItems = this._messageItems.map((item) => {
|
|
161
|
+
if (item.type === "toolCall" && item.data.id === updated.id) {
|
|
162
|
+
return { type: "toolCall", data: updated };
|
|
163
|
+
}
|
|
164
|
+
if (item.type !== "assistant" || !item.data.children.some(matches)) {
|
|
165
|
+
return item;
|
|
166
|
+
}
|
|
167
|
+
if (item.data.id === activeResponse?.id) {
|
|
168
|
+
return { type: "assistant", data: { ...activeResponse } };
|
|
169
|
+
}
|
|
170
|
+
return { type: "assistant", data: { ...item.data, children: replace(item.data.children) } };
|
|
133
171
|
});
|
|
134
172
|
}
|
|
135
173
|
tryFinalizeResponse() {
|
|
@@ -242,14 +280,32 @@ class MessageStateController {
|
|
|
242
280
|
this.#notifyStateChange();
|
|
243
281
|
this._config.onThreadSettled?.();
|
|
244
282
|
}
|
|
283
|
+
/** Tool call ids rendered at or after `index`, inside assistant responses or as top-level items. */
|
|
284
|
+
getToolCallIdsFrom(index) {
|
|
285
|
+
return this._messageItems.slice(index).flatMap((item) => {
|
|
286
|
+
if (item.type === "toolCall") {
|
|
287
|
+
return [item.data.id];
|
|
288
|
+
}
|
|
289
|
+
if (item.type === "assistant") {
|
|
290
|
+
return item.data.children.flatMap((child) => child.type === "toolCall" ? [child.data.id] : []);
|
|
291
|
+
}
|
|
292
|
+
return [];
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/** Removes items from `index` onward and returns the ids of the tool calls they held. */
|
|
245
296
|
removeMessageItemsFrom(index) {
|
|
297
|
+
const removedToolCallIds = this.getToolCallIdsFrom(index);
|
|
298
|
+
removedToolCallIds.forEach((id) => this._toolCalls.delete(id));
|
|
246
299
|
this._messageItems = this._messageItems.slice(0, index);
|
|
247
300
|
this._activeResponse = null;
|
|
248
301
|
this.#notifyStateChange();
|
|
302
|
+
return removedToolCallIds;
|
|
249
303
|
}
|
|
250
304
|
/**
|
|
251
305
|
* Reconstructs the message hierarchy for API compatibility.
|
|
252
306
|
* Converts assistant responses back to ChatMessage format with tool calls.
|
|
307
|
+
* MCP-app `uiResource`/`uiResourceStatus` are stripped: resources are re-resolved via the
|
|
308
|
+
* adapter on restore, never persisted or sent back to the agent.
|
|
253
309
|
*/
|
|
254
310
|
getMessages() {
|
|
255
311
|
const messages = [];
|
|
@@ -258,8 +314,9 @@ class MessageStateController {
|
|
|
258
314
|
messages.push({ ...item.data, toolCalls: [] });
|
|
259
315
|
} else if (item.type === "assistant") {
|
|
260
316
|
const response = item.data;
|
|
261
|
-
const
|
|
262
|
-
const
|
|
317
|
+
const children = response.children.map(responseItemWithoutMcpAppResource);
|
|
318
|
+
const textContent = children.filter((c) => c.type === "text").map((c) => c.content).join("");
|
|
319
|
+
const toolCalls = children.filter((c) => c.type === "toolCall").map((c) => c.data);
|
|
263
320
|
const message = {
|
|
264
321
|
id: response.id,
|
|
265
322
|
role: "assistant",
|
|
@@ -268,13 +325,13 @@ class MessageStateController {
|
|
|
268
325
|
status: response.status === "streaming" ? "streaming" : response.status === "error" ? "error" : "complete",
|
|
269
326
|
toolCalls: toolCalls.length ? toolCalls : void 0,
|
|
270
327
|
feedback: response.feedback,
|
|
271
|
-
children
|
|
328
|
+
children
|
|
272
329
|
};
|
|
273
330
|
messages.push(message);
|
|
274
331
|
} else if (item.type === "toolCall") {
|
|
275
332
|
const lastMsg = messages[messages.length - 1];
|
|
276
333
|
if (lastMsg && lastMsg.role === "assistant") {
|
|
277
|
-
lastMsg.toolCalls = [...lastMsg.toolCalls || [], item.data];
|
|
334
|
+
lastMsg.toolCalls = [...lastMsg.toolCalls || [], withoutMcpAppResource(item.data)];
|
|
278
335
|
}
|
|
279
336
|
}
|
|
280
337
|
}
|
|
@@ -289,10 +346,11 @@ class MessageStateController {
|
|
|
289
346
|
let children;
|
|
290
347
|
if (msg.children?.length) {
|
|
291
348
|
children = msg.children.map((child) => {
|
|
292
|
-
|
|
293
|
-
|
|
349
|
+
const restored = responseItemWithoutMcpAppResource(child);
|
|
350
|
+
if (restored.type === "toolCall") {
|
|
351
|
+
this._toolCalls.set(restored.data.id, restored.data);
|
|
294
352
|
}
|
|
295
|
-
return
|
|
353
|
+
return restored;
|
|
296
354
|
});
|
|
297
355
|
} else {
|
|
298
356
|
children = [];
|
|
@@ -300,7 +358,7 @@ class MessageStateController {
|
|
|
300
358
|
children.push({ type: "text", messageId: msg.id, content: msg.content, status: "complete" });
|
|
301
359
|
}
|
|
302
360
|
if (msg.toolCalls) {
|
|
303
|
-
for (const toolCall of msg.toolCalls) {
|
|
361
|
+
for (const toolCall of msg.toolCalls.map(withoutMcpAppResource)) {
|
|
304
362
|
children.push({ type: "toolCall", data: toolCall });
|
|
305
363
|
this._toolCalls.set(toolCall.id, toolCall);
|
|
306
364
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ToolCall, ToolCanvas, ToolCanvasInline, AnyToolDefinition, ToolPresentation } from './types.js';
|
|
2
|
+
export interface ForgeAiCanvasOpenRequestEventData {
|
|
3
|
+
toolCallId: string;
|
|
4
|
+
toolName: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
/** Set to true by the host once the tool call is showing in the canvas. */
|
|
7
|
+
handled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ForgeAiCanvasCloseRequestEventData {
|
|
10
|
+
toolCallId: string;
|
|
11
|
+
/** Set to true by the host once the canvas has closed. */
|
|
12
|
+
handled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare global {
|
|
15
|
+
interface HTMLElementEventMap {
|
|
16
|
+
'forge-ai-canvas-open-request': CustomEvent<ForgeAiCanvasOpenRequestEventData>;
|
|
17
|
+
'forge-ai-canvas-close-request': CustomEvent<ForgeAiCanvasCloseRequestEventData>;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** State a canvas host shares with the tool calls rendered in its thread. */
|
|
21
|
+
export interface ToolCanvasHostState {
|
|
22
|
+
/** Presentation assigned to inline renderers of canvas-enabled tools. */
|
|
23
|
+
presentation: ToolPresentation;
|
|
24
|
+
/** Tool call currently shown in the canvas, if any. */
|
|
25
|
+
openToolCallId?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Provided by hosts that render tool calls next to a canvas panel. Without a provider, inline
|
|
29
|
+
* renderers get `inline`.
|
|
30
|
+
*/
|
|
31
|
+
export declare const toolCanvasHostContext: {
|
|
32
|
+
__context__: ToolCanvasHostState;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Asks the nearest canvas host to show the given tool call. Hosts without a canvas leave the event
|
|
36
|
+
* unhandled. Returns whether the tool call is now showing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function requestCanvasOpen(target: EventTarget, detail: ForgeAiCanvasOpenRequestEventData): boolean;
|
|
39
|
+
/** Asks the nearest canvas host to close the canvas if it is showing the given tool call. Returns whether it closed. */
|
|
40
|
+
export declare function requestCanvasClose(target: EventTarget, detail: ForgeAiCanvasCloseRequestEventData): boolean;
|
|
41
|
+
export interface CreateToolCanvasConfig {
|
|
42
|
+
available: boolean;
|
|
43
|
+
/** Read live by `toggle()`; `isOpen` on the result is a snapshot taken when the controls are built. */
|
|
44
|
+
isOpen: () => boolean;
|
|
45
|
+
open: (options?: {
|
|
46
|
+
title?: string;
|
|
47
|
+
}) => boolean;
|
|
48
|
+
close: () => boolean;
|
|
49
|
+
}
|
|
50
|
+
/** Builds the `canvas` controls a host injects into a tool renderer. */
|
|
51
|
+
export declare function createToolCanvas({ available, isOpen, open, close }: CreateToolCanvasConfig): ToolCanvas;
|
|
52
|
+
export declare function resolveToolCanvasTitle(toolCall: ToolCall, toolDefinition: AnyToolDefinition): string;
|
|
53
|
+
export declare function resolveToolCanvasSubtitle(toolCall: ToolCall, toolDefinition: AnyToolDefinition): string | undefined;
|
|
54
|
+
export declare function resolveToolCanvasActionLabel(toolCall: ToolCall, toolDefinition: AnyToolDefinition, active: boolean): string;
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the artifact card icon to a fresh `<svg>` element, or undefined for the card's default glyph.
|
|
57
|
+
* Markup strings are parsed and reduced to an allowlist of shape elements and presentation attributes.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveToolCanvasIcon(toolCall: ToolCall, toolDefinition: AnyToolDefinition): SVGElement | undefined;
|
|
60
|
+
export declare function resolveToolCanvasInline(toolDefinition: AnyToolDefinition): ToolCanvasInline;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createContext } from "@lit/context";
|
|
2
|
+
const toolCanvasHostContext = createContext(/* @__PURE__ */ Symbol("forge-ai-tool-canvas-host"));
|
|
3
|
+
function requestCanvasOpen(target, detail) {
|
|
4
|
+
const request = { ...detail, handled: false };
|
|
5
|
+
target.dispatchEvent(
|
|
6
|
+
new CustomEvent("forge-ai-canvas-open-request", {
|
|
7
|
+
detail: request,
|
|
8
|
+
bubbles: true,
|
|
9
|
+
composed: true
|
|
10
|
+
})
|
|
11
|
+
);
|
|
12
|
+
return request.handled;
|
|
13
|
+
}
|
|
14
|
+
function requestCanvasClose(target, detail) {
|
|
15
|
+
const request = { ...detail, handled: false };
|
|
16
|
+
target.dispatchEvent(
|
|
17
|
+
new CustomEvent("forge-ai-canvas-close-request", {
|
|
18
|
+
detail: request,
|
|
19
|
+
bubbles: true,
|
|
20
|
+
composed: true
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
return request.handled;
|
|
24
|
+
}
|
|
25
|
+
function createToolCanvas({ available, isOpen, open, close }) {
|
|
26
|
+
return {
|
|
27
|
+
available,
|
|
28
|
+
isOpen: isOpen(),
|
|
29
|
+
open: (options) => available && open(options),
|
|
30
|
+
close: () => available && close(),
|
|
31
|
+
toggle: () => available && (isOpen() ? close() : open())
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const DEFAULT_ACTION_LABEL = { open: "Open in canvas", collapse: "Collapse canvas" };
|
|
35
|
+
function resolveToolCallValue(value, toolCall) {
|
|
36
|
+
if (typeof value === "function") {
|
|
37
|
+
return value(toolCall);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function resolveToolCanvasTitle(toolCall, toolDefinition) {
|
|
42
|
+
return resolveToolCallValue(toolDefinition.canvas?.title, toolCall) ?? toolDefinition.displayName ?? toolDefinition.name;
|
|
43
|
+
}
|
|
44
|
+
function resolveToolCanvasSubtitle(toolCall, toolDefinition) {
|
|
45
|
+
return resolveToolCallValue(toolDefinition.canvas?.subtitle, toolCall);
|
|
46
|
+
}
|
|
47
|
+
function resolveToolCanvasActionLabel(toolCall, toolDefinition, active) {
|
|
48
|
+
const labels = resolveToolCallValue(toolDefinition.canvas?.actionLabel, toolCall) ?? DEFAULT_ACTION_LABEL;
|
|
49
|
+
return active ? labels.collapse : labels.open;
|
|
50
|
+
}
|
|
51
|
+
function resolveToolCanvasIcon(toolCall, toolDefinition) {
|
|
52
|
+
const icon = resolveToolCallValue(toolDefinition.canvas?.icon, toolCall);
|
|
53
|
+
if (!icon) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
if (typeof icon !== "string") {
|
|
57
|
+
return icon.cloneNode(true);
|
|
58
|
+
}
|
|
59
|
+
const template = document.createElement("template");
|
|
60
|
+
template.innerHTML = icon;
|
|
61
|
+
const svg = template.content.querySelector("svg");
|
|
62
|
+
if (!svg) {
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
sanitizeSvg(svg);
|
|
66
|
+
return svg;
|
|
67
|
+
}
|
|
68
|
+
const SVG_ICON_ELEMENTS = /* @__PURE__ */ new Set(["svg", "g", "path", "circle", "ellipse", "rect", "line", "polyline", "polygon"]);
|
|
69
|
+
const SVG_ICON_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
70
|
+
"xmlns",
|
|
71
|
+
"viewBox",
|
|
72
|
+
"width",
|
|
73
|
+
"height",
|
|
74
|
+
"d",
|
|
75
|
+
"fill",
|
|
76
|
+
"fill-rule",
|
|
77
|
+
"clip-rule",
|
|
78
|
+
"stroke",
|
|
79
|
+
"stroke-width",
|
|
80
|
+
"stroke-linecap",
|
|
81
|
+
"stroke-linejoin",
|
|
82
|
+
"opacity",
|
|
83
|
+
"transform",
|
|
84
|
+
"cx",
|
|
85
|
+
"cy",
|
|
86
|
+
"r",
|
|
87
|
+
"rx",
|
|
88
|
+
"ry",
|
|
89
|
+
"x",
|
|
90
|
+
"y",
|
|
91
|
+
"x1",
|
|
92
|
+
"y1",
|
|
93
|
+
"x2",
|
|
94
|
+
"y2",
|
|
95
|
+
"points",
|
|
96
|
+
"aria-hidden"
|
|
97
|
+
]);
|
|
98
|
+
function sanitizeSvg(svg) {
|
|
99
|
+
for (const element of [svg, ...svg.querySelectorAll("*")]) {
|
|
100
|
+
if (!SVG_ICON_ELEMENTS.has(element.localName)) {
|
|
101
|
+
element.remove();
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
for (const attribute of [...element.attributes]) {
|
|
105
|
+
if (!SVG_ICON_ATTRIBUTES.has(attribute.name)) {
|
|
106
|
+
element.removeAttribute(attribute.name);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function resolveToolCanvasInline(toolDefinition) {
|
|
112
|
+
const canvas = toolDefinition.canvas;
|
|
113
|
+
if (canvas?.inline) {
|
|
114
|
+
return canvas.inline;
|
|
115
|
+
}
|
|
116
|
+
return canvas?.open === "auto" ? "card" : "renderer";
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
createToolCanvas,
|
|
120
|
+
requestCanvasClose,
|
|
121
|
+
requestCanvasOpen,
|
|
122
|
+
resolveToolCanvasActionLabel,
|
|
123
|
+
resolveToolCanvasIcon,
|
|
124
|
+
resolveToolCanvasInline,
|
|
125
|
+
resolveToolCanvasSubtitle,
|
|
126
|
+
resolveToolCanvasTitle,
|
|
127
|
+
toolCanvasHostContext
|
|
128
|
+
};
|