@genesislcap/ai-assistant 14.403.0-ai-assistant.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 (244) hide show
  1. package/api-extractor.json +4 -0
  2. package/dist/ai-assistant.api.json +4028 -0
  3. package/dist/ai-assistant.d.ts +396 -0
  4. package/dist/dts/channel/ai-activity-channel.d.ts +32 -0
  5. package/dist/dts/channel/ai-activity-channel.d.ts.map +1 -0
  6. package/dist/dts/components/activity-halo/activity-halo.d.ts +31 -0
  7. package/dist/dts/components/activity-halo/activity-halo.d.ts.map +1 -0
  8. package/dist/dts/components/chat-bubble/chat-bubble.d.ts +52 -0
  9. package/dist/dts/components/chat-bubble/chat-bubble.d.ts.map +1 -0
  10. package/dist/dts/components/chat-bubble/chat-bubble.styles.d.ts +2 -0
  11. package/dist/dts/components/chat-bubble/chat-bubble.styles.d.ts.map +1 -0
  12. package/dist/dts/components/chat-bubble/chat-bubble.template.d.ts +4 -0
  13. package/dist/dts/components/chat-bubble/chat-bubble.template.d.ts.map +1 -0
  14. package/dist/dts/components/chat-bubble/index.d.ts +2 -0
  15. package/dist/dts/components/chat-bubble/index.d.ts.map +1 -0
  16. package/dist/dts/components/chat-driver/chat-driver.d.ts +49 -0
  17. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -0
  18. package/dist/dts/components/chat-driver/index.d.ts +2 -0
  19. package/dist/dts/components/chat-driver/index.d.ts.map +1 -0
  20. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +19 -0
  21. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -0
  22. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.d.ts +2 -0
  23. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.d.ts.map +1 -0
  24. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.template.d.ts +3 -0
  25. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.template.d.ts.map +1 -0
  26. package/dist/dts/components/chat-interaction-wrapper/index.d.ts +4 -0
  27. package/dist/dts/components/chat-interaction-wrapper/index.d.ts.map +1 -0
  28. package/dist/dts/components/chat-markdown/chat-markdown.d.ts +6 -0
  29. package/dist/dts/components/chat-markdown/chat-markdown.d.ts.map +1 -0
  30. package/dist/dts/components/chat-markdown/index.d.ts +2 -0
  31. package/dist/dts/components/chat-markdown/index.d.ts.map +1 -0
  32. package/dist/dts/components/halo-overlay.d.ts +25 -0
  33. package/dist/dts/components/halo-overlay.d.ts.map +1 -0
  34. package/dist/dts/config/config.d.ts +51 -0
  35. package/dist/dts/config/config.d.ts.map +1 -0
  36. package/dist/dts/config/configure.d.ts +1 -0
  37. package/dist/dts/config/configure.d.ts.map +1 -0
  38. package/dist/dts/config/index.d.ts +2 -0
  39. package/dist/dts/config/index.d.ts.map +1 -0
  40. package/dist/dts/index.d.ts +10 -0
  41. package/dist/dts/index.d.ts.map +1 -0
  42. package/dist/dts/main/index.d.ts +5 -0
  43. package/dist/dts/main/index.d.ts.map +1 -0
  44. package/dist/dts/main/main.d.ts +103 -0
  45. package/dist/dts/main/main.d.ts.map +1 -0
  46. package/dist/dts/main/main.styles.d.ts +2 -0
  47. package/dist/dts/main/main.styles.d.ts.map +1 -0
  48. package/dist/dts/main/main.template.d.ts +4 -0
  49. package/dist/dts/main/main.template.d.ts.map +1 -0
  50. package/dist/dts/main/main.types.d.ts +54 -0
  51. package/dist/dts/main/main.types.d.ts.map +1 -0
  52. package/dist/dts/styles/index.d.ts +2 -0
  53. package/dist/dts/styles/index.d.ts.map +1 -0
  54. package/dist/dts/styles/styles.d.ts +5 -0
  55. package/dist/dts/styles/styles.d.ts.map +1 -0
  56. package/dist/dts/tags/index.d.ts +1 -0
  57. package/dist/dts/tags/index.d.ts.map +1 -0
  58. package/dist/dts/types/ai-chat-widget.d.ts +12 -0
  59. package/dist/dts/types/ai-chat-widget.d.ts.map +1 -0
  60. package/dist/dts/utils/index.d.ts +2 -0
  61. package/dist/dts/utils/index.d.ts.map +1 -0
  62. package/dist/dts/utils/logger.d.ts +2 -0
  63. package/dist/dts/utils/logger.d.ts.map +1 -0
  64. package/dist/esm/channel/ai-activity-channel.js +2 -0
  65. package/dist/esm/components/activity-halo/activity-halo.js +119 -0
  66. package/dist/esm/components/chat-bubble/chat-bubble.js +381 -0
  67. package/dist/esm/components/chat-bubble/chat-bubble.styles.js +193 -0
  68. package/dist/esm/components/chat-bubble/chat-bubble.template.js +50 -0
  69. package/dist/esm/components/chat-bubble/index.js +1 -0
  70. package/dist/esm/components/chat-driver/chat-driver.js +209 -0
  71. package/dist/esm/components/chat-driver/index.js +1 -0
  72. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +90 -0
  73. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.js +6 -0
  74. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.template.js +4 -0
  75. package/dist/esm/components/chat-interaction-wrapper/index.js +3 -0
  76. package/dist/esm/components/chat-markdown/chat-markdown.js +95 -0
  77. package/dist/esm/components/chat-markdown/index.js +1 -0
  78. package/dist/esm/components/halo-overlay.js +118 -0
  79. package/dist/esm/config/config.js +16 -0
  80. package/dist/esm/config/configure.js +0 -0
  81. package/dist/esm/config/index.js +1 -0
  82. package/dist/esm/index.js +8 -0
  83. package/dist/esm/main/index.js +4 -0
  84. package/dist/esm/main/main.js +491 -0
  85. package/dist/esm/main/main.styles.js +356 -0
  86. package/dist/esm/main/main.template.js +272 -0
  87. package/dist/esm/main/main.types.js +22 -0
  88. package/dist/esm/styles/index.js +1 -0
  89. package/dist/esm/styles/styles.js +237 -0
  90. package/dist/esm/tags/index.js +0 -0
  91. package/dist/esm/types/ai-chat-widget.js +1 -0
  92. package/dist/esm/utils/index.js +1 -0
  93. package/dist/esm/utils/logger.js +2 -0
  94. package/dist/tsconfig.tsbuildinfo +1 -0
  95. package/dist/tsdoc-metadata.json +11 -0
  96. package/docs/.gitattributes +2 -0
  97. package/docs/api/ai-assistant.ai_activity_channel_name.md +11 -0
  98. package/docs/api/ai-assistant.aiactivityevents.md +24 -0
  99. package/docs/api/ai-assistant.aiactivityhalo.channelname.md +16 -0
  100. package/docs/api/ai-assistant.aiactivityhalo.connectedcallback.md +18 -0
  101. package/docs/api/ai-assistant.aiactivityhalo.disconnectedcallback.md +18 -0
  102. package/docs/api/ai-assistant.aiactivityhalo.haloactive.md +14 -0
  103. package/docs/api/ai-assistant.aiactivityhalo.md +176 -0
  104. package/docs/api/ai-assistant.aiactivityhalo.minshowtime.md +16 -0
  105. package/docs/api/ai-assistant.aiactivityhalo.tools.md +16 -0
  106. package/docs/api/ai-assistant.aiassistantanimation.md +18 -0
  107. package/docs/api/ai-assistant.aiassistantanimationdef.label.md +16 -0
  108. package/docs/api/ai-assistant.aiassistantanimationdef.md +80 -0
  109. package/docs/api/ai-assistant.aiassistantanimationdef.tooltip.md +16 -0
  110. package/docs/api/ai-assistant.aiassistantconfig.chatconfig.md +16 -0
  111. package/docs/api/ai-assistant.aiassistantconfig.debugstatefactory.md +16 -0
  112. package/docs/api/ai-assistant.aiassistantconfig.headertitle.md +16 -0
  113. package/docs/api/ai-assistant.aiassistantconfig.md +157 -0
  114. package/docs/api/ai-assistant.aiassistantconfig.systemprompt.md +16 -0
  115. package/docs/api/ai-assistant.aiassistantconfig.tooldefinitions.md +16 -0
  116. package/docs/api/ai-assistant.aiassistantconfig.toolhandlers.md +16 -0
  117. package/docs/api/ai-assistant.aiassistantserializedstate.enabledanimations.md +14 -0
  118. package/docs/api/ai-assistant.aiassistantserializedstate.md +118 -0
  119. package/docs/api/ai-assistant.aiassistantserializedstate.messages.md +14 -0
  120. package/docs/api/ai-assistant.aiassistantserializedstate.showthinkingsteps.md +14 -0
  121. package/docs/api/ai-assistant.aiassistantserializedstate.showtoolcalls.md +14 -0
  122. package/docs/api/ai-assistant.aiassistantstate.md +16 -0
  123. package/docs/api/ai-assistant.aichatbubble.bubbleleft.md +11 -0
  124. package/docs/api/ai-assistant.aichatbubble.bubbletop.md +11 -0
  125. package/docs/api/ai-assistant.aichatbubble.channelname.md +11 -0
  126. package/docs/api/ai-assistant.aichatbubble.connectedcallback.md +15 -0
  127. package/docs/api/ai-assistant.aichatbubble.designsystemprefix.md +11 -0
  128. package/docs/api/ai-assistant.aichatbubble.dialogcontent.md +11 -0
  129. package/docs/api/ai-assistant.aichatbubble.dialogcontentchanged.md +64 -0
  130. package/docs/api/ai-assistant.aichatbubble.dialogheight.md +11 -0
  131. package/docs/api/ai-assistant.aichatbubble.dialogleft.md +11 -0
  132. package/docs/api/ai-assistant.aichatbubble.dialogopen.md +11 -0
  133. package/docs/api/ai-assistant.aichatbubble.dialogopenchanged.md +64 -0
  134. package/docs/api/ai-assistant.aichatbubble.dialogtop.md +11 -0
  135. package/docs/api/ai-assistant.aichatbubble.dialogwidth.md +11 -0
  136. package/docs/api/ai-assistant.aichatbubble.disconnectedcallback.md +15 -0
  137. package/docs/api/ai-assistant.aichatbubble.hovered.md +11 -0
  138. package/docs/api/ai-assistant.aichatbubble.imagesrc.md +11 -0
  139. package/docs/api/ai-assistant.aichatbubble.md +396 -0
  140. package/docs/api/ai-assistant.aichatbubble.onbubblemousedown.md +50 -0
  141. package/docs/api/ai-assistant.aichatbubble.onclosedialog.md +15 -0
  142. package/docs/api/ai-assistant.aichatbubble.ondialogheadermousedown.md +53 -0
  143. package/docs/api/ai-assistant.aichatbubble.onpopout.md +15 -0
  144. package/docs/api/ai-assistant.aichatbubble.title.md +11 -0
  145. package/docs/api/ai-assistant.aichatbubble.tooltipstyle.md +11 -0
  146. package/docs/api/ai-assistant.aichatwidget.data.md +14 -0
  147. package/docs/api/ai-assistant.aichatwidget.md +80 -0
  148. package/docs/api/ai-assistant.aichatwidget.resolved.md +16 -0
  149. package/docs/api/ai-assistant.animation_defs.md +25 -0
  150. package/docs/api/ai-assistant.chatdriver._constructor_.md +99 -0
  151. package/docs/api/ai-assistant.chatdriver.gethistory.md +18 -0
  152. package/docs/api/ai-assistant.chatdriver.isbusy.md +18 -0
  153. package/docs/api/ai-assistant.chatdriver.loadhistory.md +55 -0
  154. package/docs/api/ai-assistant.chatdriver.md +158 -0
  155. package/docs/api/ai-assistant.chatdriver.requestinteraction.md +73 -0
  156. package/docs/api/ai-assistant.chatdriver.resolveinteraction.md +69 -0
  157. package/docs/api/ai-assistant.chatdriver.sendmessage.md +69 -0
  158. package/docs/api/ai-assistant.chathistoryupdatedevent.md +16 -0
  159. package/docs/api/ai-assistant.defaultaiassistantconfig.md +16 -0
  160. package/docs/api/ai-assistant.foundationaiassistant.aiprovider.md +14 -0
  161. package/docs/api/ai-assistant.foundationaiassistant.applystate.md +55 -0
  162. package/docs/api/ai-assistant.foundationaiassistant.attachmenterrors.md +14 -0
  163. package/docs/api/ai-assistant.foundationaiassistant.attachments.md +14 -0
  164. package/docs/api/ai-assistant.foundationaiassistant.channelname.md +14 -0
  165. package/docs/api/ai-assistant.foundationaiassistant.chatconfig.md +14 -0
  166. package/docs/api/ai-assistant.foundationaiassistant.connectedcallback.md +18 -0
  167. package/docs/api/ai-assistant.foundationaiassistant.debugstatefactory.md +14 -0
  168. package/docs/api/ai-assistant.foundationaiassistant.designsystemprefix.md +14 -0
  169. package/docs/api/ai-assistant.foundationaiassistant.disconnectedcallback.md +18 -0
  170. package/docs/api/ai-assistant.foundationaiassistant.downloadhistory.md +18 -0
  171. package/docs/api/ai-assistant.foundationaiassistant.enabledanimations.md +16 -0
  172. package/docs/api/ai-assistant.foundationaiassistant.handlefileselect.md +53 -0
  173. package/docs/api/ai-assistant.foundationaiassistant.handleinteractioncompleted.md +53 -0
  174. package/docs/api/ai-assistant.foundationaiassistant.handlepopout.md +20 -0
  175. package/docs/api/ai-assistant.foundationaiassistant.handlesendclick.md +18 -0
  176. package/docs/api/ai-assistant.foundationaiassistant.hasactivependinginteraction.md +16 -0
  177. package/docs/api/ai-assistant.foundationaiassistant.headertitle.md +14 -0
  178. package/docs/api/ai-assistant.foundationaiassistant.imagesrc.md +14 -0
  179. package/docs/api/ai-assistant.foundationaiassistant.inputvalue.md +14 -0
  180. package/docs/api/ai-assistant.foundationaiassistant.md +826 -0
  181. package/docs/api/ai-assistant.foundationaiassistant.messages.md +14 -0
  182. package/docs/api/ai-assistant.foundationaiassistant.messageschanged.md +18 -0
  183. package/docs/api/ai-assistant.foundationaiassistant.onchatheadermousedown.md +53 -0
  184. package/docs/api/ai-assistant.foundationaiassistant.placeholder.md +14 -0
  185. package/docs/api/ai-assistant.foundationaiassistant.popoutmode.md +16 -0
  186. package/docs/api/ai-assistant.foundationaiassistant.removeattachment.md +53 -0
  187. package/docs/api/ai-assistant.foundationaiassistant.removeattachmenterror.md +53 -0
  188. package/docs/api/ai-assistant.foundationaiassistant.setenabledanimations.md +53 -0
  189. package/docs/api/ai-assistant.foundationaiassistant.settingsopen.md +16 -0
  190. package/docs/api/ai-assistant.foundationaiassistant.showhalo.md +16 -0
  191. package/docs/api/ai-assistant.foundationaiassistant.showhalochanged.md +18 -0
  192. package/docs/api/ai-assistant.foundationaiassistant.showloadingindicator.md +16 -0
  193. package/docs/api/ai-assistant.foundationaiassistant.showloadingindicatorchanged.md +18 -0
  194. package/docs/api/ai-assistant.foundationaiassistant.showthinkingsteps.md +16 -0
  195. package/docs/api/ai-assistant.foundationaiassistant.showtoolcalls.md +16 -0
  196. package/docs/api/ai-assistant.foundationaiassistant.state.md +14 -0
  197. package/docs/api/ai-assistant.foundationaiassistant.statechanged.md +18 -0
  198. package/docs/api/ai-assistant.foundationaiassistant.systemprompt.md +14 -0
  199. package/docs/api/ai-assistant.foundationaiassistant.togglesettings.md +18 -0
  200. package/docs/api/ai-assistant.foundationaiassistant.toggleshowthinkingsteps.md +18 -0
  201. package/docs/api/ai-assistant.foundationaiassistant.toggleshowtoolcalls.md +18 -0
  202. package/docs/api/ai-assistant.foundationaiassistant.tooldefinitions.md +14 -0
  203. package/docs/api/ai-assistant.foundationaiassistant.toolhandlers.md +14 -0
  204. package/docs/api/ai-assistant.foundationaiassistant.triggerfileinput.md +18 -0
  205. package/docs/api/ai-assistant.foundationaiassistant.visiblemessages.md +16 -0
  206. package/docs/api/ai-assistant.foundationaiassistanttemplate.md +50 -0
  207. package/docs/api/ai-assistant.md +262 -0
  208. package/docs/api/ai-assistant.popoutmode.md +16 -0
  209. package/docs/api/index.md +30 -0
  210. package/docs/api-report.md.api.md +280 -0
  211. package/license.txt +46 -0
  212. package/package.json +92 -0
  213. package/src/channel/ai-activity-channel.ts +30 -0
  214. package/src/components/activity-halo/activity-halo.ts +113 -0
  215. package/src/components/chat-bubble/chat-bubble.styles.ts +194 -0
  216. package/src/components/chat-bubble/chat-bubble.template.ts +63 -0
  217. package/src/components/chat-bubble/chat-bubble.ts +389 -0
  218. package/src/components/chat-bubble/index.ts +1 -0
  219. package/src/components/chat-driver/chat-driver.ts +254 -0
  220. package/src/components/chat-driver/index.ts +1 -0
  221. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.ts +7 -0
  222. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.template.ts +6 -0
  223. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +89 -0
  224. package/src/components/chat-interaction-wrapper/index.ts +3 -0
  225. package/src/components/chat-markdown/chat-markdown.ts +87 -0
  226. package/src/components/chat-markdown/index.ts +1 -0
  227. package/src/components/halo-overlay.ts +115 -0
  228. package/src/config/config.ts +59 -0
  229. package/src/config/configure.ts +0 -0
  230. package/src/config/index.ts +1 -0
  231. package/src/index.ts +9 -0
  232. package/src/main/index.ts +4 -0
  233. package/src/main/main.styles.ts +357 -0
  234. package/src/main/main.template.ts +364 -0
  235. package/src/main/main.ts +474 -0
  236. package/src/main/main.types.ts +58 -0
  237. package/src/styles/index.ts +1 -0
  238. package/src/styles/styles.ts +238 -0
  239. package/src/tags/index.ts +0 -0
  240. package/src/types/ai-chat-widget.ts +11 -0
  241. package/src/utils/index.ts +1 -0
  242. package/src/utils/logger.ts +3 -0
  243. package/temp/api-report.md.api.md +280 -0
  244. package/tsconfig.json +11 -0
