@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.
Files changed (88) hide show
  1. package/custom-elements.json +4501 -1781
  2. package/dist/ai-artifact-card/ai-artifact-card.d.ts +75 -0
  3. package/dist/ai-artifact-card/ai-artifact-card.mjs +142 -0
  4. package/dist/ai-artifact-card/ai-artifact-card.scss.mjs +283 -0
  5. package/dist/ai-artifact-card/index.d.ts +1 -0
  6. package/dist/ai-artifact-card/index.mjs +5 -0
  7. package/dist/ai-artifact-card-group/ai-artifact-card-group.d.ts +57 -0
  8. package/dist/ai-artifact-card-group/ai-artifact-card-group.mjs +137 -0
  9. package/dist/ai-artifact-card-group/ai-artifact-card-group.scss.mjs +173 -0
  10. package/dist/ai-artifact-card-group/index.d.ts +1 -0
  11. package/dist/ai-artifact-card-group/index.mjs +5 -0
  12. package/dist/ai-assistant-response/ai-assistant-response.d.ts +2 -2
  13. package/dist/ai-assistant-response/ai-assistant-response.mjs +26 -2
  14. package/dist/ai-canvas/ai-canvas.d.ts +43 -0
  15. package/dist/ai-canvas/ai-canvas.mjs +95 -0
  16. package/dist/ai-canvas/ai-canvas.scss.mjs +4 -0
  17. package/dist/ai-canvas/index.d.ts +1 -0
  18. package/dist/ai-canvas/index.mjs +5 -0
  19. package/dist/ai-chatbot/ag-ui-adapter.d.ts +2 -2
  20. package/dist/ai-chatbot/ag-ui-adapter.mjs +1 -1
  21. package/dist/ai-chatbot/agent-adapter.d.ts +111 -4
  22. package/dist/ai-chatbot/agent-adapter.mjs +22 -0
  23. package/dist/ai-chatbot/agent-runner.d.ts +2 -2
  24. package/dist/ai-chatbot/ai-chatbot-base.d.ts +29 -2
  25. package/dist/ai-chatbot/ai-chatbot-base.mjs +147 -3
  26. package/dist/ai-chatbot/ai-chatbot-tool-call.d.ts +2 -2
  27. package/dist/ai-chatbot/ai-chatbot-tool-call.mjs +88 -10
  28. package/dist/ai-chatbot/ai-chatbot.d.ts +24 -1
  29. package/dist/ai-chatbot/ai-chatbot.mjs +102 -2
  30. package/dist/ai-chatbot/ai-chatbot.scss.mjs +1 -1
  31. package/dist/ai-chatbot/create-tool-renderer.d.ts +5 -5
  32. package/dist/ai-chatbot/index.d.ts +3 -2
  33. package/dist/ai-chatbot/index.mjs +3 -0
  34. package/dist/ai-chatbot/message-state-controller.d.ts +10 -1
  35. package/dist/ai-chatbot/message-state-controller.mjs +78 -20
  36. package/dist/ai-chatbot/tool-canvas.d.ts +60 -0
  37. package/dist/ai-chatbot/tool-canvas.mjs +128 -0
  38. package/dist/ai-chatbot/types.d.ts +325 -15
  39. package/dist/ai-chatbot/utils.d.ts +8 -3
  40. package/dist/ai-chatbot/utils.mjs +7 -1
  41. package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +40 -2
  42. package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +224 -7
  43. package/dist/ai-chatbot-launcher/ai-chatbot-launcher.scss.mjs +1 -1
  44. package/dist/ai-embedded-chat/ai-embedded-chat.mjs +1 -0
  45. package/dist/ai-message-thread/ai-message-thread.d.ts +3 -2
  46. package/dist/ai-message-thread/ai-message-thread.mjs +36 -3
  47. package/dist/ai-steps/ai-steps.d.ts +67 -0
  48. package/dist/ai-steps/ai-steps.mjs +163 -0
  49. package/dist/ai-steps/ai-steps.scss.mjs +4 -0
  50. package/dist/ai-steps/index.d.ts +1 -0
  51. package/dist/ai-steps/index.mjs +5 -0
  52. package/dist/ai-tool-call-indicator/ai-tool-call-indicator.d.ts +2 -2
  53. package/dist/ai-tool-call-indicator/ai-tool-call-indicator.mjs +1 -1
  54. package/dist/core/canvas-controller.d.ts +81 -0
  55. package/dist/core/canvas-controller.mjs +221 -0
  56. package/dist/core/chatbot-core-controller.d.ts +4 -2
  57. package/dist/core/chatbot-core-controller.mjs +121 -4
  58. package/dist/core/index.d.ts +2 -1
  59. package/dist/core/index.mjs +2 -0
  60. package/dist/core/resize-controller.d.ts +5 -0
  61. package/dist/core/resize-controller.mjs +7 -5
  62. package/dist/index.d.ts +4 -0
  63. package/dist/index.mjs +15 -0
  64. package/dist/tools/ai-data-table/ai-data-table-definition.mjs +1 -0
  65. package/dist/tools/ai-mcp-app/ai-mcp-app.d.ts +70 -0
  66. package/dist/tools/ai-mcp-app/ai-mcp-app.mjs +589 -0
  67. package/dist/tools/ai-mcp-app/ai-mcp-app.scss.mjs +4 -0
  68. package/dist/tools/ai-mcp-app/index.d.ts +3 -0
  69. package/dist/tools/ai-mcp-app/index.mjs +6 -0
  70. package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.d.ts +60 -0
  71. package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.mjs +147 -0
  72. package/dist/tools/ai-mcp-app/mcp-app-bridge-types.d.ts +124 -0
  73. package/dist/tools/ai-mcp-app/mcp-app-bridge.d.ts +41 -0
  74. package/dist/tools/ai-mcp-app/mcp-app-bridge.mjs +293 -0
  75. package/dist/tools/ai-mcp-app/mcp-app-context.d.ts +46 -0
  76. package/dist/tools/ai-mcp-app/mcp-app-context.mjs +5 -0
  77. package/dist/tools/ai-steps/ai-steps-definition.d.ts +2 -0
  78. package/dist/tools/ai-steps/ai-steps-definition.mjs +51 -0
  79. package/dist/tools/ai-steps/ai-steps.d.ts +28 -0
  80. package/dist/tools/ai-steps/ai-steps.mjs +49 -0
  81. package/dist/tools/ai-steps/ai-steps.scss.mjs +4 -0
  82. package/dist/tools/ai-steps/index.d.ts +2 -0
  83. package/dist/tools/ai-steps/index.mjs +6 -0
  84. package/dist/tools/index.d.ts +1 -0
  85. package/dist/tools/index.mjs +5 -1
  86. package/dist/utils/inert-outside.d.ts +7 -0
  87. package/dist/utils/inert-outside.mjs +28 -0
  88. package/package.json +4 -1
