@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,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, TemplateResult, PropertyValues, CSSResult } from 'lit';
|
|
2
|
-
import { MessageItem,
|
|
2
|
+
import { MessageItem, AnyToolDefinition } from '../ai-chatbot/types.js';
|
|
3
3
|
import { FeatureToggle } from '../ai-chatbot/ai-chatbot.js';
|
|
4
4
|
declare global {
|
|
5
5
|
interface HTMLElementTagNameMap {
|
|
@@ -55,12 +55,13 @@ export declare class AiMessageThreadComponent extends LitElement {
|
|
|
55
55
|
#private;
|
|
56
56
|
static styles: CSSResult;
|
|
57
57
|
messageItems: MessageItem[];
|
|
58
|
-
tools?: Map<string,
|
|
58
|
+
tools?: Map<string, AnyToolDefinition>;
|
|
59
59
|
enableReactions: boolean;
|
|
60
60
|
showThinking: boolean;
|
|
61
61
|
debugMode: boolean;
|
|
62
62
|
autoScroll: FeatureToggle;
|
|
63
63
|
private _messageThreadContainer;
|
|
64
|
+
private _messageThreadContent;
|
|
64
65
|
connectedCallback(): void;
|
|
65
66
|
disconnectedCallback(): void;
|
|
66
67
|
firstUpdated(): void;
|
|
@@ -2,7 +2,9 @@ import { unsafeCSS, LitElement, html, nothing } from "lit";
|
|
|
2
2
|
import { property, query, customElement } from "lit/decorators.js";
|
|
3
3
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
4
4
|
import { when } from "lit/directives/when.js";
|
|
5
|
+
import { keyed } from "lit/directives/keyed.js";
|
|
5
6
|
import { MarkdownStreamController } from "../ai-chatbot/markdown-stream-controller.mjs";
|
|
7
|
+
import { rendersAsMcpAppWidget } from "../ai-chatbot/utils.mjs";
|
|
6
8
|
import "../ai-assistant-response/ai-assistant-response.mjs";
|
|
7
9
|
import "../ai-client-message/ai-client-message.mjs";
|
|
8
10
|
import "../ai-empty-state/ai-empty-state.mjs";
|
|
@@ -12,6 +14,7 @@ import "../ai-thinking-indicator/ai-thinking-indicator.mjs";
|
|
|
12
14
|
import "../ai-user-message/ai-user-message.mjs";
|
|
13
15
|
import "../ai-chatbot/ai-chatbot-tool-call.mjs";
|
|
14
16
|
import "../core/tooltip/tooltip.mjs";
|
|
17
|
+
import "../tools/ai-mcp-app/ai-mcp-app.mjs";
|
|
15
18
|
import styles from "./ai-message-thread.scss.mjs";
|
|
16
19
|
var __defProp = Object.defineProperty;
|
|
17
20
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -31,7 +34,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
31
34
|
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);
|
|
32
35
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
33
36
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
34
|
-
var _markdownController, _canAutoScroll, _resizeObserver, _AiMessageThreadComponent_instances, scheduleScroll_fn, checkScrollState_fn, _handleScroll, _handleScrollToBottomClick, scrollToBottomButton_get, handleCopy_fn, handleResend_fn, handleThumbsUp_fn, handleThumbsDown_fn, handleUserCopy_fn, handleUserResend_fn, handleUserEdit_fn, renderToolCall_fn, activeResponse_get, renderAssistantResponse_fn, emptyState_get, thinkingIndicator_get, messages_get, dispatchEvent_fn;
|
|
37
|
+
var _markdownController, _canAutoScroll, _lastScrollTop, _resizeObserver, _contentResizeObserver, _AiMessageThreadComponent_instances, observe_fn, handleContentResize_fn, scheduleScroll_fn, checkScrollState_fn, _handleScroll, _handleScrollToBottomClick, scrollToBottomButton_get, handleCopy_fn, handleResend_fn, handleThumbsUp_fn, handleThumbsDown_fn, handleUserCopy_fn, handleUserResend_fn, handleUserEdit_fn, renderToolCall_fn, activeResponse_get, renderAssistantResponse_fn, emptyState_get, thinkingIndicator_get, messages_get, dispatchEvent_fn;
|
|
35
38
|
const AiMessageThreadComponentTagName = "forge-ai-message-thread";
|
|
36
39
|
const SCROLL_THRESHOLD = 100;
|
|
37
40
|
let AiMessageThreadComponent = class extends LitElement {
|
|
@@ -45,7 +48,9 @@ let AiMessageThreadComponent = class extends LitElement {
|
|
|
45
48
|
this.autoScroll = "on";
|
|
46
49
|
__privateAdd(this, _markdownController);
|
|
47
50
|
__privateAdd(this, _canAutoScroll, true);
|
|
51
|
+
__privateAdd(this, _lastScrollTop, 0);
|
|
48
52
|
__privateAdd(this, _resizeObserver);
|
|
53
|
+
__privateAdd(this, _contentResizeObserver);
|
|
49
54
|
__privateAdd(this, _handleScroll, () => {
|
|
50
55
|
__privateMethod(this, _AiMessageThreadComponent_instances, checkScrollState_fn).call(this);
|
|
51
56
|
});
|
|
@@ -57,13 +62,18 @@ let AiMessageThreadComponent = class extends LitElement {
|
|
|
57
62
|
super.connectedCallback();
|
|
58
63
|
__privateSet(this, _markdownController, new MarkdownStreamController(this));
|
|
59
64
|
__privateSet(this, _resizeObserver, new ResizeObserver(() => __privateMethod(this, _AiMessageThreadComponent_instances, checkScrollState_fn).call(this)));
|
|
65
|
+
__privateSet(this, _contentResizeObserver, new ResizeObserver(() => __privateMethod(this, _AiMessageThreadComponent_instances, handleContentResize_fn).call(this)));
|
|
66
|
+
if (this.hasUpdated) {
|
|
67
|
+
__privateMethod(this, _AiMessageThreadComponent_instances, observe_fn).call(this);
|
|
68
|
+
}
|
|
60
69
|
}
|
|
61
70
|
disconnectedCallback() {
|
|
62
71
|
super.disconnectedCallback();
|
|
63
72
|
__privateGet(this, _resizeObserver)?.disconnect();
|
|
73
|
+
__privateGet(this, _contentResizeObserver)?.disconnect();
|
|
64
74
|
}
|
|
65
75
|
firstUpdated() {
|
|
66
|
-
|
|
76
|
+
__privateMethod(this, _AiMessageThreadComponent_instances, observe_fn).call(this);
|
|
67
77
|
}
|
|
68
78
|
updated(changedProperties) {
|
|
69
79
|
super.updated(changedProperties);
|
|
@@ -95,8 +105,19 @@ let AiMessageThreadComponent = class extends LitElement {
|
|
|
95
105
|
};
|
|
96
106
|
_markdownController = /* @__PURE__ */ new WeakMap();
|
|
97
107
|
_canAutoScroll = /* @__PURE__ */ new WeakMap();
|
|
108
|
+
_lastScrollTop = /* @__PURE__ */ new WeakMap();
|
|
98
109
|
_resizeObserver = /* @__PURE__ */ new WeakMap();
|
|
110
|
+
_contentResizeObserver = /* @__PURE__ */ new WeakMap();
|
|
99
111
|
_AiMessageThreadComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
112
|
+
observe_fn = function() {
|
|
113
|
+
__privateGet(this, _resizeObserver)?.observe(this._messageThreadContainer);
|
|
114
|
+
__privateGet(this, _contentResizeObserver)?.observe(this._messageThreadContent);
|
|
115
|
+
};
|
|
116
|
+
handleContentResize_fn = function() {
|
|
117
|
+
if (this.autoScroll === "on") {
|
|
118
|
+
this.scrollToBottom({ behavior: "instant" });
|
|
119
|
+
}
|
|
120
|
+
};
|
|
100
121
|
scheduleScroll_fn = async function() {
|
|
101
122
|
await this.updateComplete;
|
|
102
123
|
await new Promise(requestAnimationFrame);
|
|
@@ -108,7 +129,10 @@ checkScrollState_fn = function() {
|
|
|
108
129
|
return;
|
|
109
130
|
}
|
|
110
131
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
111
|
-
const
|
|
132
|
+
const isNearBottom = scrollTop + clientHeight >= scrollHeight - SCROLL_THRESHOLD;
|
|
133
|
+
const scrolledUp = scrollTop < __privateGet(this, _lastScrollTop);
|
|
134
|
+
__privateSet(this, _lastScrollTop, scrollTop);
|
|
135
|
+
const canAutoScroll = isNearBottom || __privateGet(this, _canAutoScroll) && !scrolledUp;
|
|
112
136
|
if (canAutoScroll !== __privateGet(this, _canAutoScroll)) {
|
|
113
137
|
__privateSet(this, _canAutoScroll, canAutoScroll);
|
|
114
138
|
this.requestUpdate();
|
|
@@ -173,6 +197,9 @@ handleUserEdit_fn = function(messageId, content) {
|
|
|
173
197
|
});
|
|
174
198
|
};
|
|
175
199
|
renderToolCall_fn = function(toolCall) {
|
|
200
|
+
if (rendersAsMcpAppWidget(toolCall)) {
|
|
201
|
+
return keyed(toolCall.id, html`<forge-ai-mcp-app .toolCall=${toolCall}></forge-ai-mcp-app>`);
|
|
202
|
+
}
|
|
176
203
|
const toolDefinition = this.tools?.get(toolCall.name);
|
|
177
204
|
return html`<forge-ai-chatbot-tool-call
|
|
178
205
|
.toolCall=${toolCall}
|
|
@@ -231,6 +258,9 @@ messages_get = function() {
|
|
|
231
258
|
return true;
|
|
232
259
|
}
|
|
233
260
|
if (item.type === "toolCall") {
|
|
261
|
+
if (rendersAsMcpAppWidget(item.data)) {
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
234
264
|
const toolDef = this.tools?.get(item.data.name);
|
|
235
265
|
return !!toolDef?.renderer;
|
|
236
266
|
}
|
|
@@ -318,6 +348,9 @@ __decorateClass([
|
|
|
318
348
|
__decorateClass([
|
|
319
349
|
query(".message-thread")
|
|
320
350
|
], AiMessageThreadComponent.prototype, "_messageThreadContainer", 2);
|
|
351
|
+
__decorateClass([
|
|
352
|
+
query(".message-thread-content")
|
|
353
|
+
], AiMessageThreadComponent.prototype, "_messageThreadContent", 2);
|
|
321
354
|
AiMessageThreadComponent = __decorateClass([
|
|
322
355
|
customElement(AiMessageThreadComponentTagName)
|
|
323
356
|
], AiMessageThreadComponent);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { LitElement, PropertyValues, nothing, TemplateResult, CSSResult } from 'lit';
|
|
2
|
+
declare global {
|
|
3
|
+
interface HTMLElementTagNameMap {
|
|
4
|
+
'forge-ai-steps': AiStepsComponent;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export declare const AiStepsComponentTagName: keyof HTMLElementTagNameMap;
|
|
8
|
+
/** Lifecycle state of an individual step. */
|
|
9
|
+
export type AiStepStatus = 'pending' | 'running' | 'complete';
|
|
10
|
+
/**
|
|
11
|
+
* A single step in the timeline. Every field is supplied by the agent — the component derives no
|
|
12
|
+
* labels of its own and makes no assumption about how the agent names its work.
|
|
13
|
+
*/
|
|
14
|
+
export interface AiStep {
|
|
15
|
+
/**
|
|
16
|
+
* Agent-provided label for the step, e.g. `'Filtered by \`crime_category\`'`. Rendered as inline
|
|
17
|
+
* markdown, so the agent decides which part of its own label to emphasize. Literal `*`, `_` and
|
|
18
|
+
* `` ` `` characters need escaping.
|
|
19
|
+
*/
|
|
20
|
+
label: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional agent-provided elaboration, rendered as a detail card beneath the label. Also rendered
|
|
23
|
+
* as inline markdown.
|
|
24
|
+
*/
|
|
25
|
+
detail?: string;
|
|
26
|
+
/** Lifecycle state of this step. Defaults to `'complete'` when omitted. */
|
|
27
|
+
status?: AiStepStatus;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @tag forge-ai-steps
|
|
31
|
+
*
|
|
32
|
+
* @summary Expandable timeline summarizing the steps an agent took while producing a response.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* Collapsed, it shows a step count and a summary of the first couple of step labels. When expanded,
|
|
36
|
+
* it lists each step as a row in a vertical timeline along with its status. Steps carrying a
|
|
37
|
+
* `detail` render as detail cards; steps without one render as a simple labeled row.
|
|
38
|
+
*
|
|
39
|
+
* Labels and details are rendered as sanitized inline markdown, so the agent controls its own
|
|
40
|
+
* emphasis — bold, italic, strikethrough, `code` and links — rather than the component or the
|
|
41
|
+
* consumer prescribing which part of a step matters.
|
|
42
|
+
*
|
|
43
|
+
* This is a presentational primitive: it renders whatever `steps` it is given and knows nothing
|
|
44
|
+
* about tool calls or tool definitions. `forge-ai-tool-steps` is the tool renderer that maps an
|
|
45
|
+
* agent's `displaySteps` tool call onto these properties.
|
|
46
|
+
*
|
|
47
|
+
* While `running` is `true` the timeline stays expanded and the summary row is hidden. When
|
|
48
|
+
* `running` flips back to `false` the timeline auto-collapses, leaving the summary row as the way
|
|
49
|
+
* back in. An element that mounts with `running` already `false` renders expanded, so static usage
|
|
50
|
+
* (a finished run, or a Storybook story) is readable without interaction.
|
|
51
|
+
*
|
|
52
|
+
* @property {AiStep[]} steps - The steps to render as timeline rows
|
|
53
|
+
* @property {boolean} running - Whether the run producing these steps is still in progress
|
|
54
|
+
*/
|
|
55
|
+
export declare class AiStepsComponent extends LitElement {
|
|
56
|
+
#private;
|
|
57
|
+
static styles: CSSResult;
|
|
58
|
+
steps: AiStep[];
|
|
59
|
+
/**
|
|
60
|
+
* Whether the run producing these steps is still in progress. While `true` the timeline is held
|
|
61
|
+
* open and the summary row is hidden; the transition back to `false` collapses the timeline.
|
|
62
|
+
*/
|
|
63
|
+
running: boolean;
|
|
64
|
+
private _expanded;
|
|
65
|
+
willUpdate(changedProperties: PropertyValues<this>): void;
|
|
66
|
+
render(): TemplateResult | typeof nothing;
|
|
67
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, html, nothing } from "lit";
|
|
2
|
+
import { property, state, customElement } from "lit/decorators.js";
|
|
3
|
+
import { join } from "lit/directives/join.js";
|
|
4
|
+
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
5
|
+
import { when } from "lit/directives/when.js";
|
|
6
|
+
import { renderInlineMarkdown } from "../utils/markdown.mjs";
|
|
7
|
+
import styles from "./ai-steps.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 _chevronIcon, _rowMarker, _AiStepsComponent_instances, renderInline_fn, summaryLabel_get, toggle_fn, renderNoDetailStep_fn, renderStep_fn, isExpanded_get, steps_get, stepsSummary_get, stepsCountLabel_get;
|
|
26
|
+
const AiStepsComponentTagName = "forge-ai-steps";
|
|
27
|
+
const MAX_DETAIL_LENGTH = 2e3;
|
|
28
|
+
let AiStepsComponent = class extends LitElement {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
__privateAdd(this, _AiStepsComponent_instances);
|
|
32
|
+
this.steps = [];
|
|
33
|
+
this.running = false;
|
|
34
|
+
this._expanded = true;
|
|
35
|
+
__privateAdd(this, _chevronIcon, html`
|
|
36
|
+
<svg
|
|
37
|
+
class="chevron"
|
|
38
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
height="20"
|
|
41
|
+
width="20"
|
|
42
|
+
fill="currentColor"
|
|
43
|
+
aria-hidden="true">
|
|
44
|
+
<path d="M7.41 8.59 12 13.17l4.59-4.58L18 10l-6 6-6-6z" />
|
|
45
|
+
</svg>
|
|
46
|
+
`);
|
|
47
|
+
__privateAdd(this, _rowMarker, html`<span class="row-marker"></span>`);
|
|
48
|
+
}
|
|
49
|
+
willUpdate(changedProperties) {
|
|
50
|
+
if (changedProperties.has("running") && !this.running && changedProperties.get("running") === true) {
|
|
51
|
+
this._expanded = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
render() {
|
|
55
|
+
if (this.steps.length === 0) {
|
|
56
|
+
return nothing;
|
|
57
|
+
}
|
|
58
|
+
return html`
|
|
59
|
+
<div class="steps">
|
|
60
|
+
<div class="steps-count">${__privateGet(this, _AiStepsComponent_instances, stepsCountLabel_get)}</div>
|
|
61
|
+
${__privateGet(this, _AiStepsComponent_instances, stepsSummary_get)} ${__privateGet(this, _AiStepsComponent_instances, steps_get)}
|
|
62
|
+
</div>
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
_chevronIcon = /* @__PURE__ */ new WeakMap();
|
|
67
|
+
_rowMarker = /* @__PURE__ */ new WeakMap();
|
|
68
|
+
_AiStepsComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
69
|
+
renderInline_fn = function(value) {
|
|
70
|
+
return html`${unsafeHTML(renderInlineMarkdown(value))}`;
|
|
71
|
+
};
|
|
72
|
+
summaryLabel_get = function() {
|
|
73
|
+
const stepLabels = this.steps.map((step) => html`<span>${__privateMethod(this, _AiStepsComponent_instances, renderInline_fn).call(this, step.label)}</span>`);
|
|
74
|
+
const visibleLabels = stepLabels.slice(0, 2);
|
|
75
|
+
const remaining = stepLabels.length - visibleLabels.length;
|
|
76
|
+
return remaining > 0 ? html`${join(visibleLabels, html`, `)} +${remaining} more` : html`${join(visibleLabels, html`, `)}`;
|
|
77
|
+
};
|
|
78
|
+
toggle_fn = function() {
|
|
79
|
+
this._expanded = !this._expanded;
|
|
80
|
+
};
|
|
81
|
+
renderNoDetailStep_fn = function(step) {
|
|
82
|
+
return html`
|
|
83
|
+
<div class="timeline-row" data-status=${step.status ?? "complete"}>
|
|
84
|
+
<div class="row-header">
|
|
85
|
+
${__privateGet(this, _rowMarker)}
|
|
86
|
+
<span class="row-label">
|
|
87
|
+
<span class="row-name">${__privateMethod(this, _AiStepsComponent_instances, renderInline_fn).call(this, step.label)}</span>
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
`;
|
|
92
|
+
};
|
|
93
|
+
renderStep_fn = function(step) {
|
|
94
|
+
const detail = step.detail;
|
|
95
|
+
if (!detail) {
|
|
96
|
+
return __privateMethod(this, _AiStepsComponent_instances, renderNoDetailStep_fn).call(this, step);
|
|
97
|
+
}
|
|
98
|
+
const truncated = detail.length > MAX_DETAIL_LENGTH ? `${detail.slice(0, MAX_DETAIL_LENGTH)}… (truncated)` : detail;
|
|
99
|
+
return html`
|
|
100
|
+
<div class="timeline-row" data-status=${step.status ?? "complete"}>
|
|
101
|
+
<div class="row-header">
|
|
102
|
+
${__privateGet(this, _rowMarker)}
|
|
103
|
+
<div class="step-card">
|
|
104
|
+
<span class="step-card-title">${__privateMethod(this, _AiStepsComponent_instances, renderInline_fn).call(this, step.label)}</span>
|
|
105
|
+
<div class="step-card-body">
|
|
106
|
+
<div class="step-card-result">${__privateMethod(this, _AiStepsComponent_instances, renderInline_fn).call(this, truncated)}</div>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
`;
|
|
112
|
+
};
|
|
113
|
+
isExpanded_get = function() {
|
|
114
|
+
return this.running || this._expanded;
|
|
115
|
+
};
|
|
116
|
+
steps_get = function() {
|
|
117
|
+
return html`
|
|
118
|
+
<div
|
|
119
|
+
id="timeline-content"
|
|
120
|
+
class="timeline ${__privateGet(this, _AiStepsComponent_instances, isExpanded_get) ? "expanded" : ""}"
|
|
121
|
+
aria-hidden=${__privateGet(this, _AiStepsComponent_instances, isExpanded_get) ? "false" : "true"}>
|
|
122
|
+
<div class="timeline-content">${this.steps.map((step) => __privateMethod(this, _AiStepsComponent_instances, renderStep_fn).call(this, step))}</div>
|
|
123
|
+
</div>
|
|
124
|
+
`;
|
|
125
|
+
};
|
|
126
|
+
stepsSummary_get = function() {
|
|
127
|
+
return when(
|
|
128
|
+
!this.running,
|
|
129
|
+
() => html`
|
|
130
|
+
<button
|
|
131
|
+
class="summary"
|
|
132
|
+
type="button"
|
|
133
|
+
aria-expanded=${this._expanded}
|
|
134
|
+
aria-controls="timeline-content"
|
|
135
|
+
@click=${__privateMethod(this, _AiStepsComponent_instances, toggle_fn)}>
|
|
136
|
+
${__privateGet(this, _chevronIcon)}
|
|
137
|
+
<span class="status-text">${__privateGet(this, _AiStepsComponent_instances, summaryLabel_get)}</span>
|
|
138
|
+
<span class="focus-indicator"></span>
|
|
139
|
+
</button>
|
|
140
|
+
`
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
stepsCountLabel_get = function() {
|
|
144
|
+
const count = this.steps.length;
|
|
145
|
+
return `${count} step${count === 1 ? "" : "s"}`;
|
|
146
|
+
};
|
|
147
|
+
AiStepsComponent.styles = unsafeCSS(styles);
|
|
148
|
+
__decorateClass([
|
|
149
|
+
property({ attribute: false })
|
|
150
|
+
], AiStepsComponent.prototype, "steps", 2);
|
|
151
|
+
__decorateClass([
|
|
152
|
+
property({ type: Boolean, reflect: true })
|
|
153
|
+
], AiStepsComponent.prototype, "running", 2);
|
|
154
|
+
__decorateClass([
|
|
155
|
+
state()
|
|
156
|
+
], AiStepsComponent.prototype, "_expanded", 2);
|
|
157
|
+
AiStepsComponent = __decorateClass([
|
|
158
|
+
customElement(AiStepsComponentTagName)
|
|
159
|
+
], AiStepsComponent);
|
|
160
|
+
export {
|
|
161
|
+
AiStepsComponent,
|
|
162
|
+
AiStepsComponentTagName
|
|
163
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const styles = '/* prettier-ignore */\n@keyframes fadein {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\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:host {\n display: flex;\n flex-direction: column;\n gap: var(--forge-spacing-small, 12px);\n}\n\n.summary {\n display: flex;\n align-items: center;\n gap: var(--forge-spacing-xsmall, 8px);\n padding-block: var(--forge-spacing-xxsmall, 4px);\n padding-inline: var(--forge-spacing-xsmall, 8px);\n border: none;\n background-color: var(--forge-theme-surface-container-minimum, #f5f5f5);\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n cursor: pointer;\n text-align: start;\n position: relative;\n outline: none;\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.summary::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.summary:hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n.summary: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.status-text {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n}\n\n.chevron {\n flex-shrink: 0;\n transform: rotate(-90deg);\n transition: transform var(--forge-animation-duration-short4, 200ms) var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n.summary[aria-expanded=true] .chevron {\n transform: rotate(0deg);\n}\n\n.focus-indicator {\n position: absolute;\n display: none;\n}\n\n:host .summary:focus .focus-indicator {\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 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-inward-grow, forge-focus-indicator-inward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) - var(--_focus-indicator-inward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) - var(--_focus-indicator-inward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) - var(--_focus-indicator-inward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) - var(--_focus-indicator-inward-offset));\n border: var(--_focus-indicator-width) solid currentColor;\n inset: var(--_focus-indicator-inward-offset);\n}\n:host .summary:focus .focus-indicator::before {\n content: "";\n}\n:host .summary:focus .focus-indicator {\n display: block;\n --forge-focus-indicator-shape: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n}\n\n.steps {\n display: flex;\n flex-direction: column;\n gap: var(--forge-spacing-xsmall, 8px);\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n font-size: var(--forge-ai-markdown-font-size, 0.875rem);\n line-height: var(--forge-ai-markdown-line-height, 1.5rem);\n color: var(--forge-theme-on-surface, #000000);\n overflow-wrap: break-word;\n}\n.steps h1,\n.steps h2,\n.steps h3,\n.steps h4,\n.steps h5,\n.steps h6 {\n margin: 1.75rem 0 var(--forge-spacing-small, 12px);\n}\n.steps strong {\n font-weight: 500;\n}\n.steps a {\n color: var(--forge-theme-primary, #3f51b5);\n}\n.steps hr {\n border: none;\n border-top: 1px solid var(--forge-theme-outline, #e0e0e0);\n}\n.steps code {\n color: var(--forge-theme-on-surface-container-low, #000000);\n background-color: var(--forge-theme-surface-container-low, #ebebeb);\n border-radius: calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1));\n padding: var(--forge-spacing-xxxsmall, 2px) var(--forge-spacing-xxsmall, 4px);\n font-size: 0.75em;\n}\n.steps pre {\n border: 1px solid var(--forge-theme-outline, #e0e0e0);\n border-radius: calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1));\n margin: 0;\n max-width: 100%;\n overflow-x: auto;\n}\n.steps pre:focus-visible {\n outline: 2px solid var(--forge-theme-primary, #3f51b5);\n outline-offset: 2px;\n}\n.steps pre code {\n display: block;\n padding: var(--forge-spacing-xsmall, 8px) var(--forge-spacing-small, 12px);\n color: var(--forge-theme-on-surface-container-minimum, #000000);\n background: var(--forge-theme-surface-container-minimum, #f5f5f5);\n white-space: pre;\n}\n.steps [data-scroll-region=table] {\n max-width: 100%;\n overflow-x: auto;\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n margin-block: var(--forge-spacing-medium, 16px);\n}\n.steps [data-scroll-region=table]:focus-visible {\n outline: 2px solid var(--forge-theme-primary, #3f51b5);\n outline-offset: 2px;\n}\n.steps [data-scroll-region=table] table {\n margin-block: 0;\n}\n.steps table {\n width: 100%;\n border-spacing: 0;\n background-color: var(--forge-theme-surface, #ffffff);\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n overflow: hidden;\n margin-block: var(--forge-spacing-medium, 16px);\n}\n.steps table thead {\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n font-weight: bold;\n text-align: left;\n font-size: calc(var(--forge-typography-font-size, 1rem) * 0.75);\n box-sizing: border-box;\n}\n.steps table tr {\n height: 36px;\n height: 32px;\n}\n.steps table tr:nth-child(even) {\n background-color: var(--forge-theme-surface-dim, #fafafa);\n}\n.steps table tr:last-child td {\n border-bottom: none;\n}\n.steps table th,\n.steps table td {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.75)));\n font-weight: var(--forge-typography-label1-font-weight, 400);\n line-height: var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-label1-text-transform, inherit);\n text-decoration: var(--forge-typography-label1-text-decoration, inherit);\n padding-block: var(--forge-spacing-xsmall, 8px);\n padding-inline-start: var(--forge-spacing-xsmall, 8px);\n padding-inline-end: var(--forge-spacing-medium, 16px);\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: var(--forge-theme-outline, #e0e0e0);\n}\n.steps table th {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label2-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label2-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.8125)));\n font-weight: var(--forge-typography-label2-font-weight, 400);\n line-height: var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label2-letter-spacing, 0.0096153846em);\n text-transform: var(--forge-typography-label2-text-transform, inherit);\n text-decoration: var(--forge-typography-label2-text-decoration, inherit);\n font-weight: 600;\n}\n.steps > p:has(+ ol),\n.steps > p:has(+ ul) {\n margin-block-end: var(--forge-spacing-small, 12px);\n}\n.steps > ul {\n list-style-type: disc;\n padding-inline-start: 1.6875rem;\n}\n.steps > ol {\n padding-inline-start: 1.75rem;\n}\n.steps > ol,\n.steps > ul {\n margin: var(--forge-spacing-xsmall, 8px) 0;\n margin-block-end: var(--forge-spacing-medium, 16px);\n}\n.steps > :first-child {\n margin-block-start: 0;\n}\n.steps > p {\n margin-block-end: var(--forge-spacing-medium, 16px);\n overflow-wrap: anywhere;\n}\n.steps > p:first-child {\n margin-block-start: 0;\n}\n.steps > p:last-child {\n margin-block-end: 0;\n}\n.steps-count {\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.timeline {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--forge-animation-duration-medium2, 300ms) var(--forge-animation-easing-decelerate, cubic-bezier(0, 0, 0, 1));\n}\n.timeline.expanded {\n grid-template-rows: 1fr;\n}\n\n.timeline-content {\n overflow: hidden;\n min-height: 0;\n padding-inline-start: var(--forge-spacing-small, 12px);\n}\n\n.timeline-row {\n position: relative;\n padding-inline-start: var(--forge-spacing-large, 24px);\n padding-block-end: var(--forge-spacing-medium, 16px);\n}\n.timeline-row::before {\n content: "";\n position: absolute;\n inset-block-start: calc((var(--forge-spacing-medium-large, 20px) - var(--forge-spacing-xsmall, 8px)) / 2);\n inset-block-end: calc(-1 * var(--forge-spacing-xsmall, 8px));\n inset-inline-start: calc((var(--forge-spacing-medium-large, 20px) - 1px) / 2);\n width: 1px;\n background-color: var(--forge-theme-outline, #e0e0e0);\n}\n.timeline-row:last-child::before {\n display: none;\n}\n\n.row-header {\n display: flex;\n align-items: flex-start;\n gap: var(--forge-spacing-small, 12px);\n width: 100%;\n min-height: var(--forge-spacing-medium-large, 20px);\n margin-inline-start: calc(-1 * var(--forge-spacing-large, 24px));\n}\n\n.row-marker {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--forge-spacing-medium-large, 20px);\n height: var(--forge-spacing-medium-large, 20px);\n border-radius: calc(var(--forge-shape-round, 50%) * var(--forge-shape-factor, 1));\n}\n.row-marker::before {\n content: "";\n flex-shrink: 0;\n width: var(--forge-spacing-xsmall, 8px);\n height: var(--forge-spacing-xsmall, 8px);\n border-radius: calc(var(--forge-shape-round, 50%) * var(--forge-shape-factor, 1));\n background-color: currentColor;\n position: relative;\n z-index: 1;\n}\n\n.row-label {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n gap: var(--forge-spacing-xxxsmall, 2px);\n}\n\n.row-name {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n display: flex;\n align-items: center;\n gap: var(--forge-spacing-xsmall, 8px);\n line-height: normal;\n font-weight: 500;\n color: var(--forge-theme-text-high, rgba(0, 0, 0, 0.87));\n}\n\n.step-card {\n width: 100%;\n}\n.step-card-title {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n font-weight: 700;\n}\n.step-card-result {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n}\n\n.row-name strong,\n.step-card-title strong {\n font-weight: 700;\n}';
|
|
2
|
+
export {
|
|
3
|
+
styles as default
|
|
4
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ai-steps';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, nothing, PropertyValues, TemplateResult, CSSResult } from 'lit';
|
|
2
|
-
import { ToolCall,
|
|
2
|
+
import { ToolCall, AnyToolDefinition } from '../ai-chatbot/types.js';
|
|
3
3
|
declare global {
|
|
4
4
|
interface HTMLElementTagNameMap {
|
|
5
5
|
'forge-ai-tool-call-indicator': AiToolCallIndicatorComponent;
|
|
@@ -20,7 +20,7 @@ export declare class AiToolCallIndicatorComponent extends LitElement {
|
|
|
20
20
|
#private;
|
|
21
21
|
static styles: CSSResult;
|
|
22
22
|
toolCalls: ToolCall[];
|
|
23
|
-
tools?: Map<string,
|
|
23
|
+
tools?: Map<string, AnyToolDefinition>;
|
|
24
24
|
debugMode: boolean;
|
|
25
25
|
private _expanded;
|
|
26
26
|
private _expandedRows;
|
|
@@ -218,7 +218,7 @@ highlightJson_fn = function(value) {
|
|
|
218
218
|
return html`${unsafeHTML(highlighted)}`;
|
|
219
219
|
};
|
|
220
220
|
statusMarker_fn = function(toolCall) {
|
|
221
|
-
if (toolCall.status === "error") {
|
|
221
|
+
if (toolCall.status === "error" || toolCall.status === "cancelled") {
|
|
222
222
|
return html`<span class="row-marker row-marker--error">${__privateGet(this, _errorIcon)}</span>`;
|
|
223
223
|
}
|
|
224
224
|
if (isToolCallSettled(toolCall, this.tools?.get(toolCall.name))) {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { AnyToolDefinition, ChatMessage, ToolCall } from '../ai-chatbot/types.js';
|
|
3
|
+
import { ForgeAiCanvasCloseRequestEventData, ForgeAiCanvasOpenRequestEventData } from '../ai-chatbot/tool-canvas.js';
|
|
4
|
+
export interface OpenCanvasOptions {
|
|
5
|
+
/** Identifies the artifact; tool-driven opens use the tool call id. */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** Overrides `canvasTitle` while this content is shown. */
|
|
8
|
+
title?: string;
|
|
9
|
+
/** Content mounted in the canvas body. Omit to show the `canvas` slot instead. */
|
|
10
|
+
content?: Node;
|
|
11
|
+
}
|
|
12
|
+
export interface CanvasOpenEventData {
|
|
13
|
+
id?: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
/** Present when the canvas was opened for a tool call. */
|
|
16
|
+
toolCall?: ToolCall;
|
|
17
|
+
}
|
|
18
|
+
/** `auto`: opened by `canvas.open: 'auto'` rather than a user or API request. */
|
|
19
|
+
export type CanvasOpenReason = 'auto' | 'request';
|
|
20
|
+
export interface CanvasContent {
|
|
21
|
+
id?: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
node?: Node;
|
|
24
|
+
toolCall?: ToolCall;
|
|
25
|
+
/** Set for tool-driven content so it can follow the tool call as it updates. */
|
|
26
|
+
toolDefinition?: AnyToolDefinition;
|
|
27
|
+
/** Title supplied with the open request; otherwise the title is re-derived from the tool call. */
|
|
28
|
+
titleOverride?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CanvasControllerConfig {
|
|
31
|
+
/** Cancelable event dispatched on the host before the canvas opens or swaps content. */
|
|
32
|
+
openEvent: string;
|
|
33
|
+
/** Event dispatched on the host when the canvas closes; cancelable except when the host forces it. */
|
|
34
|
+
closeEvent: string;
|
|
35
|
+
dispatchHostEvent: (config: {
|
|
36
|
+
type: string;
|
|
37
|
+
detail?: unknown;
|
|
38
|
+
cancelable?: boolean;
|
|
39
|
+
}) => CustomEvent;
|
|
40
|
+
getToolCalls: () => ToolCall[];
|
|
41
|
+
getTools: () => Map<string, AnyToolDefinition>;
|
|
42
|
+
/** Whether the host can show the canvas right now. Defaults to always. */
|
|
43
|
+
canOpen?: () => boolean;
|
|
44
|
+
/** Called once the canvas has gone from closed to open, not when its content is swapped. */
|
|
45
|
+
onOpen?: (config: {
|
|
46
|
+
reason: CanvasOpenReason;
|
|
47
|
+
}) => void;
|
|
48
|
+
/** Called after the canvas is hidden for any reason. */
|
|
49
|
+
onClose?: () => void;
|
|
50
|
+
/** Called when the requested tool call is already showing, so the host can draw attention to it. */
|
|
51
|
+
onRefocus?: () => void;
|
|
52
|
+
/** Resolves once the host's collapse presentation has finished; hidden content is released after it. */
|
|
53
|
+
collapsed?: () => Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Owns the artifact canvas state shared by every chatbot form factor: what is shown, the cancelable
|
|
57
|
+
* open/close events, tool call tracking, auto-open, and the `canvas` controls injected into renderers.
|
|
58
|
+
* The host decides how that state is presented (a side panel, a modal, ...).
|
|
59
|
+
*/
|
|
60
|
+
export declare class CanvasController implements ReactiveController {
|
|
61
|
+
#private;
|
|
62
|
+
constructor(host: ReactiveControllerHost & HTMLElement, config: CanvasControllerConfig);
|
|
63
|
+
hostConnected(): void;
|
|
64
|
+
get isOpen(): boolean;
|
|
65
|
+
get content(): CanvasContent | null;
|
|
66
|
+
open(options?: OpenCanvasOptions): boolean;
|
|
67
|
+
/** Closes the canvas. Returns false if it was not open or the close event was prevented. */
|
|
68
|
+
close(): boolean;
|
|
69
|
+
/** Closes without asking, for when the host can no longer show the canvas (e.g. it left its conversation view). */
|
|
70
|
+
forceClose(): void;
|
|
71
|
+
/** Forgets the canvas entirely, for when the thread it belonged to is gone. */
|
|
72
|
+
reset(): void;
|
|
73
|
+
/** Tool calls restored from history are marked as seen so loading a thread never auto-opens the canvas. */
|
|
74
|
+
markSeen(messages: ChatMessage[]): void;
|
|
75
|
+
readonly handleOpenRequest: (evt: CustomEvent<ForgeAiCanvasOpenRequestEventData>) => void;
|
|
76
|
+
readonly handleCloseRequest: (evt: CustomEvent<ForgeAiCanvasCloseRequestEventData>) => void;
|
|
77
|
+
/** The tool call object is replaced on every args or status update, so open content follows it by id. */
|
|
78
|
+
syncToolCall(): void;
|
|
79
|
+
/** Opens tools configured with `canvas.open: 'auto'` once their renderer shows. Call after render, not during it. */
|
|
80
|
+
autoOpenPending(): void;
|
|
81
|
+
}
|