@@ -0,0 +1,491 @@
1
+ var FoundationAiAssistant_1;
2
+ import { __awaiter, __decorate } from "tslib";
3
+ import { AIProvider } from '@genesislcap/foundation-ai';
4
+ import { createTypedBroadcastChannel } from '@genesislcap/foundation-broadcast-channel';
5
+ import { customElement, html, GenesisElement, observable, volatile, attr, } from '@genesislcap/web-core';
6
+ import { AI_ACTIVITY_CHANNEL_NAME } from '../channel/ai-activity-channel';
7
+ import { ChatDriver } from '../components/chat-driver/chat-driver';
8
+ import { AiChatInteractionWrapper } from '../components/chat-interaction-wrapper/chat-interaction-wrapper';
9
+ import { AiChatMarkdown } from '../components/chat-markdown/chat-markdown';
10
+ import { AiHaloOverlay } from '../components/halo-overlay';
11
+ import { logger } from '../utils/logger';
12
+ import { styles } from './main.styles';
13
+ import { FoundationAiAssistantTemplate } from './main.template';
14
+ import { ALL_ANIMATIONS } from './main.types';
15
+ AiChatMarkdown;
16
+ AiChatInteractionWrapper;
17
+ AiHaloOverlay;
18
+ /**
19
+ * Foundation AI Assistant component.
20
+ *
21
+ * @remarks
22
+ * Lazy-loaded via `configure()`. Inject an `AIProvider` and `AiAssistantConfig` through the DI
23
+ * container. The component creates a `ChatDriver` to manage the conversation loop.
24
+ *
25
+ * @beta
26
+ */
27
+ let FoundationAiAssistant = FoundationAiAssistant_1 = class FoundationAiAssistant extends GenesisElement {
28
+ constructor() {
29
+ super(...arguments);
30
+ this.designSystemPrefix = 'rapid';
31
+ this.channelName = AI_ACTIVITY_CHANNEL_NAME;
32
+ this.placeholder = 'Message assistant...';
33
+ this.chatConfig = {};
34
+ this.messages = [];
35
+ this.state = 'idle';
36
+ this.inputValue = '';
37
+ this.attachments = [];
38
+ this.attachmentErrors = [];
39
+ /** Current user-facing toggle state for tool call visibility. */
40
+ this.showToolCalls = false;
41
+ /** Current user-facing toggle state for thinking step visibility. */
42
+ this.showThinkingSteps = false;
43
+ /** Currently enabled animations. */
44
+ this.enabledAnimations = [];
45
+ /** Whether the loading spinner is currently visible. Controlled by the loading delay timer. */
46
+ this.showLoadingIndicator = false;
47
+ /** Whether the settings panel is open. */
48
+ this.settingsOpen = false;
49
+ this.haloStartPublished = false;
50
+ /**
51
+ * Whether the halo animation should be shown.
52
+ * True when the AI is actively computing (loading state, no pending interaction).
53
+ */
54
+ this.showHalo = false;
55
+ this.onChannelMessage = (event) => {
56
+ var _a, _b;
57
+ if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'chat-popin' && ((_b = event.data.detail) === null || _b === void 0 ? void 0 : _b.state)) {
58
+ this.applyState(event.data.detail.state);
59
+ }
60
+ };
61
+ }
62
+ syncShowHalo() {
63
+ if (this.state !== 'loading') {
64
+ this.showHalo = false;
65
+ return;
66
+ }
67
+ const last = this.messages[this.messages.length - 1];
68
+ this.showHalo = !(last === null || last === void 0 ? void 0 : last.interaction);
69
+ }
70
+ /** True when there is a pending (unresolved) interaction — disables the popout button. */
71
+ get hasActivePendingInteraction() {
72
+ if (this.state !== 'loading')
73
+ return false;
74
+ const last = this.messages[this.messages.length - 1];
75
+ return !!(last === null || last === void 0 ? void 0 : last.interaction) && !last.interaction.resolved;
76
+ }
77
+ showHaloChanged() {
78
+ var _a, _b;
79
+ if (!((_a = this.enabledAnimations) === null || _a === void 0 ? void 0 : _a.includes('halo')))
80
+ return;
81
+ if (!this.showHalo) {
82
+ (_b = this.activityChannel) === null || _b === void 0 ? void 0 : _b.postMessage('halo-stop');
83
+ this.haloStartPublished = false;
84
+ }
85
+ // halo-start is published exclusively from messagesChanged when toolCalls arrive,
86
+ // so we never re-activate grids on non-toolCall transitions (e.g. tool results
87
+ // arriving after an interaction resolves).
88
+ }
89
+ getActiveToolNames() {
90
+ var _a;
91
+ for (let i = this.messages.length - 1; i >= 0; i -= 1) {
92
+ const msg = this.messages[i];
93
+ if ((_a = msg.toolCalls) === null || _a === void 0 ? void 0 : _a.length) {
94
+ return msg.toolCalls.map((tc) => tc.name);
95
+ }
96
+ }
97
+ return [];
98
+ }
99
+ /**
100
+ * Messages filtered by the current toggle state.
101
+ * Tool-related messages (those with toolCalls or toolResult) are hidden when
102
+ * `showToolCalls` is false.
103
+ */
104
+ get visibleMessages() {
105
+ return this.messages.filter((m) => {
106
+ var _a, _b, _c;
107
+ // Never show tool messages to the user
108
+ if (m.role === 'tool') {
109
+ return false;
110
+ }
111
+ // Filter thinking messages based on toggle
112
+ if (m.thinking && !this.showThinkingSteps) {
113
+ return false;
114
+ }
115
+ // Filter out empty assistant messages that might have slipped through
116
+ if (m.role === 'assistant' && !((_a = m.content) === null || _a === void 0 ? void 0 : _a.trim()) && !((_b = m.toolCalls) === null || _b === void 0 ? void 0 : _b.length) && !m.interaction) {
117
+ return false;
118
+ }
119
+ const isToolRelated = !!(((_c = m.toolCalls) === null || _c === void 0 ? void 0 : _c.length) || m.toolResult);
120
+ return !isToolRelated || this.showToolCalls;
121
+ });
122
+ }
123
+ connectedCallback() {
124
+ var _a, _b, _c;
125
+ super.connectedCallback();
126
+ this.activityChannel = createTypedBroadcastChannel(this.channelName);
127
+ const { showToolCalls, showThinkingSteps, animations } = this.chatConfig;
128
+ this.showToolCalls = showToolCalls === true;
129
+ this.showThinkingSteps = showThinkingSteps === true;
130
+ this.enabledAnimations =
131
+ (_a = animations === null || animations === void 0 ? void 0 : animations.enabled) !== null && _a !== void 0 ? _a : (animations ? [...ALL_ANIMATIONS] : []);
132
+ this.driver = new ChatDriver(this.aiProvider, (_b = this.toolHandlers) !== null && _b !== void 0 ? _b : {}, (_c = this.toolDefinitions) !== null && _c !== void 0 ? _c : [], this.systemPrompt);
133
+ this.driver.addEventListener('history-updated', (e) => {
134
+ this.messages = [...e.detail];
135
+ });
136
+ // When embedded in a bubble (expand mode), listen for chat-popin to restore state
137
+ // when the layout panel collapses back.
138
+ if (this.popoutMode === 'expand') {
139
+ this.activityChannel.addEventListener('message', this.onChannelMessage);
140
+ }
141
+ logger.debug('FoundationAiAssistant connected');
142
+ }
143
+ disconnectedCallback() {
144
+ var _a, _b;
145
+ super.disconnectedCallback();
146
+ this.stopLoadingTimer();
147
+ this.state = 'idle';
148
+ (_a = this.activityChannel) === null || _a === void 0 ? void 0 : _a.removeEventListener('message', this.onChannelMessage);
149
+ (_b = this.activityChannel) === null || _b === void 0 ? void 0 : _b.close();
150
+ this.activityChannel = undefined;
151
+ this.driver = undefined;
152
+ }
153
+ stateChanged() {
154
+ this.syncShowHalo();
155
+ }
156
+ messagesChanged() {
157
+ var _a, _b, _c, _d;
158
+ // Reset the loading timer when an assistant message arrives mid-loop so each
159
+ // individual step gets a fresh window before the spinner appears.
160
+ // If the last message is a blocking interaction, stop the timer — the AI is
161
+ // waiting for the user, not computing.
162
+ if (this.state === 'loading') {
163
+ const last = this.messages[this.messages.length - 1];
164
+ if (last === null || last === void 0 ? void 0 : last.interaction) {
165
+ this.stopLoadingTimer();
166
+ }
167
+ else if ((last === null || last === void 0 ? void 0 : last.role) === 'assistant') {
168
+ this.startLoadingTimer();
169
+ }
170
+ }
171
+ this.syncShowHalo();
172
+ // Publish halo-start whenever a new toolCalls message arrives.
173
+ // If we've already published one this turn, send halo-stop first so grids
174
+ // not relevant to the new tools begin deactivating (fix #2).
175
+ // Never publish with empty toolNames (fix #3).
176
+ if (this.showHalo && ((_a = this.enabledAnimations) === null || _a === void 0 ? void 0 : _a.includes('halo'))) {
177
+ const last = this.messages[this.messages.length - 1];
178
+ if ((_b = last === null || last === void 0 ? void 0 : last.toolCalls) === null || _b === void 0 ? void 0 : _b.length) {
179
+ const toolNames = this.getActiveToolNames();
180
+ if (toolNames.length) {
181
+ if (this.haloStartPublished) {
182
+ (_c = this.activityChannel) === null || _c === void 0 ? void 0 : _c.postMessage('halo-stop');
183
+ }
184
+ (_d = this.activityChannel) === null || _d === void 0 ? void 0 : _d.postMessage('halo-start', { toolNames });
185
+ this.haloStartPublished = true;
186
+ }
187
+ }
188
+ }
189
+ this.scrollToBottom();
190
+ }
191
+ showLoadingIndicatorChanged() {
192
+ // Scroll to bottom when the spinner appears so it is visible.
193
+ if (this.showLoadingIndicator) {
194
+ this.scrollToBottom();
195
+ }
196
+ }
197
+ // Double rAF: first frame lets the framework flush the DOM update,
198
+ // second frame reads the correct scrollHeight after layout.
199
+ scrollToBottom() {
200
+ requestAnimationFrame(() => {
201
+ requestAnimationFrame(() => {
202
+ var _a;
203
+ const el = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.messages');
204
+ if (el)
205
+ el.scrollTop = el.scrollHeight;
206
+ });
207
+ });
208
+ }
209
+ startLoadingTimer() {
210
+ var _a;
211
+ this.clearLoadingTimer();
212
+ const delay = (_a = this.chatConfig.loadingDelay) !== null && _a !== void 0 ? _a : FoundationAiAssistant_1.DEFAULT_LOADING_DELAY_S;
213
+ if (delay === 0) {
214
+ this.showLoadingIndicator = true;
215
+ }
216
+ else {
217
+ this.loadingTimer = setTimeout(() => {
218
+ this.showLoadingIndicator = true;
219
+ }, delay * FoundationAiAssistant_1.MS_PER_SECOND);
220
+ }
221
+ }
222
+ clearLoadingTimer() {
223
+ if (this.loadingTimer !== undefined) {
224
+ clearTimeout(this.loadingTimer);
225
+ this.loadingTimer = undefined;
226
+ }
227
+ }
228
+ stopLoadingTimer() {
229
+ this.clearLoadingTimer();
230
+ this.showLoadingIndicator = false;
231
+ }
232
+ /** Called when the user clicks the popout button. */
233
+ handlePopout() {
234
+ var _a, _b;
235
+ if (this.popoutMode === 'expand') {
236
+ (_a = this.activityChannel) === null || _a === void 0 ? void 0 : _a.postMessage('chat-popout', { state: this.serializeState() });
237
+ }
238
+ else if (this.popoutMode === 'collapse') {
239
+ (_b = this.activityChannel) === null || _b === void 0 ? void 0 : _b.postMessage('chat-popin', { state: this.serializeState() });
240
+ }
241
+ }
242
+ /** Applies a serialized state snapshot to this live instance (used on collapse path). */
243
+ applyState(state) {
244
+ var _a;
245
+ this.messages = [...state.messages];
246
+ this.showToolCalls = state.showToolCalls;
247
+ this.showThinkingSteps = state.showThinkingSteps;
248
+ this.enabledAnimations = [...state.enabledAnimations];
249
+ (_a = this.driver) === null || _a === void 0 ? void 0 : _a.loadHistory(state.messages);
250
+ }
251
+ serializeState() {
252
+ return {
253
+ messages: [...this.messages],
254
+ showToolCalls: this.showToolCalls,
255
+ showThinkingSteps: this.showThinkingSteps,
256
+ enabledAnimations: [...this.enabledAnimations],
257
+ };
258
+ }
259
+ toggleSettings() {
260
+ this.settingsOpen = !this.settingsOpen;
261
+ }
262
+ toggleShowToolCalls() {
263
+ this.showToolCalls = !this.showToolCalls;
264
+ }
265
+ toggleShowThinkingSteps() {
266
+ this.showThinkingSteps = !this.showThinkingSteps;
267
+ }
268
+ setEnabledAnimations(animations) {
269
+ this.enabledAnimations = animations;
270
+ }
271
+ downloadHistory() {
272
+ var _a, _b;
273
+ const timestamp = new Date().toISOString().replace(/:/g, '-');
274
+ const agentName = ((_a = this.headerTitle) !== null && _a !== void 0 ? _a : 'chat').toLowerCase().replace(/\s+/g, '-');
275
+ const payload = {
276
+ messages: this.messages,
277
+ debug: (_b = this.debugStateFactory) === null || _b === void 0 ? void 0 : _b.call(this),
278
+ };
279
+ const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' });
280
+ const url = URL.createObjectURL(blob);
281
+ const a = document.createElement('a');
282
+ a.href = url;
283
+ a.download = `${agentName}-${timestamp}.json`;
284
+ a.click();
285
+ URL.revokeObjectURL(url);
286
+ }
287
+ triggerFileInput() {
288
+ var _a, _b;
289
+ (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.file-input')) === null || _b === void 0 ? void 0 : _b.click();
290
+ }
291
+ handleFileSelect(e) {
292
+ void this.loadSelectedFiles(e);
293
+ }
294
+ removeAttachment(attachment) {
295
+ this.attachments = this.attachments.filter((a) => a !== attachment);
296
+ }
297
+ removeAttachmentError(message) {
298
+ const idx = this.attachmentErrors.indexOf(message);
299
+ if (idx !== -1) {
300
+ this.attachmentErrors = [
301
+ ...this.attachmentErrors.slice(0, idx),
302
+ ...this.attachmentErrors.slice(idx + 1),
303
+ ];
304
+ }
305
+ }
306
+ isAcceptedFile(file) {
307
+ var _a, _b;
308
+ const accepted = this.chatConfig.acceptedFiles;
309
+ if (!accepted)
310
+ return false;
311
+ const acceptedList = accepted.split(',').map((s) => s.trim().toLowerCase());
312
+ const ext = `.${(_b = (_a = file.name.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : ''}`;
313
+ return acceptedList.some((a) => a === ext ||
314
+ a === file.type ||
315
+ (a.endsWith('/*') && file.type.startsWith(a.replace('/*', '/'))));
316
+ }
317
+ readFileAsText(file) {
318
+ return new Promise((resolve, reject) => {
319
+ const reader = new FileReader();
320
+ reader.onload = () => resolve(reader.result);
321
+ reader.onerror = () => reject(new Error(`Failed to read file: ${file.name}`));
322
+ reader.readAsText(file);
323
+ });
324
+ }
325
+ loadSelectedFiles(e) {
326
+ return __awaiter(this, void 0, void 0, function* () {
327
+ var _a;
328
+ const input = e.target;
329
+ const files = Array.from((_a = input.files) !== null && _a !== void 0 ? _a : []);
330
+ input.value = '';
331
+ const results = yield Promise.all(files.map((file) => __awaiter(this, void 0, void 0, function* () {
332
+ if (!this.isAcceptedFile(file)) {
333
+ return { ok: false, message: `"${file.name}" is not an accepted file type.` };
334
+ }
335
+ try {
336
+ const content = yield this.readFileAsText(file);
337
+ return {
338
+ ok: true,
339
+ attachment: { name: file.name, content, mimeType: file.type || 'text/plain' },
340
+ };
341
+ }
342
+ catch (readError) {
343
+ logger.error('Failed to read file:', readError);
344
+ return { ok: false, message: `Failed to read "${file.name}".` };
345
+ }
346
+ })));
347
+ const newAttachments = results
348
+ .filter((r) => r.ok)
349
+ .map((r) => r.attachment);
350
+ const newErrors = results
351
+ .filter((r) => !r.ok)
352
+ .map((r) => r.message);
353
+ if (newAttachments.length)
354
+ this.attachments = [...this.attachments, ...newAttachments];
355
+ if (newErrors.length)
356
+ this.attachmentErrors = [...this.attachmentErrors, ...newErrors];
357
+ });
358
+ }
359
+ handleSendClick() {
360
+ this.send();
361
+ }
362
+ send() {
363
+ return __awaiter(this, void 0, void 0, function* () {
364
+ var _a;
365
+ const input = this.inputValue.trim();
366
+ if ((!input && !this.attachments.length) || this.state === 'loading')
367
+ return;
368
+ const pendingAttachments = this.attachments.length ? [...this.attachments] : undefined;
369
+ this.inputValue = '';
370
+ this.attachments = [];
371
+ this.attachmentErrors = [];
372
+ this.state = 'loading';
373
+ this.startLoadingTimer();
374
+ const displayInput = (pendingAttachments === null || pendingAttachments === void 0 ? void 0 : pendingAttachments.length)
375
+ ? `${input}\n\n*Attached: ${pendingAttachments.map((a) => a.name).join(', ')}*`
376
+ : input;
377
+ try {
378
+ yield ((_a = this.driver) === null || _a === void 0 ? void 0 : _a.sendMessage(displayInput, pendingAttachments));
379
+ }
380
+ finally {
381
+ this.stopLoadingTimer();
382
+ this.state = 'idle';
383
+ }
384
+ });
385
+ }
386
+ onChatHeaderMouseDown(e) {
387
+ if (this.popoutMode !== 'expand')
388
+ return;
389
+ e.preventDefault();
390
+ this.dispatchEvent(new CustomEvent('chat-header-mousedown', {
391
+ bubbles: true,
392
+ composed: true,
393
+ detail: { clientX: e.clientX, clientY: e.clientY },
394
+ }));
395
+ }
396
+ handleInteractionCompleted(e) {
397
+ var _a;
398
+ const detail = e.detail;
399
+ if (detail && detail.interactionId) {
400
+ this.startLoadingTimer();
401
+ (_a = this.driver) === null || _a === void 0 ? void 0 : _a.resolveInteraction(detail.interactionId, detail);
402
+ }
403
+ }
404
+ };
405
+ FoundationAiAssistant.DEFAULT_LOADING_DELAY_S = 5;
406
+ FoundationAiAssistant.MS_PER_SECOND = 1000;
407
+ __decorate([
408
+ AIProvider
409
+ ], FoundationAiAssistant.prototype, "aiProvider", void 0);
410
+ __decorate([
411
+ observable
412
+ ], FoundationAiAssistant.prototype, "designSystemPrefix", void 0);
413
+ __decorate([
414
+ attr({ attribute: 'header-title' })
415
+ ], FoundationAiAssistant.prototype, "headerTitle", void 0);
416
+ __decorate([
417
+ attr({ attribute: 'channel-name' })
418
+ ], FoundationAiAssistant.prototype, "channelName", void 0);
419
+ __decorate([
420
+ attr({ attribute: 'image-src' })
421
+ ], FoundationAiAssistant.prototype, "imageSrc", void 0);
422
+ __decorate([
423
+ attr()
424
+ ], FoundationAiAssistant.prototype, "placeholder", void 0);
425
+ __decorate([
426
+ attr({ attribute: 'popout-mode' })
427
+ ], FoundationAiAssistant.prototype, "popoutMode", void 0);
428
+ __decorate([
429
+ observable
430
+ ], FoundationAiAssistant.prototype, "systemPrompt", void 0);
431
+ __decorate([
432
+ observable
433
+ ], FoundationAiAssistant.prototype, "toolDefinitions", void 0);
434
+ __decorate([
435
+ observable
436
+ ], FoundationAiAssistant.prototype, "toolHandlers", void 0);
437
+ __decorate([
438
+ observable
439
+ ], FoundationAiAssistant.prototype, "chatConfig", void 0);
440
+ __decorate([
441
+ observable
442
+ ], FoundationAiAssistant.prototype, "debugStateFactory", void 0);
443
+ __decorate([
444
+ observable
445
+ ], FoundationAiAssistant.prototype, "messages", void 0);
446
+ __decorate([
447
+ observable
448
+ ], FoundationAiAssistant.prototype, "state", void 0);
449
+ __decorate([
450
+ observable
451
+ ], FoundationAiAssistant.prototype, "inputValue", void 0);
452
+ __decorate([
453
+ observable
454
+ ], FoundationAiAssistant.prototype, "attachments", void 0);
455
+ __decorate([
456
+ observable
457
+ ], FoundationAiAssistant.prototype, "attachmentErrors", void 0);
458
+ __decorate([
459
+ observable
460
+ ], FoundationAiAssistant.prototype, "showToolCalls", void 0);
461
+ __decorate([
462
+ observable
463
+ ], FoundationAiAssistant.prototype, "showThinkingSteps", void 0);
464
+ __decorate([
465
+ observable
466
+ ], FoundationAiAssistant.prototype, "enabledAnimations", void 0);
467
+ __decorate([
468
+ observable
469
+ ], FoundationAiAssistant.prototype, "showLoadingIndicator", void 0);
470
+ __decorate([
471
+ observable
472
+ ], FoundationAiAssistant.prototype, "settingsOpen", void 0);
473
+ __decorate([
474
+ observable
475
+ ], FoundationAiAssistant.prototype, "showHalo", void 0);
476
+ __decorate([
477
+ volatile
478
+ ], FoundationAiAssistant.prototype, "hasActivePendingInteraction", null);
479
+ __decorate([
480
+ volatile
481
+ ], FoundationAiAssistant.prototype, "visibleMessages", null);
482
+ FoundationAiAssistant = FoundationAiAssistant_1 = __decorate([
483
+ customElement({
484
+ name: 'foundation-ai-assistant',
485
+ template: html `
486
+ ${(x) => FoundationAiAssistantTemplate(x.designSystemPrefix)}
487
+ `,
488
+ styles,
489
+ })
490
+ ], FoundationAiAssistant);
491
+ export { FoundationAiAssistant };