@tylertech/forge-ai 0.15.3-dev.0 → 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 +7733 -6803
- package/dist/ai-assistant-response/ai-assistant-response.d.ts +2 -2
- package/dist/ai-assistant-response/ai-assistant-response.mjs +4 -3
- 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/agent-adapter.d.ts +5 -5
- package/dist/ai-chatbot/agent-runner.d.ts +2 -2
- package/dist/ai-chatbot/ai-chatbot-base.d.ts +3 -2
- package/dist/ai-chatbot/ai-chatbot-base.mjs +11 -0
- 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 +2 -1
- package/dist/ai-chatbot/index.mjs +3 -0
- package/dist/ai-chatbot/message-state-controller.d.ts +2 -2
- package/dist/ai-chatbot/message-state-controller.mjs +11 -11
- 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 +128 -16
- package/dist/ai-chatbot/utils.d.ts +8 -3
- package/dist/ai-chatbot/utils.mjs +4 -0
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +40 -2
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +224 -5
- 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 +2 -2
- package/dist/ai-message-thread/ai-message-thread.mjs +3 -2
- package/dist/ai-tool-call-indicator/ai-tool-call-indicator.d.ts +2 -2
- 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 +2 -2
- package/dist/core/chatbot-core-controller.mjs +44 -22
- 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 +1 -0
- package/dist/index.mjs +6 -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 +2 -1
- package/dist/tools/ai-mcp-app/ai-mcp-app.mjs +16 -1
- package/dist/tools/ai-mcp-app/ai-mcp-app.scss.mjs +1 -1
- package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.d.ts +3 -4
- package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.mjs +12 -21
- package/dist/tools/ai-mcp-app/mcp-app-bridge-types.d.ts +2 -1
- package/dist/tools/ai-steps/ai-steps-definition.mjs +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, TemplateResult, CSSResult } from 'lit';
|
|
2
|
-
import { AssistantResponse,
|
|
2
|
+
import { AssistantResponse, AnyToolDefinition } from '../ai-chatbot/types.js';
|
|
3
3
|
declare global {
|
|
4
4
|
interface HTMLElementTagNameMap {
|
|
5
5
|
'forge-ai-assistant-response': AiAssistantResponseComponent;
|
|
@@ -34,7 +34,7 @@ export declare class AiAssistantResponseComponent extends LitElement {
|
|
|
34
34
|
#private;
|
|
35
35
|
static styles: CSSResult;
|
|
36
36
|
response: AssistantResponse;
|
|
37
|
-
tools?: Map<string,
|
|
37
|
+
tools?: Map<string, AnyToolDefinition>;
|
|
38
38
|
enableReactions: boolean;
|
|
39
39
|
debugMode: boolean;
|
|
40
40
|
showThinking: boolean;
|
|
@@ -4,6 +4,7 @@ import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
|
4
4
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
5
5
|
import { keyed } from "lit/directives/keyed.js";
|
|
6
6
|
import { MarkdownStreamController } from "../ai-chatbot/markdown-stream-controller.mjs";
|
|
7
|
+
import { rendersAsMcpAppWidget } from "../ai-chatbot/utils.mjs";
|
|
7
8
|
import "../ai-response-message-toolbar/ai-response-message-toolbar.mjs";
|
|
8
9
|
import "../ai-chatbot/ai-chatbot-tool-call.mjs";
|
|
9
10
|
import "../ai-tool-call-indicator/ai-tool-call-indicator.mjs";
|
|
@@ -84,10 +85,10 @@ renderTextChunk_fn = function(child) {
|
|
|
84
85
|
return html`<div class="text-chunk">${unsafeHTML(renderedHtml)}</div>`;
|
|
85
86
|
};
|
|
86
87
|
isMcpAppToolCall_fn = function(toolCall) {
|
|
87
|
-
return
|
|
88
|
+
return rendersAsMcpAppWidget(toolCall) || this.tools?.get(toolCall.name)?.mcpApp !== void 0;
|
|
88
89
|
};
|
|
89
90
|
renderToolCall_fn = function(toolCall) {
|
|
90
|
-
if (toolCall
|
|
91
|
+
if (rendersAsMcpAppWidget(toolCall)) {
|
|
91
92
|
return keyed(
|
|
92
93
|
toolCall.id,
|
|
93
94
|
html`<forge-ai-mcp-app
|
|
@@ -199,7 +200,7 @@ thinkingIndicator_get = function() {
|
|
|
199
200
|
}
|
|
200
201
|
const isUnsettled = child.data.status === "parsing" || child.data.status === "executing" || child.data.status === "pending";
|
|
201
202
|
if (__privateMethod(this, _AiAssistantResponseComponent_instances, isMcpAppToolCall_fn).call(this, child.data)) {
|
|
202
|
-
return
|
|
203
|
+
return rendersAsMcpAppWidget(child.data) && isUnsettled;
|
|
203
204
|
}
|
|
204
205
|
return isUnsettled;
|
|
205
206
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LitElement, TemplateResult, CSSResult } from 'lit';
|
|
2
|
+
import { HeadingLevel } from '../ai-chatbot/types.js';
|
|
3
|
+
declare global {
|
|
4
|
+
interface HTMLElementTagNameMap {
|
|
5
|
+
'forge-ai-canvas': AiCanvasComponent;
|
|
6
|
+
}
|
|
7
|
+
interface HTMLElementEventMap {
|
|
8
|
+
'forge-ai-canvas-close': CustomEvent<void>;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export declare const AiCanvasComponentTagName: keyof HTMLElementTagNameMap;
|
|
12
|
+
/**
|
|
13
|
+
* @tag forge-ai-canvas
|
|
14
|
+
*
|
|
15
|
+
* @summary A side panel that presents an artifact next to a conversation.
|
|
16
|
+
*
|
|
17
|
+
* @description
|
|
18
|
+
* Presentational panel with a titled header, an actions area, a close button, and a scrollable body.
|
|
19
|
+
* Form factors such as `forge-ai-chatbot-launcher` own the open/close state and layout; this component
|
|
20
|
+
* only renders the panel chrome and reports close requests.
|
|
21
|
+
*
|
|
22
|
+
* @slot title - Replaces the default title heading
|
|
23
|
+
* @slot actions - Action buttons rendered before the close button
|
|
24
|
+
* @slot - Panel body content
|
|
25
|
+
*
|
|
26
|
+
* @property {string} titleText - Title shown in the panel header. Also names the panel region for assistive technology, including when the `title` slot replaces the heading
|
|
27
|
+
* @property {HeadingLevel} headingLevel - Heading level applied to the default title (default: 2)
|
|
28
|
+
* @property {string} closeLabel - Accessible label and tooltip for the close button (default: 'Close canvas')
|
|
29
|
+
*
|
|
30
|
+
* @cssproperty --forge-ai-canvas-body-padding - Padding around the body content
|
|
31
|
+
* @cssproperty --forge-ai-canvas-border-inline-start - Border on the panel's leading edge (default: 1px solid outline)
|
|
32
|
+
*
|
|
33
|
+
* @event {CustomEvent<void>} forge-ai-canvas-close - Fired when the close button is clicked
|
|
34
|
+
*/
|
|
35
|
+
export declare class AiCanvasComponent extends LitElement {
|
|
36
|
+
#private;
|
|
37
|
+
static styles: CSSResult;
|
|
38
|
+
titleText: string;
|
|
39
|
+
headingLevel: HeadingLevel;
|
|
40
|
+
closeLabel: string;
|
|
41
|
+
focus(): void;
|
|
42
|
+
render(): TemplateResult;
|
|
43
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, html } from "lit";
|
|
2
|
+
import { property, customElement } from "lit/decorators.js";
|
|
3
|
+
import { unsafeStatic, html as html$1 } from "lit/static-html.js";
|
|
4
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
5
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
6
|
+
import "../core/tooltip/tooltip.mjs";
|
|
7
|
+
import styles from "./ai-canvas.scss.mjs";
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __typeError = (msg) => {
|
|
11
|
+
throw TypeError(msg);
|
|
12
|
+
};
|
|
13
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
14
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
15
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
16
|
+
if (decorator = decorators[i])
|
|
17
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
18
|
+
if (kind && result) __defProp(target, key, result);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
22
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
23
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
24
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
25
|
+
var _closeButtonRef, _AiCanvasComponent_instances, handleCloseClick_fn, heading_get;
|
|
26
|
+
const AiCanvasComponentTagName = "forge-ai-canvas";
|
|
27
|
+
let AiCanvasComponent = class extends LitElement {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
__privateAdd(this, _AiCanvasComponent_instances);
|
|
31
|
+
this.titleText = "";
|
|
32
|
+
this.headingLevel = 2;
|
|
33
|
+
this.closeLabel = "Close canvas";
|
|
34
|
+
__privateAdd(this, _closeButtonRef, createRef());
|
|
35
|
+
}
|
|
36
|
+
focus() {
|
|
37
|
+
__privateGet(this, _closeButtonRef).value?.focus();
|
|
38
|
+
}
|
|
39
|
+
render() {
|
|
40
|
+
return html`
|
|
41
|
+
<div class="canvas" role="region" aria-label=${ifDefined(this.titleText || void 0)}>
|
|
42
|
+
<div class="header">
|
|
43
|
+
<div class="header-start">
|
|
44
|
+
<slot name="title">${__privateGet(this, _AiCanvasComponent_instances, heading_get)}</slot>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="header-end">
|
|
47
|
+
<slot name="actions"></slot>
|
|
48
|
+
<button
|
|
49
|
+
${ref(__privateGet(this, _closeButtonRef))}
|
|
50
|
+
id="close-button"
|
|
51
|
+
type="button"
|
|
52
|
+
class="forge-icon-button forge-icon-button--medium close-button"
|
|
53
|
+
aria-label=${this.closeLabel}
|
|
54
|
+
@click=${__privateMethod(this, _AiCanvasComponent_instances, handleCloseClick_fn)}>
|
|
55
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
|
|
56
|
+
<path
|
|
57
|
+
d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
|
|
58
|
+
</svg>
|
|
59
|
+
</button>
|
|
60
|
+
<forge-ai-tooltip for="close-button" placement="bottom">${this.closeLabel}</forge-ai-tooltip>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="body">
|
|
64
|
+
<slot></slot>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
_closeButtonRef = /* @__PURE__ */ new WeakMap();
|
|
71
|
+
_AiCanvasComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
72
|
+
handleCloseClick_fn = function() {
|
|
73
|
+
this.dispatchEvent(new CustomEvent("forge-ai-canvas-close", { bubbles: true, composed: true }));
|
|
74
|
+
};
|
|
75
|
+
heading_get = function() {
|
|
76
|
+
const tagName = unsafeStatic(`h${this.headingLevel}`);
|
|
77
|
+
return html$1`<${tagName} class="title">${this.titleText}</${tagName}>`;
|
|
78
|
+
};
|
|
79
|
+
AiCanvasComponent.styles = unsafeCSS(styles);
|
|
80
|
+
__decorateClass([
|
|
81
|
+
property({ attribute: "title-text" })
|
|
82
|
+
], AiCanvasComponent.prototype, "titleText", 2);
|
|
83
|
+
__decorateClass([
|
|
84
|
+
property({ type: Number, attribute: "heading-level" })
|
|
85
|
+
], AiCanvasComponent.prototype, "headingLevel", 2);
|
|
86
|
+
__decorateClass([
|
|
87
|
+
property({ attribute: "close-label" })
|
|
88
|
+
], AiCanvasComponent.prototype, "closeLabel", 2);
|
|
89
|
+
AiCanvasComponent = __decorateClass([
|
|
90
|
+
customElement(AiCanvasComponentTagName)
|
|
91
|
+
], AiCanvasComponent);
|
|
92
|
+
export {
|
|
93
|
+
AiCanvasComponent,
|
|
94
|
+
AiCanvasComponentTagName
|
|
95
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const styles = '/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n.forge-icon-button {\n --_icon-button-display:var(--forge-icon-button-display, inline-flex);\n --_icon-button-size:var(--forge-icon-button-size, 48px);\n --_icon-button-gap:var(--forge-icon-button-gap, 0);\n --_icon-button-icon-color:var(--forge-icon-button-icon-color, currentColor);\n --_icon-button-background-color:var(--forge-icon-button-background-color, none);\n --_icon-button-icon-size:var(--forge-icon-button-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n --_icon-button-cursor:var(--forge-icon-button-cursor, pointer);\n --_icon-button-padding:var(--forge-icon-button-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-border:var(--forge-icon-button-border, none);\n --_icon-button-shadow:var(--forge-icon-button-shadow, none);\n --_icon-button-transition-duration:var(--forge-icon-button-transition-duration, var(--forge-animation-duration-short3, 150ms));\n --_icon-button-transition-timing:var(--forge-icon-button-transition-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_icon-button-shape:var(--forge-icon-button-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_icon-button-shape-start-start:var(--forge-icon-button-shape-start-start, var(--_icon-button-shape));\n --_icon-button-shape-start-end:var(--forge-icon-button-shape-start-end, var(--_icon-button-shape));\n --_icon-button-shape-end-start:var(--forge-icon-button-shape-end-start, var(--_icon-button-shape));\n --_icon-button-shape-end-end:var(--forge-icon-button-shape-end-end, var(--_icon-button-shape));\n --_icon-button-shape-squared:var(--forge-icon-button-shape-squared, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_icon-button-outlined-border-width:var(--forge-icon-button-outlined-border-width, 1px);\n --_icon-button-outlined-border-style:var(--forge-icon-button-outlined-border-style, solid);\n --_icon-button-outlined-border-color:var(--forge-icon-button-outlined-border-color, var(--_icon-button-icon-color));\n --_icon-button-tonal-icon-color:var(--forge-icon-button-tonal-icon-color, var(--forge-theme-on-primary-container, #222c62));\n --_icon-button-tonal-background-color:var(--forge-icon-button-tonal-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-filled-icon-color:var(--forge-icon-button-filled-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-filled-background-color:var(--forge-icon-button-filled-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-raised-shadow:var(--forge-icon-button-raised-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-hover-shadow:var(--forge-icon-button-raised-hover-shadow, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-active-shadow:var(--forge-icon-button-raised-active-shadow, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-disabled-shadow:var(--forge-icon-button-raised-disabled-shadow, none);\n --_icon-button-density-small-size:var(--forge-icon-button-density-small-size, 24px);\n --_icon-button-density-small-padding:var(--forge-icon-button-density-small-padding, var(--forge-spacing-xxxsmall, 2px));\n --_icon-button-density-small-icon-size:var(--forge-icon-button-density-small-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.125));\n --_icon-button-density-medium-size:var(--forge-icon-button-density-medium-size, 36px);\n --_icon-button-density-medium-padding:var(--forge-icon-button-density-medium-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-density-large-size:var(--forge-icon-button-density-large-size, var(--_icon-button-size));\n --_icon-button-toggle-on-background-color:var(--forge-icon-button-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-toggle-on-icon-color:var(--forge-icon-button-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-outlined-toggle-on-background-color:var(--forge-icon-button-outlined-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-outlined-toggle-on-icon-color:var(--forge-icon-button-outlined-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-tonal-toggle-background-color:var(--forge-icon-button-tonal-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-tonal-toggle-on-background-color:var(--forge-icon-button-tonal-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-tonal-toggle-on-icon-color:var(--forge-icon-button-tonal-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-background-color:var(--forge-icon-button-filled-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-filled-toggle-icon-color:var(--forge-icon-button-filled-toggle-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-background-color:var(--forge-icon-button-filled-toggle-on-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-icon-color:var(--forge-icon-button-filled-toggle-on-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-disabled-cursor:var(--forge-icon-button-disabled-cursor, not-allowed);\n --_icon-button-disabled-opacity:var(--forge-icon-button-disabled-opacity, 0.38);\n --_icon-button-popover-icon-padding:var(--forge-icon-button-popover-icon-padding, var(--forge-spacing-xsmall, 8px));\n --_icon-button-focus-indicator-color:var(--forge-icon-button-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n}\n\n.forge-icon-button {\n display: var(--_icon-button-display);\n position: relative;\n outline: none;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n position: relative;\n z-index: 0;\n display: var(--_icon-button-display);\n align-items: center;\n justify-content: center;\n gap: var(--_icon-button-gap);\n box-sizing: border-box;\n height: var(--_icon-button-density-large-size);\n min-width: var(--_icon-button-density-large-size);\n border: var(--_icon-button-border);\n border-start-start-radius: var(--_icon-button-shape-start-start);\n border-start-end-radius: var(--_icon-button-shape-start-end);\n border-end-start-radius: var(--_icon-button-shape-end-start);\n border-end-end-radius: var(--_icon-button-shape-end-end);\n padding: var(--_icon-button-padding);\n box-shadow: var(--_icon-button-shadow);\n color: var(--_icon-button-icon-color);\n background: var(--_icon-button-background-color);\n font-size: var(--_icon-button-icon-size);\n cursor: var(--_icon-button-cursor);\n user-select: none;\n transition-property: box-shadow, background;\n transition-duration: var(--_icon-button-transition-duration);\n transition-timing-function: var(--_icon-button-transition-timing);\n}\n\n.forge-icon-button img, .forge-icon-button svg {\n height: var(--_icon-button-icon-size);\n width: var(--_icon-button-icon-size);\n}\n\n.forge-icon-button svg {\n fill: currentColor;\n}\n\n.forge-icon-button:not(:disabled) {\n --_state-layer-display:var(--forge-state-layer-display, flex);\n --_state-layer-color:var(--forge-state-layer-color, var(--forge-theme-on-surface, #000000));\n --_state-layer-hover-color:var(--forge-state-layer-hover-color, var(--_state-layer-color));\n --_state-layer-hover-opacity:var(--forge-state-layer-hover-opacity, 0.08);\n --_state-layer-pressed-color:var(--forge-state-layer-pressed-color, var(--_state-layer-color));\n --_state-layer-pressed-opacity:var(--forge-state-layer-pressed-opacity, 0.12);\n --_state-layer-hover-duration:var(--forge-state-layer-hover-duration, 15ms);\n --_state-layer-pressed-duration:var(--forge-state-layer-pressed-duration, 105ms);\n --_state-layer-animation-duration:var(--forge-state-layer-animation-duration, 375ms);\n}\n\n.forge-icon-button:not(:disabled)::before {\n opacity: 0;\n position: absolute;\n backface-visibility: hidden;\n transform: translateZ(0);\n background-color: var(--_state-layer-hover-color);\n inset: 0;\n transition: opacity var(--_state-layer-hover-duration) linear, background-color var(--_state-layer-hover-duration) linear;\n --_state-layer-hover-duration:var(--forge-state-layer-hover-duration, 100ms);\n content: "";\n opacity: 0;\n border-radius: inherit;\n}\n\n.forge-icon-button:not(:disabled):hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n\n.forge-icon-button:not(:disabled):active::before {\n opacity: var(--_state-layer-pressed-opacity);\n transition-duration: var(--_state-layer-pressed-duration);\n --_state-layer-pressed-opacity:var(--forge-state-layer-pressed-opacity, 0.18);\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-state-layer-color: var(--_icon-button-icon-color);\n}\n\n@keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n.forge-icon-button:not(:disabled) {\n outline: none;\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n --_focus-indicator-display:var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width:var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width:var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color:var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape:var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration:var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing:var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start:var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end:var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end:var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start:var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset:var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset:var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block:var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline:var(--forge-focus-indicator-offset-inline, 0);\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-focus-indicator-color: var(--_icon-button-focus-indicator-color);\n --forge-focus-indicator-shape: var(--_icon-button-shape);\n}\n\n.forge-icon-button:not(:disabled):where(.forge-icon-button--text, :not(:where(.forge-icon-button--outlined, .forge-icon-button--tonal, .forge-icon-button--filled, .forge-icon-button--raised))) {\n --forge-focus-indicator-outward-offset: 0px;\n}\n\n.forge-icon-button--outlined {\n border-width: var(--_icon-button-outlined-border-width);\n border-style: var(--_icon-button-outlined-border-style);\n border-color: var(--_icon-button-outlined-border-color);\n}\n\n.forge-icon-button--tonal {\n --_icon-button-icon-color:var(--_icon-button-tonal-icon-color);\n --_icon-button-background-color:var(--_icon-button-tonal-background-color);\n}\n\n.forge-icon-button--filled, .forge-icon-button--raised {\n --_icon-button-icon-color:var(--_icon-button-filled-icon-color);\n --_icon-button-background-color:var(--_icon-button-filled-background-color);\n}\n\n.forge-icon-button--raised {\n --_icon-button-shadow:var(--_icon-button-raised-shadow);\n}\n\n.forge-icon-button--raised:hover {\n --_icon-button-raised-shadow:var(--_icon-button-raised-hover-shadow);\n}\n\n.forge-icon-button--raised:active {\n --_icon-button-raised-shadow:var(--_icon-button-raised-active-shadow);\n}\n\n.forge-icon-button--squared {\n --_icon-button-shape:var(--_icon-button-shape-squared);\n}\n\n.forge-icon-button--small {\n --_icon-button-size:var(--_icon-button-density-small-size);\n --_icon-button-icon-size:var(--_icon-button-density-small-icon-size);\n --_icon-button-padding:var(--_icon-button-density-small-padding);\n}\n\n.forge-icon-button--small > * {\n font-size: var(--_icon-button-density-small-icon-size);\n}\n\n.forge-icon-button--medium {\n --_icon-button-size:var(--_icon-button-density-medium-size);\n --_icon-button-padding:var(--_icon-button-density-medium-padding);\n}\n\n.forge-icon-button:disabled {\n pointer-events: none;\n opacity: var(--_icon-button-disabled-opacity);\n pointer-events: auto;\n cursor: not-allowed;\n}\n\n.forge-icon-button forge-circular-progress {\n --forge-circular-progress-indicator-color: var(--_icon-button-icon-color);\n --forge-circular-progress-track-color: transparent;\n --forge-circular-progress-size: 1em;\n}\n\n:host {\n display: block;\n height: 100%;\n min-inline-size: 0;\n box-sizing: border-box;\n}\n\n.canvas {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-inline-size: 0;\n box-sizing: border-box;\n background-color: var(--forge-theme-surface, #ffffff);\n border-inline-start: var(--forge-ai-canvas-border-inline-start, 1px solid var(--forge-theme-outline, #e0e0e0));\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--forge-spacing-small, 12px);\n flex-shrink: 0;\n min-height: 56px;\n padding-inline: var(--forge-spacing-medium, 16px);\n box-sizing: border-box;\n border-block-end: 1px solid var(--forge-theme-outline, #e0e0e0);\n}\n\n.header-start {\n display: flex;\n align-items: center;\n flex: 1;\n min-inline-size: 0;\n}\n\n.title {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-heading1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-heading1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-heading1-font-weight, 500);\n line-height: var(--forge-typography-heading1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-heading1-letter-spacing, 0.0178571429em);\n text-transform: var(--forge-typography-heading1-text-transform, inherit);\n text-decoration: var(--forge-typography-heading1-text-decoration, inherit);\n margin: 0;\n color: var(--forge-theme-text-high, rgba(0, 0, 0, 0.87));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.header-end {\n display: flex;\n align-items: center;\n gap: var(--forge-spacing-xxsmall, 4px);\n flex-shrink: 0;\n}\n\n.close-button,\n.close-button > svg {\n fill: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}\n\n.body::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.body::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.body::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.body::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.body::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.body::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--forge-ai-canvas-body-padding, var(--forge-spacing-medium, 16px));\n box-sizing: border-box;\n}';
|
|
2
|
+
export {
|
|
3
|
+
styles as default
|
|
4
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ai-canvas';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AgentAdapter } from './agent-adapter.js';
|
|
2
|
-
import { ChatMessage,
|
|
2
|
+
import { ChatMessage, AnyToolDefinition } from './types.js';
|
|
3
3
|
export interface AgUiAdapterConfig {
|
|
4
4
|
url: string;
|
|
5
5
|
context?: Record<string, unknown>;
|
|
6
6
|
headers?: Record<string, string>;
|
|
7
|
-
tools?:
|
|
7
|
+
tools?: AnyToolDefinition[];
|
|
8
8
|
}
|
|
9
9
|
export declare class AgUiAdapter extends AgentAdapter {
|
|
10
10
|
#private;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatMessage, FileUploadCallbacks, McpAppUiResource, McpToolResult,
|
|
1
|
+
import { ChatMessage, FileUploadCallbacks, McpAppUiResource, McpToolResult, AnyToolDefinition } from './types.js';
|
|
2
2
|
import { EventEmitter, Subscription } from './event-emitter.js';
|
|
3
3
|
export interface MessageStartEvent {
|
|
4
4
|
messageId: string;
|
|
@@ -167,7 +167,7 @@ export interface ActivityDeltaAgentEvent {
|
|
|
167
167
|
}
|
|
168
168
|
export declare abstract class AgentAdapter {
|
|
169
169
|
protected _state: AdapterState;
|
|
170
|
-
protected _tools:
|
|
170
|
+
protected _tools: AnyToolDefinition[];
|
|
171
171
|
protected _events: {
|
|
172
172
|
runStarted: EventEmitter<void>;
|
|
173
173
|
runFinished: EventEmitter<void>;
|
|
@@ -235,14 +235,14 @@ export declare abstract class AgentAdapter {
|
|
|
235
235
|
disposeMcpAppView?(params: {
|
|
236
236
|
toolCallId: string;
|
|
237
237
|
}): void;
|
|
238
|
-
setTools(tools:
|
|
239
|
-
getTools():
|
|
238
|
+
setTools(tools: AnyToolDefinition[]): void;
|
|
239
|
+
getTools(): AnyToolDefinition[];
|
|
240
240
|
/**
|
|
241
241
|
* Tools to forward to the backend agent, excluding MCP-app tools (`ToolDefinition.mcpApp`).
|
|
242
242
|
* MCP-app tools are a host-internal mechanism for streaming a UI resource into an existing
|
|
243
243
|
* tool call — the model never calls them directly, so they must never reach the agent.
|
|
244
244
|
*/
|
|
245
|
-
getModelFacingTools():
|
|
245
|
+
getModelFacingTools(): AnyToolDefinition[];
|
|
246
246
|
getState(): AdapterState;
|
|
247
247
|
get isConnected(): boolean;
|
|
248
248
|
get isConnecting(): boolean;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AgentAdapter } from './agent-adapter.js';
|
|
2
|
-
import { ChatMessage, ToolCall,
|
|
2
|
+
import { ChatMessage, ToolCall, AnyToolDefinition } from './types.js';
|
|
3
3
|
export interface AgentRunnerConfig {
|
|
4
4
|
/** The adapter instance that handles communication with the AI model */
|
|
5
5
|
adapter: AgentAdapter;
|
|
6
6
|
/** The user prompt to send to the agent */
|
|
7
7
|
prompt: string;
|
|
8
8
|
/** Optional tools the agent can call during execution */
|
|
9
|
-
tools?:
|
|
9
|
+
tools?: AnyToolDefinition[];
|
|
10
10
|
/** Execution mode: 'one-shot' stops after first response, 'multi-turn' allows tool usage loops. @default 'one-shot' */
|
|
11
11
|
mode?: 'one-shot' | 'multi-turn';
|
|
12
12
|
/** Maximum conversation turns in multi-turn mode to prevent infinite loops. @default 20 */
|
|
@@ -10,7 +10,7 @@ import { ForgeAiSuggestionsEventData, Suggestion } from '../ai-suggestions';
|
|
|
10
10
|
import { ForgeAiVoiceInputResultEvent } from '../ai-voice-input';
|
|
11
11
|
import { AgentAdapter } from './agent-adapter.js';
|
|
12
12
|
import { ChatbotCoreController } from '../core/chatbot-core-controller.js';
|
|
13
|
-
import { Agent, ChatMessage, ClientMessageInput, ContextItem, HeadingLevel, MessageItem, SlashCommand, ThreadState,
|
|
13
|
+
import { Agent, ChatMessage, ClientMessageInput, ContextItem, HeadingLevel, MessageItem, SlashCommand, ThreadState, ToolCall, AnyToolDefinition } from './types.js';
|
|
14
14
|
export type FeatureToggle = 'on' | 'off';
|
|
15
15
|
export declare abstract class AiChatbotBase extends LitElement {
|
|
16
16
|
#private;
|
|
@@ -56,8 +56,9 @@ export declare abstract class AiChatbotBase extends LitElement {
|
|
|
56
56
|
protected _coreController: ChatbotCoreController;
|
|
57
57
|
protected get _isStreaming(): boolean;
|
|
58
58
|
protected get _isUploading(): boolean;
|
|
59
|
-
protected get _tools(): Map<string,
|
|
59
|
+
protected get _tools(): Map<string, AnyToolDefinition>;
|
|
60
60
|
protected get _messageItems(): MessageItem[];
|
|
61
|
+
protected get _toolCalls(): ToolCall[];
|
|
61
62
|
protected get _hasMessages(): boolean;
|
|
62
63
|
protected get _allContextItems(): ContextItem[];
|
|
63
64
|
connectedCallback(): void;
|
|
@@ -140,6 +140,17 @@ class AiChatbotBase extends LitElement {
|
|
|
140
140
|
get _messageItems() {
|
|
141
141
|
return this._coreController?.messageItems ?? [];
|
|
142
142
|
}
|
|
143
|
+
get _toolCalls() {
|
|
144
|
+
return this._messageItems.flatMap((item) => {
|
|
145
|
+
if (item.type === "toolCall") {
|
|
146
|
+
return [item.data];
|
|
147
|
+
}
|
|
148
|
+
if (item.type === "assistant") {
|
|
149
|
+
return item.data.children.flatMap((child) => child.type === "toolCall" ? [child.data] : []);
|
|
150
|
+
}
|
|
151
|
+
return [];
|
|
152
|
+
});
|
|
153
|
+
}
|
|
143
154
|
get _hasMessages() {
|
|
144
155
|
return this._coreController?.hasMessages ?? false;
|
|
145
156
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, TemplateResult, nothing, PropertyValues, CSSResult } from 'lit';
|
|
2
|
-
import { ToolCall,
|
|
2
|
+
import { ToolCall, AnyToolDefinition } from './types.js';
|
|
3
3
|
declare global {
|
|
4
4
|
interface HTMLElementTagNameMap {
|
|
5
5
|
'forge-ai-chatbot-tool-call': AiChatbotToolCallComponent;
|
|
@@ -13,7 +13,7 @@ export declare class AiChatbotToolCallComponent extends LitElement {
|
|
|
13
13
|
#private;
|
|
14
14
|
static styles: CSSResult;
|
|
15
15
|
toolCall: ToolCall;
|
|
16
|
-
toolDefinition?:
|
|
16
|
+
toolDefinition?: AnyToolDefinition;
|
|
17
17
|
updated(changedProperties: PropertyValues<this>): void;
|
|
18
18
|
render(): TemplateResult | typeof nothing;
|
|
19
19
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { unsafeCSS, LitElement, nothing, html } from "lit";
|
|
2
2
|
import { property, customElement } from "lit/decorators.js";
|
|
3
3
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
4
|
+
import { ContextConsumer } from "@lit/context";
|
|
5
|
+
import { toolCanvasHostContext, createToolCanvas, requestCanvasOpen, requestCanvasClose, resolveToolCanvasInline, resolveToolCanvasIcon, resolveToolCanvasTitle, resolveToolCanvasSubtitle, resolveToolCanvasActionLabel } from "./tool-canvas.mjs";
|
|
4
6
|
import { shouldShowToolRenderer } from "./utils.mjs";
|
|
7
|
+
import "../ai-artifact-card/ai-artifact-card.mjs";
|
|
5
8
|
import styles from "./ai-chatbot-tool-call.scss.mjs";
|
|
6
9
|
var __defProp = Object.defineProperty;
|
|
7
10
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -21,7 +24,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
21
24
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
22
25
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
23
26
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
24
|
-
var _customRendererRef, _renderedElement, _AiChatbotToolCallComponent_instances, shouldRenderCustom_get, dispatchScrollRequest_fn, customRenderer_get, replaceRenderedElement_fn;
|
|
27
|
+
var _customRendererRef, _renderedElement, _renderedCanvas, _canvasHostConsumer, _AiChatbotToolCallComponent_instances, shouldRenderCustom_get, presentation_get, isOpenInCanvas_get, _canvasControls, canvas_get, showsArtifactCard_get, artifactCard_fn, dispatchScrollRequest_fn, customRenderer_get, replaceRenderedElement_fn;
|
|
25
28
|
const AiChatbotToolCallComponentTagName = "forge-ai-chatbot-tool-call";
|
|
26
29
|
let AiChatbotToolCallComponent = class extends LitElement {
|
|
27
30
|
constructor() {
|
|
@@ -29,27 +32,40 @@ let AiChatbotToolCallComponent = class extends LitElement {
|
|
|
29
32
|
__privateAdd(this, _AiChatbotToolCallComponent_instances);
|
|
30
33
|
__privateAdd(this, _customRendererRef, createRef());
|
|
31
34
|
__privateAdd(this, _renderedElement);
|
|
35
|
+
__privateAdd(this, _renderedCanvas);
|
|
36
|
+
__privateAdd(this, _canvasHostConsumer, new ContextConsumer(this, {
|
|
37
|
+
context: toolCanvasHostContext,
|
|
38
|
+
subscribe: true,
|
|
39
|
+
callback: () => this.requestUpdate()
|
|
40
|
+
}));
|
|
41
|
+
__privateAdd(this, _canvasControls);
|
|
32
42
|
}
|
|
33
43
|
updated(changedProperties) {
|
|
34
44
|
super.updated(changedProperties);
|
|
35
|
-
if (!changedProperties.has("toolCall") && !changedProperties.has("toolDefinition")) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
45
|
const container = __privateGet(this, _customRendererRef).value;
|
|
39
46
|
if (!container || !__privateGet(this, _AiChatbotToolCallComponent_instances, shouldRenderCustom_get)) {
|
|
40
47
|
return;
|
|
41
48
|
}
|
|
42
49
|
const renderer = this.toolDefinition?.renderer;
|
|
50
|
+
const canvas = __privateGet(this, _AiChatbotToolCallComponent_instances, canvas_get);
|
|
51
|
+
const mounted = container.childNodes.length > 0;
|
|
52
|
+
const changed = changedProperties.has("toolCall") || changedProperties.has("toolDefinition");
|
|
43
53
|
if (renderer?.elementTag) {
|
|
44
|
-
if (__privateGet(this, _renderedElement) instanceof HTMLElement && __privateGet(this, _renderedElement).tagName.toLowerCase() === renderer.elementTag) {
|
|
45
|
-
__privateGet(this, _renderedElement)
|
|
54
|
+
if (mounted && __privateGet(this, _renderedElement) instanceof HTMLElement && __privateGet(this, _renderedElement).tagName.toLowerCase() === renderer.elementTag) {
|
|
55
|
+
const existing = __privateGet(this, _renderedElement);
|
|
56
|
+
existing.toolCall = this.toolCall;
|
|
57
|
+
existing.presentation = __privateGet(this, _AiChatbotToolCallComponent_instances, presentation_get);
|
|
58
|
+
existing.canvas = canvas;
|
|
46
59
|
return;
|
|
47
60
|
}
|
|
48
61
|
const element = document.createElement(renderer.elementTag);
|
|
49
62
|
element.toolCall = this.toolCall;
|
|
63
|
+
element.presentation = __privateGet(this, _AiChatbotToolCallComponent_instances, presentation_get);
|
|
64
|
+
element.canvas = canvas;
|
|
50
65
|
__privateMethod(this, _AiChatbotToolCallComponent_instances, replaceRenderedElement_fn).call(this, container, element);
|
|
51
|
-
} else if (renderer?.render) {
|
|
52
|
-
|
|
66
|
+
} else if (renderer?.render && (changed || !mounted || canvas !== __privateGet(this, _renderedCanvas))) {
|
|
67
|
+
__privateSet(this, _renderedCanvas, canvas);
|
|
68
|
+
__privateMethod(this, _AiChatbotToolCallComponent_instances, replaceRenderedElement_fn).call(this, container, renderer.render(this.toolCall, { presentation: __privateGet(this, _AiChatbotToolCallComponent_instances, presentation_get), canvas }));
|
|
53
69
|
}
|
|
54
70
|
}
|
|
55
71
|
render() {
|
|
@@ -58,10 +74,68 @@ let AiChatbotToolCallComponent = class extends LitElement {
|
|
|
58
74
|
};
|
|
59
75
|
_customRendererRef = /* @__PURE__ */ new WeakMap();
|
|
60
76
|
_renderedElement = /* @__PURE__ */ new WeakMap();
|
|
77
|
+
_renderedCanvas = /* @__PURE__ */ new WeakMap();
|
|
78
|
+
_canvasHostConsumer = /* @__PURE__ */ new WeakMap();
|
|
61
79
|
_AiChatbotToolCallComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
62
80
|
shouldRenderCustom_get = function() {
|
|
63
81
|
return shouldShowToolRenderer(this.toolCall, this.toolDefinition);
|
|
64
82
|
};
|
|
83
|
+
presentation_get = function() {
|
|
84
|
+
if (!this.toolDefinition?.canvas) {
|
|
85
|
+
return "inline";
|
|
86
|
+
}
|
|
87
|
+
return __privateGet(this, _canvasHostConsumer).value?.presentation ?? "inline";
|
|
88
|
+
};
|
|
89
|
+
isOpenInCanvas_get = function() {
|
|
90
|
+
return __privateGet(this, _canvasHostConsumer).value?.openToolCallId === this.toolCall.id;
|
|
91
|
+
};
|
|
92
|
+
_canvasControls = /* @__PURE__ */ new WeakMap();
|
|
93
|
+
canvas_get = function() {
|
|
94
|
+
const available = __privateGet(this, _AiChatbotToolCallComponent_instances, presentation_get) === "inline-expandable";
|
|
95
|
+
const isOpen = __privateGet(this, _AiChatbotToolCallComponent_instances, isOpenInCanvas_get);
|
|
96
|
+
if (__privateGet(this, _canvasControls)?.available !== available || __privateGet(this, _canvasControls).isOpen !== isOpen) {
|
|
97
|
+
__privateSet(this, _canvasControls, createToolCanvas({
|
|
98
|
+
available,
|
|
99
|
+
isOpen: () => __privateGet(this, _AiChatbotToolCallComponent_instances, isOpenInCanvas_get),
|
|
100
|
+
open: (options) => requestCanvasOpen(this, {
|
|
101
|
+
toolCallId: this.toolCall.id,
|
|
102
|
+
toolName: this.toolCall.name,
|
|
103
|
+
title: options?.title
|
|
104
|
+
}),
|
|
105
|
+
close: () => requestCanvasClose(this, { toolCallId: this.toolCall.id })
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
return __privateGet(this, _canvasControls);
|
|
109
|
+
};
|
|
110
|
+
showsArtifactCard_get = function() {
|
|
111
|
+
if (!this.toolDefinition || __privateGet(this, _AiChatbotToolCallComponent_instances, presentation_get) !== "inline-expandable") {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
switch (resolveToolCanvasInline(this.toolDefinition)) {
|
|
115
|
+
case "card":
|
|
116
|
+
return true;
|
|
117
|
+
case "card-while-open":
|
|
118
|
+
return __privateGet(this, _AiChatbotToolCallComponent_instances, isOpenInCanvas_get);
|
|
119
|
+
default:
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
artifactCard_fn = function(toolDefinition) {
|
|
124
|
+
const active = __privateGet(this, _AiChatbotToolCallComponent_instances, isOpenInCanvas_get);
|
|
125
|
+
const icon = resolveToolCanvasIcon(this.toolCall, toolDefinition);
|
|
126
|
+
icon?.setAttribute("slot", "icon");
|
|
127
|
+
return html`
|
|
128
|
+
<forge-ai-artifact-card
|
|
129
|
+
title-text=${resolveToolCanvasTitle(this.toolCall, toolDefinition)}
|
|
130
|
+
.subtitleText=${resolveToolCanvasSubtitle(this.toolCall, toolDefinition) ?? ""}
|
|
131
|
+
action-label=${resolveToolCanvasActionLabel(this.toolCall, toolDefinition, active)}
|
|
132
|
+
asset-id=${this.toolCall.id}
|
|
133
|
+
?active=${active}
|
|
134
|
+
@forge-ai-artifact-card-open=${() => __privateGet(this, _AiChatbotToolCallComponent_instances, canvas_get).toggle()}>
|
|
135
|
+
${icon ?? nothing}
|
|
136
|
+
</forge-ai-artifact-card>
|
|
137
|
+
`;
|
|
138
|
+
};
|
|
65
139
|
dispatchScrollRequest_fn = function() {
|
|
66
140
|
this.dispatchEvent(
|
|
67
141
|
new CustomEvent("forge-ai-message-thread-scroll-request", {
|
|
@@ -71,10 +145,14 @@ dispatchScrollRequest_fn = function() {
|
|
|
71
145
|
);
|
|
72
146
|
};
|
|
73
147
|
customRenderer_get = function() {
|
|
74
|
-
const
|
|
75
|
-
|
|
148
|
+
const toolDefinition = this.toolDefinition;
|
|
149
|
+
const renderer = toolDefinition?.renderer;
|
|
150
|
+
if (!toolDefinition || !renderer || !__privateGet(this, _AiChatbotToolCallComponent_instances, shouldRenderCustom_get)) {
|
|
76
151
|
return nothing;
|
|
77
152
|
}
|
|
153
|
+
if (__privateGet(this, _AiChatbotToolCallComponent_instances, showsArtifactCard_get)) {
|
|
154
|
+
return __privateMethod(this, _AiChatbotToolCallComponent_instances, artifactCard_fn).call(this, toolDefinition);
|
|
155
|
+
}
|
|
78
156
|
if (renderer.elementTag || renderer.render) {
|
|
79
157
|
return html`<div ${ref(__privateGet(this, _customRendererRef))}></div>`;
|
|
80
158
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { TemplateResult, CSSResult } from 'lit';
|
|
1
|
+
import { PropertyValues, TemplateResult, CSSResult } from 'lit';
|
|
2
2
|
import { AiMessageThreadComponent } from '../ai-message-thread';
|
|
3
3
|
import { AiPromptComponent } from '../ai-prompt';
|
|
4
4
|
import { AiChatbotBase } from './ai-chatbot-base.js';
|
|
5
|
+
import { CanvasOpenEventData, OpenCanvasOptions } from '../core/canvas-controller.js';
|
|
5
6
|
import { Agent, ChatMessage, ForgeAiChatbotThreadSelectEventData, ForgeAiChatbotThreadSearchEventData, ForgeAiChatbotThreadLoadMoreEventData, ForgeAiChatbotThreadRenameEventData, ForgeAiChatbotThreadDeleteEventData, ForgeAiChatbotContextRemoveEventData, Thread } from './types.js';
|
|
6
7
|
import { Ref } from 'lit/directives/ref.js';
|
|
7
8
|
declare global {
|
|
@@ -35,6 +36,8 @@ declare global {
|
|
|
35
36
|
'forge-ai-chatbot-thread-delete': CustomEvent<ForgeAiChatbotThreadDeleteEventData>;
|
|
36
37
|
'forge-ai-chatbot-context-remove': CustomEvent<ForgeAiChatbotContextRemoveEventData>;
|
|
37
38
|
'forge-ai-chatbot-thread-retry': CustomEvent<void>;
|
|
39
|
+
'forge-ai-chatbot-canvas-open': CustomEvent<CanvasOpenEventData>;
|
|
40
|
+
'forge-ai-chatbot-canvas-close': CustomEvent<void>;
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
export interface ForgeAiChatbotMessageEventData {
|
|
@@ -102,12 +105,15 @@ export declare const AiChatbotComponentTagName: keyof HTMLElementTagNameMap;
|
|
|
102
105
|
* @property {FeatureToggle} exportOption - Controls the export-conversation header action. `'on'` (default) shows it when messages exist; `'off'` hides it entirely.
|
|
103
106
|
* @property {string | null} selectedThreadId - The id of the currently selected thread. Set this to highlight a thread in the conversations panel (e.g. when restoring a conversation loaded from the backend). Updated internally when a thread is selected or a new chat starts.
|
|
104
107
|
* @property {boolean} threadsLoading - When true, shows a loading indicator in the conversations panel's recent chats list while threads are loading (default: false)
|
|
108
|
+
* @property {string} canvasTitle - Default title for the artifact canvas modal, used when the open request does not supply one
|
|
105
109
|
* @property {string | undefined} threadsError - Message describing a failed thread load. When set, the conversations panel shows the message with a retry button instead of its empty state or loading indicator. The conversations button also shows an error badge so the failure is visible with the panel closed. If threads are already loaded the list stays visible and the message renders as a compact single line with a retry - at the bottom of the list when a page was in flight, otherwise above it. Clear it once a load succeeds.
|
|
106
110
|
*
|
|
107
111
|
* @cssproperty --forge-ai-chatbot-icon-color - The fill color for the AI icon. Defaults to `tertiary`.
|
|
108
112
|
* @cssproperty --forge-ai-chatbot-suggestion-background - The background color for suggestion buttons. Defaults to `tertiary-container`.
|
|
109
113
|
* @cssproperty --forge-ai-chatbot-suggestion-foreground - The text color for suggestion buttons. Defaults to `on-tertiary-container`.
|
|
110
114
|
* @cssproperty --forge-ai-chatbot-header-title-color - The color of the header title text. Defaults to `currentColor`.
|
|
115
|
+
* @cssproperty --forge-ai-chatbot-canvas-width - Width of the artifact canvas modal (default: 80vw).
|
|
116
|
+
* @cssproperty --forge-ai-chatbot-canvas-height - Height of the artifact canvas modal (default: 80vh).
|
|
111
117
|
*
|
|
112
118
|
* @event {CustomEvent<void>} forge-ai-chatbot-connected - Fired when adapter connects
|
|
113
119
|
* @event {CustomEvent<void>} forge-ai-chatbot-disconnected - Fired when adapter disconnects
|
|
@@ -132,6 +138,8 @@ export declare const AiChatbotComponentTagName: keyof HTMLElementTagNameMap;
|
|
|
132
138
|
* @event {CustomEvent<ForgeAiChatbotThreadRenameEventData>} forge-ai-chatbot-thread-rename - Fired when user renames a thread. Cancelable - if prevented, call onSuccess() to commit or onError() to revert.
|
|
133
139
|
* @event {CustomEvent<ForgeAiChatbotThreadDeleteEventData>} forge-ai-chatbot-thread-delete - Fired when user deletes a thread. Cancelable - if prevented, call onSuccess() to commit deletion or onError() to revert. Otherwise optimistically removed.
|
|
134
140
|
* @event {CustomEvent<void>} forge-ai-chatbot-thread-retry - Fired when the retry button in the conversations panel's error state is clicked. Re-request the threads and clear threadsError once the load succeeds
|
|
141
|
+
* @event {CustomEvent<CanvasOpenEventData>} forge-ai-chatbot-canvas-open - Fired before the canvas modal opens or replaces its content. Cancelable - prevents the canvas from opening
|
|
142
|
+
* @event {CustomEvent<void>} forge-ai-chatbot-canvas-close - Fired when the canvas modal closes. Cancelable only for user or `closeCanvas()` initiated closes; closes caused by clearing the thread cannot be prevented
|
|
135
143
|
*/
|
|
136
144
|
export declare class AiChatbotComponent extends AiChatbotBase {
|
|
137
145
|
#private;
|
|
@@ -148,11 +156,26 @@ export declare class AiChatbotComponent extends AiChatbotBase {
|
|
|
148
156
|
selectedThreadId: string | null;
|
|
149
157
|
threadsLoading: boolean;
|
|
150
158
|
threadsError?: string;
|
|
159
|
+
canvasTitle?: string;
|
|
151
160
|
protected _messageThreadRef: Ref<AiMessageThreadComponent>;
|
|
152
161
|
protected _promptRef: Ref<AiPromptComponent>;
|
|
153
162
|
protected _handleInfo(): void;
|
|
154
163
|
sendMessage(content: string, files?: File[]): Promise<void>;
|
|
155
164
|
focus(): void;
|
|
165
|
+
willUpdate(changedProperties: PropertyValues<this>): void;
|
|
166
|
+
updated(changedProperties: PropertyValues<this>): void;
|
|
167
|
+
get canvasOpen(): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Opens the artifact canvas in a modal over the chatbot, or swaps its content if already open.
|
|
170
|
+
* Returns false when the open event is prevented.
|
|
171
|
+
*/
|
|
172
|
+
openCanvas(options?: OpenCanvasOptions): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Closes the artifact canvas. Returns false if it was not open or the close event was prevented.
|
|
175
|
+
*/
|
|
176
|
+
closeCanvas(): boolean;
|
|
177
|
+
clearMessages(): boolean;
|
|
178
|
+
setMessages(messages: ChatMessage[]): void;
|
|
156
179
|
showConversations(): void;
|
|
157
180
|
hideConversations(): void;
|
|
158
181
|
/**
|