@@ -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).toolCall = this.toolCall;
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
- __privateMethod(this, _AiChatbotToolCallComponent_instances, replaceRenderedElement_fn).call(this, container, renderer.render(this.toolCall));
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 renderer = this.toolDefinition?.renderer;
75
- if (!renderer || !__privateGet(this, _AiChatbotToolCallComponent_instances, shouldRenderCustom_get)) {
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
  /**
@@ -3,14 +3,17 @@ import { property, customElement } from "lit/decorators.js";
3
3
  import { createRef, ref } from "lit/directives/ref.js";
4
4
  import { when } from "lit/directives/when.js";
5
5
  import { AiChatbotBase } from "./ai-chatbot-base.mjs";
6
+ import { CanvasController } from "../core/canvas-controller.mjs";
6
7
  import { forwardCancelableEvent } from "../utils.mjs";
7
8
  import "../ai-attachment/ai-attachment.mjs";
9
+ import "../ai-canvas/ai-canvas.mjs";
8
10
  import "../ai-chat-header/ai-chat-header.mjs";
9
11
  import "../ai-chat-interface/ai-chat-interface.mjs";
10
12
  import "../ai-context-chip/ai-context-chip.mjs";
11
13
  import "../ai-conversations-panel/ai-conversations-panel.mjs";
12
14
  import "../ai-file-picker/ai-file-picker.mjs";
13
15
  import "../ai-message-thread/ai-message-thread.mjs";
16
+ import "../ai-modal/ai-modal.mjs";
14
17
  import "../ai-prompt/ai-prompt.mjs";
15
18
  import "../ai-spinner/ai-spinner.mjs";
16
19
  import "../ai-suggestions/ai-suggestions.mjs";
@@ -33,7 +36,7 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
33
36
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
34
37
  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);
35
38
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
36
- var _chatInterfaceRef, _headerRef, _conversationsPanelRef, _conversationsDialogRef, _boundEscapeHandler, _AiChatbotComponent_instances, handleHeaderExpand_fn, handleHeaderMinimize_fn, handleHeaderClear_fn, handleHeaderInfo_fn, handleConversationsDialogClose_fn, handleEscapeKey_fn, handleBackdropClick_fn, handleConversationsToggle_fn, handleThreadSelect_fn, handleThreadRetry_fn, handleNewChat_fn, handlePanelClose_fn, _handleThreadSearch, _handleThreadLoadMore, _handleThreadRename, _handleThreadDelete, promptSlot_get, messageThread_get;
39
+ var _canvasModalRef, _canvasRef, _canvas, _chatInterfaceRef, _headerRef, _conversationsPanelRef, _conversationsDialogRef, _boundEscapeHandler, _AiChatbotComponent_instances, handleHeaderExpand_fn, handleHeaderMinimize_fn, handleHeaderClear_fn, handleHeaderInfo_fn, syncCanvasModal_fn, handleCanvasModalClose_fn, canvasModal_get, handleCanvasCloseClick_fn, handleConversationsDialogClose_fn, handleEscapeKey_fn, handleBackdropClick_fn, handleConversationsToggle_fn, handleThreadSelect_fn, handleThreadRetry_fn, handleNewChat_fn, handlePanelClose_fn, _handleThreadSearch, _handleThreadLoadMore, _handleThreadRename, _handleThreadDelete, promptSlot_get, messageThread_get;
37
40
  const AiChatbotComponentTagName = "forge-ai-chatbot";
38
41
  let AiChatbotComponent = class extends AiChatbotBase {
39
42
  constructor() {
@@ -50,6 +53,18 @@ let AiChatbotComponent = class extends AiChatbotBase {
50
53
  this.showThreadDelete = false;
51
54
  this.selectedThreadId = null;
52
55
  this.threadsLoading = false;
56
+ __privateAdd(this, _canvasModalRef, createRef());
57
+ __privateAdd(this, _canvasRef, createRef());
58
+ __privateAdd(this, _canvas, new CanvasController(this, {
59
+ openEvent: "forge-ai-chatbot-canvas-open",
60
+ closeEvent: "forge-ai-chatbot-canvas-close",
61
+ dispatchHostEvent: (config) => this._dispatchHostEvent(config),
62
+ getToolCalls: () => this._toolCalls,
63
+ getTools: () => this._tools,
64
+ // A modal opened while the chat is hidden (closed floating chat, collapsed sidebar) is invisible but still makes the page inert.
65
+ canOpen: () => this.checkVisibility() && this.getBoundingClientRect().width > 0,
66
+ onRefocus: () => __privateGet(this, _canvasRef).value?.focus()
67
+ }));
53
68
  __privateAdd(this, _chatInterfaceRef, createRef());
54
69
  this._messageThreadRef = createRef();
55
70
  this._promptRef = createRef();
@@ -89,6 +104,42 @@ let AiChatbotComponent = class extends AiChatbotBase {
89
104
  focus() {
90
105
  this._promptRef.value?.focus();
91
106
  }
107
+ willUpdate(changedProperties) {
108
+ super.willUpdate(changedProperties);
109
+ __privateGet(this, _canvas).syncToolCall();
110
+ }
111
+ // No `canvas.open: 'auto'` here: a modal popping over the chat mid-conversation is too disruptive, so only the launcher auto-opens.
112
+ updated(changedProperties) {
113
+ super.updated(changedProperties);
114
+ __privateMethod(this, _AiChatbotComponent_instances, syncCanvasModal_fn).call(this);
115
+ }
116
+ get canvasOpen() {
117
+ return __privateGet(this, _canvas).isOpen;
118
+ }
119
+ /**
120
+ * Opens the artifact canvas in a modal over the chatbot, or swaps its content if already open.
121
+ * Returns false when the open event is prevented.
122
+ */
123
+ openCanvas(options = {}) {
124
+ return __privateGet(this, _canvas).open(options);
125
+ }
126
+ /**
127
+ * Closes the artifact canvas. Returns false if it was not open or the close event was prevented.
128
+ */
129
+ closeCanvas() {
130
+ return __privateGet(this, _canvas).close();
131
+ }
132
+ clearMessages() {
133
+ if (super.clearMessages()) {
134
+ __privateGet(this, _canvas).reset();
135
+ return true;
136
+ }
137
+ return false;
138
+ }
139
+ setMessages(messages) {
140
+ __privateGet(this, _canvas).reset();
141
+ super.setMessages(messages);
142
+ }
92
143
  showConversations() {
93
144
  const dialog = __privateGet(this, _conversationsDialogRef).value;
94
145
  if (dialog && !dialog.open) {
@@ -121,6 +172,7 @@ let AiChatbotComponent = class extends AiChatbotBase {
121
172
  startNewChat() {
122
173
  super.startNewChat();
123
174
  this.selectedThreadId = null;
175
+ __privateGet(this, _canvas).reset();
124
176
  }
125
177
  toggleConversations() {
126
178
  if (this.conversationsOpen) {
@@ -131,7 +183,10 @@ let AiChatbotComponent = class extends AiChatbotBase {
131
183
  }
132
184
  render() {
133
185
  return html`
134
- <div class="chatbot-container">
186
+ <div
187
+ class="chatbot-container"
188
+ @forge-ai-canvas-open-request=${__privateGet(this, _canvas).handleOpenRequest}
189
+ @forge-ai-canvas-close-request=${__privateGet(this, _canvas).handleCloseRequest}>
135
190
  <forge-ai-chat-interface
136
191
  ${ref(__privateGet(this, _chatInterfaceRef))}
137
192
  role="region"
@@ -205,10 +260,14 @@ let AiChatbotComponent = class extends AiChatbotBase {
205
260
  </dialog>
206
261
  `
207
262
  )}
263
+ ${__privateGet(this, _AiChatbotComponent_instances, canvasModal_get)}
208
264
  </div>
209
265
  `;
210
266
  }
211
267
  };
268
+ _canvasModalRef = /* @__PURE__ */ new WeakMap();
269
+ _canvasRef = /* @__PURE__ */ new WeakMap();
270
+ _canvas = /* @__PURE__ */ new WeakMap();
212
271
  _chatInterfaceRef = /* @__PURE__ */ new WeakMap();
213
272
  _headerRef = /* @__PURE__ */ new WeakMap();
214
273
  _conversationsPanelRef = /* @__PURE__ */ new WeakMap();
@@ -227,6 +286,44 @@ handleHeaderClear_fn = function() {
227
286
  handleHeaderInfo_fn = function() {
228
287
  this._handleInfo();
229
288
  };
289
+ syncCanvasModal_fn = function() {
290
+ const modal = __privateGet(this, _canvasModalRef).value;
291
+ if (modal && modal.open !== __privateGet(this, _canvas).isOpen) {
292
+ modal.open = __privateGet(this, _canvas).isOpen;
293
+ }
294
+ };
295
+ handleCanvasModalClose_fn = function(evt) {
296
+ evt.stopPropagation();
297
+ if (evt.detail.reason === "programmatic" || !__privateGet(this, _canvas).isOpen) {
298
+ return;
299
+ }
300
+ if (!__privateGet(this, _canvas).close()) {
301
+ __privateMethod(this, _AiChatbotComponent_instances, syncCanvasModal_fn).call(this);
302
+ }
303
+ };
304
+ canvasModal_get = function() {
305
+ const title = __privateGet(this, _canvas).content?.title ?? this.canvasTitle ?? "";
306
+ return html`
307
+ <forge-ai-modal
308
+ ${ref(__privateGet(this, _canvasModalRef))}
309
+ class="canvas-modal"
310
+ label=${title || "Canvas"}
311
+ @forge-ai-modal-close=${__privateMethod(this, _AiChatbotComponent_instances, handleCanvasModalClose_fn)}>
312
+ <forge-ai-canvas
313
+ ${ref(__privateGet(this, _canvasRef))}
314
+ class="canvas"
315
+ .titleText=${title}
316
+ .headingLevel=${this.headingLevel}
317
+ @forge-ai-canvas-close=${__privateMethod(this, _AiChatbotComponent_instances, handleCanvasCloseClick_fn)}>
318
+ <slot name="canvas-actions" slot="actions"></slot>
319
+ ${__privateGet(this, _canvas).content?.node ?? html`<slot name="canvas"></slot>`}
320
+ </forge-ai-canvas>
321
+ </forge-ai-modal>
322
+ `;
323
+ };
324
+ handleCanvasCloseClick_fn = function() {
325
+ __privateGet(this, _canvas).close();
326
+ };
230
327
  handleConversationsDialogClose_fn = function() {
231
328
  window.removeEventListener("keydown", __privateGet(this, _boundEscapeHandler), { capture: true });
232
329
  this.conversationsOpen = false;
@@ -393,6 +490,9 @@ __decorateClass([
393
490
  __decorateClass([
394
491
  property({ type: String, attribute: "threads-error" })
395
492
  ], AiChatbotComponent.prototype, "threadsError", 2);
493
+ __decorateClass([
494
+ property({ attribute: "canvas-title" })
495
+ ], AiChatbotComponent.prototype, "canvasTitle", 2);
396
496
  AiChatbotComponent = __decorateClass([
397
497
  customElement(AiChatbotComponentTagName)
398
498
  ], AiChatbotComponent);
@@ -1,4 +1,4 @@
1
- const styles = '/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n@keyframes forge-dialog-zoom-in {\n from {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n to {\n opacity: 1;\n scale: 1;\n }\n}\n@keyframes forge-dialog-zoom-out {\n from {\n opacity: 1;\n scale: 1;\n }\n to {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n}\n@keyframes forge-dialog-fade-in {\n from {\n opacity: var(--_dialog-fade-opacity);\n }\n to {\n opacity: 1;\n }\n}\n@keyframes forge-dialog-fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: var(--_dialog-fade-opacity);\n }\n}\n@keyframes forge-dialog-slide-in {\n from {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n to {\n opacity: 1;\n translate: 0 0;\n }\n}\n@keyframes forge-dialog-slide-out {\n from {\n opacity: 1;\n translate: 0 0;\n }\n to {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog {\n --_dialog-background:var(--forge-dialog-background, var(--forge-theme-surface-bright, #ffffff));\n --_dialog-shape:var(--forge-dialog-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_dialog-elevation:var(--forge-dialog-elevation, 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12));\n --_dialog-spacing:var(--forge-dialog-spacing, auto);\n --_dialog-block-start-spacing:var(--forge-dialog-block-start-spacing, var(--_dialog-spacing));\n --_dialog-block-end-spacing:var(--forge-dialog-block-end-spacing, var(--_dialog-spacing));\n --_dialog-inline-start-spacing:var(--forge-dialog-inline-start-spacing, var(--_dialog-spacing));\n --_dialog-inline-end-spacing:var(--forge-dialog-inline-end-spacing, var(--_dialog-spacing));\n --_dialog-padding:var(--forge-dialog-padding, 0);\n --_dialog-width:var(--forge-dialog-width, fit-content);\n --_dialog-height:var(--forge-dialog-height, fit-content);\n --_dialog-min-width:var(--forge-dialog-min-width, 0);\n --_dialog-max-width:var(--forge-dialog-max-width, calc(100% - var(--forge-spacing-xxlarge, 48px)));\n --_dialog-min-height:var(--forge-dialog-min-height, 0);\n --_dialog-max-height:var(--forge-dialog-max-height, calc(100% - var(--forge-spacing-xxlarge, 48px)));\n --_dialog-z-index:var(--forge-dialog-z-index, var(--forge-z-index-dialog, 8));\n --_dialog-move-handle-color:var(--forge-dialog-move-handle-color, currentColor);\n --_dialog-move-handle-size:var(--forge-dialog-move-handle-size, 24px);\n --_dialog-move-handle-hover-cursor:var(--forge-dialog-move-handle-hover-cursor, grab);\n --_dialog-move-handle-active-cursor:var(--forge-dialog-move-handle-active-cursor, grabbing);\n --_dialog-move-handle-spacing:var(--forge-dialog-move-handle-spacing, calc(var(--forge-spacing-xxsmall, 4px) * -1) 0 0);\n --_dialog-move-transition-duration:var(--forge-dialog-move-transition-duration, var(--forge-animation-duration-short4, 200ms));\n --_dialog-move-transition-easing:var(--forge-dialog-move-transition-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_dialog-moving-opacity:var(--forge-dialog-moving-opacity, 0.54);\n --_dialog-enter-animation-duration:var(--forge-dialog-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-enter-animation-easing:var(--forge-dialog-enter-animation-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_dialog-exit-animation-duration:var(--forge-dialog-exit-animation-duration, var(--forge-animation-duration-short2, 100ms));\n --_dialog-exit-animation-easing:var(--forge-dialog-exit-animation-easing, var(--forge-animation-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)));\n --_dialog-zoom-opacity:var(--forge-dialog-zoom-opacity, 0);\n --_dialog-zoom-scale:var(--forge-dialog-zoom-scale, 0.8);\n --_dialog-fade-opacity:var(--forge-dialog-fade-opacity, 0);\n --_dialog-slide-opacity:var(--forge-dialog-slide-opacity, 0);\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 -30%);\n --_dialog-backdrop-opacity:var(--forge-dialog-backdrop-opacity, var(--forge-backdrop-opacity, 0.54));\n --_dialog-nonmodal-elevation:var(--forge-dialog-nonmodal-elevation, 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 --_dialog-fullscreen-enter-animation-duration:var(--forge-dialog-fullscreen-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-fullscreen-exit-animation-duration:var(--forge-dialog-fullscreen-exit-animation-duration, var(--forge-animation-duration-short2, 100ms));\n --_dialog-position-x:var(--forge-dialog-position-x, 0);\n --_dialog-position-y:var(--forge-dialog-position-y, 0);\n --_dialog-preset-sheet-enter-animation-duration:var(--forge-dialog-preset-sheet-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-preset-sheet-exit-animation-duration:var(--forge-dialog-preset-sheet-exit-animation-duration, var(--forge-animation-duration-short3, 150ms));\n --_backdrop-background:var(--forge-backdrop-background, #000);\n --_backdrop-opacity:var(--forge-backdrop-opacity, 0.54);\n --_backdrop-z-index:var(--forge-backdrop-z-index, var(--forge-z-index-backdrop, 7));\n --_backdrop-enter-animation-duration:var(--forge-backdrop-enter-animation-duration, var(--forge-animation-duration-short4, 200ms));\n --_backdrop-enter-animation-easing:var(--forge-backdrop-enter-animation-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_backdrop-exit-animation-duration:var(--forge-backdrop-exit-animation-duration, var(--forge-animation-duration-short1, 50ms));\n --_backdrop-exit-animation-easing:var(--forge-backdrop-exit-animation-easing, var(--forge-animation-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)));\n --forge-theme-surface: var(--forge-theme-surface-bright, #ffffff);\n}\n\n.forge-dialog {\n position: fixed;\n inset: 0;\n z-index: var(--_dialog-z-index);\n background-color: rgba(0, 0, 0, 0);\n color: inherit;\n border: none;\n width: auto;\n height: auto;\n padding: 0;\n margin: 0;\n overflow: visible;\n max-width: 100%;\n max-height: 100%;\n box-sizing: border-box;\n position: absolute;\n inset: 0;\n display: flex;\n background: var(--_dialog-background);\n box-shadow: var(--_dialog-elevation);\n z-index: var(--_dialog-z-index);\n overflow: hidden;\n border-radius: var(--_dialog-shape);\n margin-block-start: var(--_dialog-block-start-spacing);\n margin-block-end: var(--_dialog-block-end-spacing);\n margin-inline-start: var(--_dialog-inline-start-spacing);\n margin-inline-end: var(--_dialog-inline-end-spacing);\n padding: var(--_dialog-padding);\n width: var(--_dialog-width);\n height: var(--_dialog-height);\n min-width: var(--_dialog-min-width);\n max-width: var(--_dialog-max-width);\n min-height: var(--_dialog-min-height);\n max-height: var(--_dialog-max-height);\n box-sizing: border-box;\n animation-duration: var(--_dialog-exit-animation-duration);\n animation-timing-function: var(--_dialog-exit-animation-easing);\n position: fixed;\n transition-property: display, opacity, overlay, scale;\n transition-behavior: allow-discrete;\n}\n\n.forge-dialog > forge-scaffold {\n height: auto;\n}\n\n.forge-dialog--fullscreen {\n --_dialog-enter-animation-duration:var(--_dialog-fullscreen-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-fullscreen-exit-animation-duration);\n height: 100%;\n width: 100%;\n max-width: none;\n max-height: none;\n border-radius: 0;\n box-shadow: none;\n}\n\n.forge-dialog:not(:modal) {\n --_dialog-elevation:var(--_dialog-nonmodal-elevation);\n pointer-events: all;\n}\n\n.forge-dialog--moveable {\n user-select: none;\n transition-property: opacity;\n transition-duration: var(--_dialog-move-transition-duration);\n transition-timing-function: var(--_dialog-move-transition-easing);\n}\n\n.forge-dialog--moved {\n margin: 0;\n}\n\n.forge-dialog--moving {\n opacity: var(--_dialog-moving-opacity);\n}\n\n.forge-dialog__move-handle {\n fill: var(--_dialog-move-handle-color);\n height: var(--_dialog-move-handle-size);\n width: var(--_dialog-move-handle-size);\n margin: var(--_dialog-move-handle-spacing);\n touch-action: none;\n}\n\n.forge-dialog__move-handle:hover {\n cursor: var(--_dialog-move-handle-hover-cursor);\n}\n\n.forge-dialog__move-handle:active {\n cursor: var(--_dialog-move-handle-active-cursor);\n}\n\n.forge-dialog__move-handle-container {\n position: absolute;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: center;\n width: 100%;\n}\n\n.forge-dialog--top {\n --_dialog-block-start-spacing:var(--forge-dialog-block-start-spacing, 0);\n top: 0;\n bottom: auto;\n}\n\n.forge-dialog--top-right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: 0;\n left: auto;\n right: 0;\n bottom: auto;\n}\n\n.forge-dialog--top-left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: 0;\n left: 0;\n right: auto;\n bottom: auto;\n}\n\n.forge-dialog--bottom {\n --_dialog-block-end-spacing:var(--forge-dialog-block-end-spacing, 0);\n top: auto;\n bottom: 0;\n}\n\n.forge-dialog--bottom-right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: auto;\n right: 0;\n bottom: 0;\n}\n\n.forge-dialog--bottom-left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: 0;\n right: auto;\n bottom: 0;\n}\n\n.forge-dialog--right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: auto;\n right: 0;\n bottom: auto;\n}\n\n.forge-dialog--left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: 0;\n right: auto;\n bottom: auto;\n}\n\n.forge-dialog--custom {\n margin: 0;\n top: var(--_dialog-position-x);\n left: var(--_dialog-position-y);\n}\n\n.forge-dialog--bottom-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n bottom: 0;\n left: 0;\n right: 0;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 100%);\n}\n\n.forge-dialog--bottom-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--bottom-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--bottom-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--bottom-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--left-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n left: 0;\n bottom: 0;\n top: 0;\n height: 100%;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, -100% 0);\n}\n\n.forge-dialog--left-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--left-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--left-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--left-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--right-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n right: 0;\n bottom: 0;\n top: 0;\n height: 100%;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 100% 0);\n}\n\n.forge-dialog--right-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--right-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--right-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--right-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--top-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n top: 0;\n left: 0;\n right: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 -100%);\n}\n\n.forge-dialog--top-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--top-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--top-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--top-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog::backdrop {\n --forge-backdrop-opacity: var(--_backdrop-opacity);\n --forge-backdrop-enter-animation-duration: var(--_backdrop-enter-animation-duration);\n --forge-backdrop-enter-animation-easing: var(--_backdrop-enter-animation-easing);\n --forge-backdrop-exit-animation-duration: var(--_backdrop-exit-animation-duration);\n --forge-backdrop-exit-animation-easing: var(--_backdrop-exit-animation-easing);\n position: absolute;\n inset: 0;\n z-index: var(--_backdrop-z-index);\n background: var(--_backdrop-background);\n opacity: 0;\n animation-fill-mode: forwards;\n transition-property: display, opacity, overlay;\n}\n\n.forge-dialog[open] {\n opacity: 1;\n scale: 1;\n transition-duration: var(--_dialog-enter-animation-duration);\n transition-timing-function: var(--_dialog-enter-animation-easing);\n}\n\n@starting-style {\n .forge-dialog[open] {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n}\n.forge-dialog[open]::backdrop {\n opacity: var(--_backdrop-opacity);\n transition-duration: var(--_backdrop-enter-animation-duration);\n transition-timing-function: var(--_backdrop-enter-animation-easing);\n}\n\n@starting-style {\n .forge-dialog[open]::backdrop {\n opacity: 0;\n }\n}\n.forge-dialog:not([open]) {\n animation-duration: var(--_dialog-enter-animation-duration);\n animation-timing-function: var(--_dialog-enter-animation-easing);\n display: none;\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n transition-duration: var(--_dialog-exit-animation-duration);\n transition-timing-function: var(--_dialog-exit-animation-easing);\n}\n\n.forge-dialog:not([open])::backdrop {\n transition-duration: var(--_backdrop-exit-animation-duration);\n transition-timing-function: var(--_backdrop-exit-animation-easing);\n}\n\n.forge-dialog--animation-fade.forge-dialog {\n transition-property: display, opacity, overlay;\n}\n\n@starting-style {\n .forge-dialog--animation-fade.forge-dialog[open] {\n opacity: var(--_dialog-fade-opacity);\n }\n}\n.forge-dialog--animation-fade.forge-dialog:not([open]) {\n opacity: var(--_dialog-fade-opacity);\n scale: 1;\n}\n\n.forge-dialog--animation-slide.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--animation-slide.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--animation-slide.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--animation-slide.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--animation-none {\n --_dialog-enter-animation-duration:var(--forge-dialog-enter-animation-duration, 0s);\n --_dialog-exit-animation-duration:var(--forge-dialog-exit-animation-duration, 0s);\n --_backdrop-enter-animation-duration:var(--forge-backdrop-enter-animation-duration, 0s);\n --_backdrop-exit-animation-duration:var(--forge-backdrop-exit-animation-duration, 0s);\n}\n\n@media (prefers-reduced-motion) {\n .forge-dialog.forge-dialog {\n transition-property: display, opacity, overlay;\n }\n @starting-style {\n .forge-dialog.forge-dialog[open] {\n opacity: var(--_dialog-fade-opacity);\n }\n }\n .forge-dialog.forge-dialog:not([open]) {\n opacity: var(--_dialog-fade-opacity);\n scale: 1;\n }\n}\n:host {\n display: block;\n width: 100%;\n height: 100%;\n --_ai-chatbot-icon-shape: var(--forge-ai-chatbot-icon-shape, 0);\n}\n\n.chatbot-container {\n position: relative;\n display: grid;\n height: 100%;\n overflow: hidden;\n border-radius: inherit;\n}\n\nforge-ai-chat-interface::part(messages) {\n overflow: hidden;\n}\nforge-ai-chat-interface forge-ai-message-thread {\n min-height: 0;\n}\n\nforge-ai-chat-header {\n --forge-ai-chat-header-title-color: var(--forge-ai-chatbot-header-title-color, currentColor);\n}\n\n.disclaimer {\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 color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n text-align: center;\n margin-block-start: var(--forge-spacing-xxsmall, 4px);\n margin-block-end: calc(var(--forge-spacing-small, 12px) * -1);\n}\n\n.suggestions-container {\n width: 100%;\n align-self: start;\n}\n\n::slotted([slot=empty-state-icon]) {\n height: 200px;\n width: 200px;\n border-radius: var(--_ai-chatbot-icon-shape);\n}\n\n.conversations-backdrop {\n position: absolute;\n inset: 0;\n background-color: transparent;\n z-index: 1;\n}\n\n.conversations-dialog {\n display: grid;\n width: min(90%, 360px);\n padding: 0;\n border: 0;\n position: absolute;\n z-index: 2;\n --forge-dialog-shape: 0;\n --forge-dialog-nonmodal-elevation: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);\n}';
1
+ const styles = '/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n@keyframes forge-dialog-zoom-in {\n from {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n to {\n opacity: 1;\n scale: 1;\n }\n}\n@keyframes forge-dialog-zoom-out {\n from {\n opacity: 1;\n scale: 1;\n }\n to {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n}\n@keyframes forge-dialog-fade-in {\n from {\n opacity: var(--_dialog-fade-opacity);\n }\n to {\n opacity: 1;\n }\n}\n@keyframes forge-dialog-fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: var(--_dialog-fade-opacity);\n }\n}\n@keyframes forge-dialog-slide-in {\n from {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n to {\n opacity: 1;\n translate: 0 0;\n }\n}\n@keyframes forge-dialog-slide-out {\n from {\n opacity: 1;\n translate: 0 0;\n }\n to {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog {\n --_dialog-background:var(--forge-dialog-background, var(--forge-theme-surface-bright, #ffffff));\n --_dialog-shape:var(--forge-dialog-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_dialog-elevation:var(--forge-dialog-elevation, 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12));\n --_dialog-spacing:var(--forge-dialog-spacing, auto);\n --_dialog-block-start-spacing:var(--forge-dialog-block-start-spacing, var(--_dialog-spacing));\n --_dialog-block-end-spacing:var(--forge-dialog-block-end-spacing, var(--_dialog-spacing));\n --_dialog-inline-start-spacing:var(--forge-dialog-inline-start-spacing, var(--_dialog-spacing));\n --_dialog-inline-end-spacing:var(--forge-dialog-inline-end-spacing, var(--_dialog-spacing));\n --_dialog-padding:var(--forge-dialog-padding, 0);\n --_dialog-width:var(--forge-dialog-width, fit-content);\n --_dialog-height:var(--forge-dialog-height, fit-content);\n --_dialog-min-width:var(--forge-dialog-min-width, 0);\n --_dialog-max-width:var(--forge-dialog-max-width, calc(100% - var(--forge-spacing-xxlarge, 48px)));\n --_dialog-min-height:var(--forge-dialog-min-height, 0);\n --_dialog-max-height:var(--forge-dialog-max-height, calc(100% - var(--forge-spacing-xxlarge, 48px)));\n --_dialog-z-index:var(--forge-dialog-z-index, var(--forge-z-index-dialog, 8));\n --_dialog-move-handle-color:var(--forge-dialog-move-handle-color, currentColor);\n --_dialog-move-handle-size:var(--forge-dialog-move-handle-size, 24px);\n --_dialog-move-handle-hover-cursor:var(--forge-dialog-move-handle-hover-cursor, grab);\n --_dialog-move-handle-active-cursor:var(--forge-dialog-move-handle-active-cursor, grabbing);\n --_dialog-move-handle-spacing:var(--forge-dialog-move-handle-spacing, calc(var(--forge-spacing-xxsmall, 4px) * -1) 0 0);\n --_dialog-move-transition-duration:var(--forge-dialog-move-transition-duration, var(--forge-animation-duration-short4, 200ms));\n --_dialog-move-transition-easing:var(--forge-dialog-move-transition-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_dialog-moving-opacity:var(--forge-dialog-moving-opacity, 0.54);\n --_dialog-enter-animation-duration:var(--forge-dialog-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-enter-animation-easing:var(--forge-dialog-enter-animation-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_dialog-exit-animation-duration:var(--forge-dialog-exit-animation-duration, var(--forge-animation-duration-short2, 100ms));\n --_dialog-exit-animation-easing:var(--forge-dialog-exit-animation-easing, var(--forge-animation-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)));\n --_dialog-zoom-opacity:var(--forge-dialog-zoom-opacity, 0);\n --_dialog-zoom-scale:var(--forge-dialog-zoom-scale, 0.8);\n --_dialog-fade-opacity:var(--forge-dialog-fade-opacity, 0);\n --_dialog-slide-opacity:var(--forge-dialog-slide-opacity, 0);\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 -30%);\n --_dialog-backdrop-opacity:var(--forge-dialog-backdrop-opacity, var(--forge-backdrop-opacity, 0.54));\n --_dialog-nonmodal-elevation:var(--forge-dialog-nonmodal-elevation, 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 --_dialog-fullscreen-enter-animation-duration:var(--forge-dialog-fullscreen-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-fullscreen-exit-animation-duration:var(--forge-dialog-fullscreen-exit-animation-duration, var(--forge-animation-duration-short2, 100ms));\n --_dialog-position-x:var(--forge-dialog-position-x, 0);\n --_dialog-position-y:var(--forge-dialog-position-y, 0);\n --_dialog-preset-sheet-enter-animation-duration:var(--forge-dialog-preset-sheet-enter-animation-duration, var(--forge-animation-duration-medium1, 250ms));\n --_dialog-preset-sheet-exit-animation-duration:var(--forge-dialog-preset-sheet-exit-animation-duration, var(--forge-animation-duration-short3, 150ms));\n --_backdrop-background:var(--forge-backdrop-background, #000);\n --_backdrop-opacity:var(--forge-backdrop-opacity, 0.54);\n --_backdrop-z-index:var(--forge-backdrop-z-index, var(--forge-z-index-backdrop, 7));\n --_backdrop-enter-animation-duration:var(--forge-backdrop-enter-animation-duration, var(--forge-animation-duration-short4, 200ms));\n --_backdrop-enter-animation-easing:var(--forge-backdrop-enter-animation-easing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_backdrop-exit-animation-duration:var(--forge-backdrop-exit-animation-duration, var(--forge-animation-duration-short1, 50ms));\n --_backdrop-exit-animation-easing:var(--forge-backdrop-exit-animation-easing, var(--forge-animation-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)));\n --forge-theme-surface: var(--forge-theme-surface-bright, #ffffff);\n}\n\n.forge-dialog {\n position: fixed;\n inset: 0;\n z-index: var(--_dialog-z-index);\n background-color: rgba(0, 0, 0, 0);\n color: inherit;\n border: none;\n width: auto;\n height: auto;\n padding: 0;\n margin: 0;\n overflow: visible;\n max-width: 100%;\n max-height: 100%;\n box-sizing: border-box;\n position: absolute;\n inset: 0;\n display: flex;\n background: var(--_dialog-background);\n box-shadow: var(--_dialog-elevation);\n z-index: var(--_dialog-z-index);\n overflow: hidden;\n border-radius: var(--_dialog-shape);\n margin-block-start: var(--_dialog-block-start-spacing);\n margin-block-end: var(--_dialog-block-end-spacing);\n margin-inline-start: var(--_dialog-inline-start-spacing);\n margin-inline-end: var(--_dialog-inline-end-spacing);\n padding: var(--_dialog-padding);\n width: var(--_dialog-width);\n height: var(--_dialog-height);\n min-width: var(--_dialog-min-width);\n max-width: var(--_dialog-max-width);\n min-height: var(--_dialog-min-height);\n max-height: var(--_dialog-max-height);\n box-sizing: border-box;\n animation-duration: var(--_dialog-exit-animation-duration);\n animation-timing-function: var(--_dialog-exit-animation-easing);\n position: fixed;\n transition-property: display, opacity, overlay, scale;\n transition-behavior: allow-discrete;\n}\n\n.forge-dialog > forge-scaffold {\n height: auto;\n}\n\n.forge-dialog--fullscreen {\n --_dialog-enter-animation-duration:var(--_dialog-fullscreen-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-fullscreen-exit-animation-duration);\n height: 100%;\n width: 100%;\n max-width: none;\n max-height: none;\n border-radius: 0;\n box-shadow: none;\n}\n\n.forge-dialog:not(:modal) {\n --_dialog-elevation:var(--_dialog-nonmodal-elevation);\n pointer-events: all;\n}\n\n.forge-dialog--moveable {\n user-select: none;\n transition-property: opacity;\n transition-duration: var(--_dialog-move-transition-duration);\n transition-timing-function: var(--_dialog-move-transition-easing);\n}\n\n.forge-dialog--moved {\n margin: 0;\n}\n\n.forge-dialog--moving {\n opacity: var(--_dialog-moving-opacity);\n}\n\n.forge-dialog__move-handle {\n fill: var(--_dialog-move-handle-color);\n height: var(--_dialog-move-handle-size);\n width: var(--_dialog-move-handle-size);\n margin: var(--_dialog-move-handle-spacing);\n touch-action: none;\n}\n\n.forge-dialog__move-handle:hover {\n cursor: var(--_dialog-move-handle-hover-cursor);\n}\n\n.forge-dialog__move-handle:active {\n cursor: var(--_dialog-move-handle-active-cursor);\n}\n\n.forge-dialog__move-handle-container {\n position: absolute;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: center;\n width: 100%;\n}\n\n.forge-dialog--top {\n --_dialog-block-start-spacing:var(--forge-dialog-block-start-spacing, 0);\n top: 0;\n bottom: auto;\n}\n\n.forge-dialog--top-right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: 0;\n left: auto;\n right: 0;\n bottom: auto;\n}\n\n.forge-dialog--top-left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: 0;\n left: 0;\n right: auto;\n bottom: auto;\n}\n\n.forge-dialog--bottom {\n --_dialog-block-end-spacing:var(--forge-dialog-block-end-spacing, 0);\n top: auto;\n bottom: 0;\n}\n\n.forge-dialog--bottom-right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: auto;\n right: 0;\n bottom: 0;\n}\n\n.forge-dialog--bottom-left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: 0;\n right: auto;\n bottom: 0;\n}\n\n.forge-dialog--right {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: auto;\n right: 0;\n bottom: auto;\n}\n\n.forge-dialog--left {\n --_dialog-spacing:var(--forge-dialog-spacing, 0);\n top: auto;\n left: 0;\n right: auto;\n bottom: auto;\n}\n\n.forge-dialog--custom {\n margin: 0;\n top: var(--_dialog-position-x);\n left: var(--_dialog-position-y);\n}\n\n.forge-dialog--bottom-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n bottom: 0;\n left: 0;\n right: 0;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 100%);\n}\n\n.forge-dialog--bottom-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--bottom-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--bottom-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--bottom-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--left-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n left: 0;\n bottom: 0;\n top: 0;\n height: 100%;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, -100% 0);\n}\n\n.forge-dialog--left-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--left-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--left-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--left-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--right-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n right: 0;\n bottom: 0;\n top: 0;\n height: 100%;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 100% 0);\n}\n\n.forge-dialog--right-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--right-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--right-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--right-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--top-sheet {\n --_dialog-enter-animation-duration:var(--_dialog-preset-sheet-enter-animation-duration);\n --_dialog-exit-animation-duration:var(--_dialog-preset-sheet-exit-animation-duration);\n --_dialog-max-width:var(--forge-dialog-max-width, none);\n --_dialog-max-height:var(--forge-dialog-max-height, none);\n inset: auto;\n display: inline-flex;\n top: 0;\n left: 0;\n right: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n --_dialog-slide-translate:var(--forge-dialog-slide-translate, 0 -100%);\n}\n\n.forge-dialog--top-sheet.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--top-sheet.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--top-sheet.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--top-sheet.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog::backdrop {\n --forge-backdrop-opacity: var(--_backdrop-opacity);\n --forge-backdrop-enter-animation-duration: var(--_backdrop-enter-animation-duration);\n --forge-backdrop-enter-animation-easing: var(--_backdrop-enter-animation-easing);\n --forge-backdrop-exit-animation-duration: var(--_backdrop-exit-animation-duration);\n --forge-backdrop-exit-animation-easing: var(--_backdrop-exit-animation-easing);\n position: absolute;\n inset: 0;\n z-index: var(--_backdrop-z-index);\n background: var(--_backdrop-background);\n opacity: 0;\n animation-fill-mode: forwards;\n transition-property: display, opacity, overlay;\n}\n\n.forge-dialog[open] {\n opacity: 1;\n scale: 1;\n transition-duration: var(--_dialog-enter-animation-duration);\n transition-timing-function: var(--_dialog-enter-animation-easing);\n}\n\n@starting-style {\n .forge-dialog[open] {\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n }\n}\n.forge-dialog[open]::backdrop {\n opacity: var(--_backdrop-opacity);\n transition-duration: var(--_backdrop-enter-animation-duration);\n transition-timing-function: var(--_backdrop-enter-animation-easing);\n}\n\n@starting-style {\n .forge-dialog[open]::backdrop {\n opacity: 0;\n }\n}\n.forge-dialog:not([open]) {\n animation-duration: var(--_dialog-enter-animation-duration);\n animation-timing-function: var(--_dialog-enter-animation-easing);\n display: none;\n opacity: var(--_dialog-zoom-opacity);\n scale: var(--_dialog-zoom-scale);\n transition-duration: var(--_dialog-exit-animation-duration);\n transition-timing-function: var(--_dialog-exit-animation-easing);\n}\n\n.forge-dialog:not([open])::backdrop {\n transition-duration: var(--_backdrop-exit-animation-duration);\n transition-timing-function: var(--_backdrop-exit-animation-easing);\n}\n\n.forge-dialog--animation-fade.forge-dialog {\n transition-property: display, opacity, overlay;\n}\n\n@starting-style {\n .forge-dialog--animation-fade.forge-dialog[open] {\n opacity: var(--_dialog-fade-opacity);\n }\n}\n.forge-dialog--animation-fade.forge-dialog:not([open]) {\n opacity: var(--_dialog-fade-opacity);\n scale: 1;\n}\n\n.forge-dialog--animation-slide.forge-dialog {\n transition-property: display, opacity, overlay, translate;\n}\n\n.forge-dialog--animation-slide.forge-dialog[open] {\n translate: 0 0;\n}\n\n@starting-style {\n .forge-dialog--animation-slide.forge-dialog[open] {\n opacity: var(--_dialog-slide-opacity);\n translate: var(--_dialog-slide-translate);\n }\n}\n.forge-dialog--animation-slide.forge-dialog:not([open]) {\n opacity: var(--_dialog-slide-opacity);\n scale: 1;\n translate: var(--_dialog-slide-translate);\n}\n\n.forge-dialog--animation-none {\n --_dialog-enter-animation-duration:var(--forge-dialog-enter-animation-duration, 0s);\n --_dialog-exit-animation-duration:var(--forge-dialog-exit-animation-duration, 0s);\n --_backdrop-enter-animation-duration:var(--forge-backdrop-enter-animation-duration, 0s);\n --_backdrop-exit-animation-duration:var(--forge-backdrop-exit-animation-duration, 0s);\n}\n\n@media (prefers-reduced-motion) {\n .forge-dialog.forge-dialog {\n transition-property: display, opacity, overlay;\n }\n @starting-style {\n .forge-dialog.forge-dialog[open] {\n opacity: var(--_dialog-fade-opacity);\n }\n }\n .forge-dialog.forge-dialog:not([open]) {\n opacity: var(--_dialog-fade-opacity);\n scale: 1;\n }\n}\n:host {\n display: block;\n width: 100%;\n height: 100%;\n --_ai-chatbot-icon-shape: var(--forge-ai-chatbot-icon-shape, 0);\n}\n\n.chatbot-container {\n position: relative;\n display: grid;\n height: 100%;\n overflow: hidden;\n border-radius: inherit;\n}\n\nforge-ai-chat-interface::part(messages) {\n overflow: hidden;\n}\nforge-ai-chat-interface forge-ai-message-thread {\n min-height: 0;\n}\n\nforge-ai-chat-header {\n --forge-ai-chat-header-title-color: var(--forge-ai-chatbot-header-title-color, currentColor);\n}\n\n.disclaimer {\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 color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n text-align: center;\n margin-block-start: var(--forge-spacing-xxsmall, 4px);\n margin-block-end: calc(var(--forge-spacing-small, 12px) * -1);\n}\n\n.suggestions-container {\n width: 100%;\n align-self: start;\n}\n\n::slotted([slot=empty-state-icon]) {\n height: 200px;\n width: 200px;\n border-radius: var(--_ai-chatbot-icon-shape);\n}\n\n.conversations-backdrop {\n position: absolute;\n inset: 0;\n background-color: transparent;\n z-index: 1;\n}\n\n.conversations-dialog {\n display: grid;\n width: min(90%, 360px);\n padding: 0;\n border: 0;\n position: absolute;\n z-index: 2;\n --forge-dialog-shape: 0;\n --forge-dialog-nonmodal-elevation: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);\n}\n\n.canvas-modal {\n --forge-ai-modal-width: var(--forge-ai-chatbot-canvas-width, 80vw);\n --forge-ai-modal-height: var(--forge-ai-chatbot-canvas-height, 80vh);\n}\n\n.canvas {\n --forge-ai-canvas-border-inline-start: none;\n flex: 1;\n min-inline-size: 0;\n}';
2
2
  export {
3
3
  styles as default
4
4
  };
@@ -1,9 +1,9 @@
1
- import { ToolCall, ToolRenderer } from './types.js';
1
+ import { ToolRenderFunction, ToolRenderer } from './types.js';
2
2
  export interface CreateToolRendererElementConfig {
3
3
  elementTag: keyof HTMLElementTagNameMap;
4
4
  }
5
- export interface CreateToolRendererFunctionConfig {
6
- render: (toolCall: ToolCall) => HTMLElement | DocumentFragment;
5
+ export interface CreateToolRendererFunctionConfig<TArgs = Record<string, unknown>, TResult = unknown> {
6
+ render: ToolRenderFunction<TArgs, TResult>;
7
7
  }
8
- export type CreateToolRendererConfig = CreateToolRendererElementConfig | CreateToolRendererFunctionConfig;
9
- export declare function createToolRenderer(config: CreateToolRendererConfig): ToolRenderer;
8
+ export type CreateToolRendererConfig<TArgs = Record<string, unknown>, TResult = unknown> = CreateToolRendererElementConfig | CreateToolRendererFunctionConfig<TArgs, TResult>;
9
+ export declare function createToolRenderer<TArgs = Record<string, unknown>, TResult = unknown>(config: CreateToolRendererConfig<TArgs, TResult>): ToolRenderer<TArgs, TResult>;
@@ -3,13 +3,14 @@ export { AiChatbotComponent, AiChatbotComponentTagName } from './ai-chatbot.js';
3
3
  export type { ForgeAiChatbotMessageEventData, ForgeAiChatbotToolCallEventData, ForgeAiChatbotErrorEventData, ForgeAiChatbotResponseFeedbackEventData, ForgeAiChatbotAgentChangeEventData, ForgeAiChatbotFileSelectEventData, ForgeAiChatbotFileRemoveEventData } from './ai-chatbot.js';
4
4
  export { AiChatbotToolCallComponent, AiChatbotToolCallComponentTagName } from './ai-chatbot-tool-call.js';
5
5
  export type { Suggestion } from '../ai-suggestions/index.js';
6
- export { AgentAdapter, type MessageStartEvent, type MessageDeltaEvent, type MessageEndEvent, type ToolCallEvent, type ToolCallStartEvent, type ToolCallArgsEvent, type ToolCallEndEvent, type FileUploadEvent, type FileRemoveEvent, type AdapterState, type ErrorEvent, type CustomAgentEvent, type RawAgentEvent, type RunStartedAgentEvent, type StepStartedAgentEvent, type StepFinishedAgentEvent, type StateSnapshotAgentEvent, type StateDeltaAgentEvent, type ActivitySnapshotAgentEvent, type ActivityDeltaAgentEvent } from './agent-adapter.js';
7
- export type { Agent, ChatMessage, ClientMessageAction, ClientMessageInput, ClientMessageKind, ContextItem, ToolDefinition, ToolCall, ToolRenderer, IToolRenderer, HandlerContext, ToolStartContext, ToolDeltaContext, ToolEndContext, FileAttachment, UploadedFileMetadata, FileUploadCallbacks, FileUploadHandler, FileRemoveCallbacks, ThreadState, FeedbackType, ResponseFeedback, MessageItem, ForgeAiChatbotContextRemoveEventData, ForgeAiChatbotThreadSelectEventData, ForgeAiChatbotThreadSearchEventData, ForgeAiChatbotThreadLoadMoreEventData, ForgeAiChatbotThreadRenameEventData, ForgeAiChatbotThreadDeleteEventData } from './types.js';
6
+ export { AgentAdapter, type MessageStartEvent, type MessageDeltaEvent, type MessageEndEvent, type ToolCallEvent, type ToolCallStartEvent, type ToolCallArgsEvent, type ToolCallEndEvent, type FileUploadEvent, type FileRemoveEvent, type AdapterState, type ErrorEvent, type CustomAgentEvent, type RawAgentEvent, type RunStartedAgentEvent, type StepStartedAgentEvent, type StepFinishedAgentEvent, type StateSnapshotAgentEvent, type StateDeltaAgentEvent, type ActivitySnapshotAgentEvent, type ActivityDeltaAgentEvent, type McpUiResourceEvent, type McpToolCallParams, type McpResourceReadParams, type McpAppResourceResolveParams, type McpModelContextUpdateParams, type ToolResultEvent } from './agent-adapter.js';
7
+ export type { Agent, ChatMessage, ClientMessageAction, ClientMessageInput, ClientMessageKind, ContextItem, ToolDefinition, AnyToolDefinition, ToolCall, ToolCallStatus, ToolRenderer, ToolPresentation, ToolCanvas, ToolRenderContext, ToolRenderFunction, ToolCanvasConfig, ToolCanvasInline, ToolCanvasIcon, ToolCanvasActionLabel, ToolCallMapper, ToolCallValue, IToolRenderer, HandlerContext, ToolStartContext, ToolDeltaContext, ToolEndContext, FileAttachment, UploadedFileMetadata, FileUploadCallbacks, FileUploadHandler, FileRemoveCallbacks, ThreadState, FeedbackType, ResponseFeedback, MessageItem, ForgeAiChatbotContextRemoveEventData, ForgeAiChatbotThreadSelectEventData, ForgeAiChatbotThreadSearchEventData, ForgeAiChatbotThreadLoadMoreEventData, ForgeAiChatbotThreadRenameEventData, ForgeAiChatbotThreadDeleteEventData, McpAppUiResource, McpAppUiResourceStatus, McpAppResourceCsp, McpAppResourcePermissions, McpAppHostContext, McpAppHostStyles, McpAppHostCapabilities, McpAppContainerDimensions, McpAppContentModalities, McpAppToolInfo, McpAppSandboxCapabilities, McpAppDisplayMode, McpToolResult } from './types.js';
8
8
  export * from './ag-ui-adapter.js';
9
9
  export * from './http-agent-with-credentials.js';
10
10
  export * from './event-emitter.js';
11
11
  export * from './agent-runner.js';
12
12
  export * from './create-tool-renderer.js';
13
+ export { requestCanvasOpen, requestCanvasClose, type ForgeAiCanvasOpenRequestEventData, type ForgeAiCanvasCloseRequestEventData } from './tool-canvas.js';
13
14
  export { MessageStateController, type MessageStateControllerConfig } from './message-state-controller.js';
14
15
  export { FileUploadManager, type FileUploadManagerConfig } from './file-upload-manager.js';
15
16
  export { MarkdownStreamController } from './markdown-stream-controller.js';
@@ -7,6 +7,7 @@ import { HttpAgentWithCredentials } from "./http-agent-with-credentials.mjs";
7
7
  import { EventEmitter, SubscriptionManager } from "./event-emitter.mjs";
8
8
  import { AgentRunner } from "./agent-runner.mjs";
9
9
  import { createToolRenderer } from "./create-tool-renderer.mjs";
10
+ import { requestCanvasClose, requestCanvasOpen } from "./tool-canvas.mjs";
10
11
  import { MessageStateController } from "./message-state-controller.mjs";
11
12
  import { FileUploadManager } from "./file-upload-manager.mjs";
12
13
  import { MarkdownStreamController } from "./markdown-stream-controller.mjs";
@@ -32,6 +33,8 @@ export {
32
33
  generateId,
33
34
  renderInlineMarkdown,
34
35
  renderMarkdown,
36
+ requestCanvasClose,
37
+ requestCanvasOpen,
35
38
  toRequestMessages,
36
39
  toRequestToolCall
37
40
  };
@@ -34,6 +34,10 @@ export declare class MessageStateController implements ReactiveController {
34
34
  appendTextDelta(messageId: string, delta: string): void;
35
35
  markTextComplete(messageId: string): void;
36
36
  addToolCallToResponse(toolCall: ToolCall): void;
37
+ /**
38
+ * Applies `updates` to a tool call wherever it is rendered: the in-progress response,
39
+ * an already finalized/restored response, or a top-level tool-call item.
40
+ */
37
41
  updateToolCallInResponse(toolCallId: string, updates: Partial<ToolCall>): void;
38
42
  completeToolCallInResponse(toolCallId: string, result: unknown, event?: ToolResultEvent): void;
39
43
  tryFinalizeResponse(): void;
@@ -52,10 +56,15 @@ export declare class MessageStateController implements ReactiveController {
52
56
  updateMessageContent(id: string, content: string): void;
53
57
  removeMessageItem(index: number): void;
54
58
  clearMessages(): void;
55
- removeMessageItemsFrom(index: number): void;
59
+ /** Tool call ids rendered at or after `index`, inside assistant responses or as top-level items. */
60
+ getToolCallIdsFrom(index: number): string[];
61
+ /** Removes items from `index` onward and returns the ids of the tool calls they held. */
62
+ removeMessageItemsFrom(index: number): string[];
56
63
  /**
57
64
  * Reconstructs the message hierarchy for API compatibility.
58
65
  * Converts assistant responses back to ChatMessage format with tool calls.
66
+ * MCP-app `uiResource`/`uiResourceStatus` are stripped: resources are re-resolved via the
67
+ * adapter on restore, never persisted or sent back to the agent.
59
68
  */
60
69
  getMessages(): ChatMessage[];
61
70
  setMessages(messages: ChatMessage[]): void;