@amodalai/chat-widget 0.1.0

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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chat-widget.css +5 -0
  3. package/dist/chat-widget.js +2311 -0
  4. package/dist/chat-widget.js.map +1 -0
  5. package/dist/client/ChatClient.d.ts +76 -0
  6. package/dist/client/ChatClient.d.ts.map +1 -0
  7. package/dist/client/ChatStream.d.ts +63 -0
  8. package/dist/client/ChatStream.d.ts.map +1 -0
  9. package/dist/client/EventEmitter.d.ts +16 -0
  10. package/dist/client/EventEmitter.d.ts.map +1 -0
  11. package/dist/client/index.d.ts +13 -0
  12. package/dist/client/index.d.ts.map +1 -0
  13. package/dist/client.d.ts +85 -0
  14. package/dist/client.d.ts.map +1 -0
  15. package/dist/client.js +9 -0
  16. package/dist/client.js.map +1 -0
  17. package/dist/components/AskUserCard.d.ts +8 -0
  18. package/dist/components/AskUserCard.d.ts.map +1 -0
  19. package/dist/components/ChatWidget.d.ts +9 -0
  20. package/dist/components/ChatWidget.d.ts.map +1 -0
  21. package/dist/components/FormattedText.d.ts +12 -0
  22. package/dist/components/FormattedText.d.ts.map +1 -0
  23. package/dist/components/InputBar.d.ts +15 -0
  24. package/dist/components/InputBar.d.ts.map +1 -0
  25. package/dist/components/KBProposalCard.d.ts +7 -0
  26. package/dist/components/KBProposalCard.d.ts.map +1 -0
  27. package/dist/components/MessageList.d.ts +15 -0
  28. package/dist/components/MessageList.d.ts.map +1 -0
  29. package/dist/components/SessionHistory.d.ts +12 -0
  30. package/dist/components/SessionHistory.d.ts.map +1 -0
  31. package/dist/components/SkillPill.d.ts +11 -0
  32. package/dist/components/SkillPill.d.ts.map +1 -0
  33. package/dist/components/StreamingIndicator.d.ts +7 -0
  34. package/dist/components/StreamingIndicator.d.ts.map +1 -0
  35. package/dist/components/TagEditor.d.ts +11 -0
  36. package/dist/components/TagEditor.d.ts.map +1 -0
  37. package/dist/components/ToolCallCard.d.ts +7 -0
  38. package/dist/components/ToolCallCard.d.ts.map +1 -0
  39. package/dist/components/widgets/AlertCard.d.ts +3 -0
  40. package/dist/components/widgets/AlertCard.d.ts.map +1 -0
  41. package/dist/components/widgets/Comparison.d.ts +3 -0
  42. package/dist/components/widgets/Comparison.d.ts.map +1 -0
  43. package/dist/components/widgets/CredentialInput.d.ts +3 -0
  44. package/dist/components/widgets/CredentialInput.d.ts.map +1 -0
  45. package/dist/components/widgets/DataTable.d.ts +3 -0
  46. package/dist/components/widgets/DataTable.d.ts.map +1 -0
  47. package/dist/components/widgets/DocumentPreview.d.ts +3 -0
  48. package/dist/components/widgets/DocumentPreview.d.ts.map +1 -0
  49. package/dist/components/widgets/EntityCard.d.ts +3 -0
  50. package/dist/components/widgets/EntityCard.d.ts.map +1 -0
  51. package/dist/components/widgets/EntityList.d.ts +3 -0
  52. package/dist/components/widgets/EntityList.d.ts.map +1 -0
  53. package/dist/components/widgets/InfoCard.d.ts +3 -0
  54. package/dist/components/widgets/InfoCard.d.ts.map +1 -0
  55. package/dist/components/widgets/Metric.d.ts +3 -0
  56. package/dist/components/widgets/Metric.d.ts.map +1 -0
  57. package/dist/components/widgets/ScopeMap.d.ts +3 -0
  58. package/dist/components/widgets/ScopeMap.d.ts.map +1 -0
  59. package/dist/components/widgets/ScoreBreakdown.d.ts +3 -0
  60. package/dist/components/widgets/ScoreBreakdown.d.ts.map +1 -0
  61. package/dist/components/widgets/StatusBoard.d.ts +3 -0
  62. package/dist/components/widgets/StatusBoard.d.ts.map +1 -0
  63. package/dist/components/widgets/Timeline.d.ts +3 -0
  64. package/dist/components/widgets/Timeline.d.ts.map +1 -0
  65. package/dist/components/widgets/WidgetRenderer.d.ts +28 -0
  66. package/dist/components/widgets/WidgetRenderer.d.ts.map +1 -0
  67. package/dist/events/entity-extractor.d.ts +7 -0
  68. package/dist/events/entity-extractor.d.ts.map +1 -0
  69. package/dist/events/event-bus.d.ts +27 -0
  70. package/dist/events/event-bus.d.ts.map +1 -0
  71. package/dist/events/index.d.ts +9 -0
  72. package/dist/events/index.d.ts.map +1 -0
  73. package/dist/events/types.d.ts +72 -0
  74. package/dist/events/types.d.ts.map +1 -0
  75. package/dist/hooks/useChat.d.ts +52 -0
  76. package/dist/hooks/useChat.d.ts.map +1 -0
  77. package/dist/hooks/useSessionHistory.d.ts +17 -0
  78. package/dist/hooks/useSessionHistory.d.ts.map +1 -0
  79. package/dist/hooks/useWidgetEvents.d.ts +17 -0
  80. package/dist/hooks/useWidgetEvents.d.ts.map +1 -0
  81. package/dist/index-m6lGOMRo.js +641 -0
  82. package/dist/index-m6lGOMRo.js.map +1 -0
  83. package/dist/index.d.ts +25 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/theme.d.ts +11 -0
  86. package/dist/theme.d.ts.map +1 -0
  87. package/dist/types.d.ts +298 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/umd-entry.d.ts +21 -0
  90. package/dist/umd-entry.d.ts.map +1 -0
  91. package/package.json +62 -0
@@ -0,0 +1,641 @@
1
+ var E = Object.defineProperty;
2
+ var I = (r, e, t) => e in r ? E(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var c = (r, e, t) => I(r, typeof e != "symbol" ? e + "" : e, t);
4
+ /**
5
+ * @license
6
+ * Copyright 2025 Amodal Labs, Inc.
7
+ * SPDX-License-Identifier: MIT
8
+ */
9
+ function w(r) {
10
+ if (!r.startsWith("data: ")) return null;
11
+ const e = r.slice(6).trim();
12
+ return e.length === 0 ? null : JSON.parse(e);
13
+ }
14
+ async function* u(r, e, t, s) {
15
+ const o = `${r}/chat/stream`, n = {
16
+ "Content-Type": "application/json"
17
+ };
18
+ s && (n.Authorization = `Bearer ${s}`);
19
+ const l = await fetch(o, {
20
+ method: "POST",
21
+ headers: n,
22
+ body: JSON.stringify(e),
23
+ signal: t
24
+ });
25
+ if (!l.ok)
26
+ throw new Error(`Chat request failed: ${String(l.status)} ${l.statusText}`);
27
+ const i = l.body;
28
+ if (!i)
29
+ throw new Error("Response body is null");
30
+ const a = i.getReader(), d = new TextDecoder();
31
+ let m = "";
32
+ try {
33
+ for (; ; ) {
34
+ const { done: h, value: x } = await a.read();
35
+ if (h) break;
36
+ m += d.decode(x, { stream: !0 });
37
+ const y = m.split(`
38
+ `);
39
+ m = y.pop() ?? "";
40
+ for (const C of y) {
41
+ const _ = C.trim();
42
+ if (_.length === 0) continue;
43
+ const g = w(_);
44
+ g && (yield g);
45
+ }
46
+ }
47
+ if (m.trim().length > 0) {
48
+ const h = w(m.trim());
49
+ h && (yield h);
50
+ }
51
+ } finally {
52
+ a.releaseLock();
53
+ }
54
+ }
55
+ async function b(r, e, t) {
56
+ const s = `${r}/sessions`, o = {
57
+ "Content-Type": "application/json"
58
+ };
59
+ t && (o.Authorization = `Bearer ${t}`);
60
+ const n = { user_id: e.id };
61
+ e.role && (n.role = e.role);
62
+ const l = await fetch(s, {
63
+ method: "POST",
64
+ headers: o,
65
+ body: JSON.stringify(n)
66
+ });
67
+ if (!l.ok)
68
+ throw new Error(`Session creation failed: ${String(l.status)} ${l.statusText}`);
69
+ return await l.json();
70
+ }
71
+ function f(r) {
72
+ const e = {};
73
+ return r && (e.Authorization = `Bearer ${r}`), e;
74
+ }
75
+ async function A(r, e, t) {
76
+ const s = t && t.length > 0 ? `?tags=${t.join(",")}` : "", o = `${r}/sessions/history${s}`, n = await fetch(o, { headers: f(e) });
77
+ if (!n.ok)
78
+ throw new Error(`List sessions failed: ${String(n.status)} ${n.statusText}`);
79
+ return await n.json();
80
+ }
81
+ async function T(r, e, t) {
82
+ const s = `${r}/sessions/history/${e}`, o = await fetch(s, { headers: f(t) });
83
+ if (!o.ok)
84
+ throw new Error(`Get session failed: ${String(o.status)} ${o.statusText}`);
85
+ return await o.json();
86
+ }
87
+ async function $(r, e, t, s) {
88
+ const o = `${r}/sessions/history/${e}`, n = await fetch(o, {
89
+ method: "PATCH",
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ ...f(s)
93
+ },
94
+ body: JSON.stringify(t)
95
+ });
96
+ if (!n.ok)
97
+ throw new Error(`Update session failed: ${String(n.status)} ${n.statusText}`);
98
+ return await n.json();
99
+ }
100
+ function j(r, e) {
101
+ return {
102
+ stream: (t, s) => u(r, t, s, e),
103
+ createSession: (t) => b(r, t, e),
104
+ listSessions: (t) => A(r, e, t),
105
+ getSessionHistory: (t) => T(r, t, e),
106
+ updateSession: (t, s) => $(r, t, s, e)
107
+ };
108
+ }
109
+ /**
110
+ * @license
111
+ * Copyright 2025 Amodal Labs, Inc.
112
+ * SPDX-License-Identifier: MIT
113
+ */
114
+ class S {
115
+ constructor() {
116
+ c(this, "listeners", /* @__PURE__ */ new Map());
117
+ }
118
+ on(e, t) {
119
+ let s = this.listeners.get(e);
120
+ return s || (s = /* @__PURE__ */ new Set(), this.listeners.set(e, s)), s.add(t), this;
121
+ }
122
+ off(e, t) {
123
+ const s = this.listeners.get(e);
124
+ return s && (s.delete(t), s.size === 0 && this.listeners.delete(e)), this;
125
+ }
126
+ emit(e, t) {
127
+ const s = this.listeners.get(e);
128
+ if (s)
129
+ for (const o of s)
130
+ o(t);
131
+ }
132
+ removeAllListeners() {
133
+ return this.listeners.clear(), this;
134
+ }
135
+ }
136
+ /**
137
+ * @license
138
+ * Copyright 2025 Amodal Labs, Inc.
139
+ * SPDX-License-Identifier: MIT
140
+ */
141
+ function v(r) {
142
+ const e = [];
143
+ return r.type === "widget_rendered" && B(r.widgetType, r.data, e), r.type === "tool_executed" && z(r.parameters, e), e;
144
+ }
145
+ function B(r, e, t) {
146
+ switch (r) {
147
+ case "entity-card": {
148
+ typeof e.mac == "string" && t.push({
149
+ entityType: "device",
150
+ entityId: e.mac,
151
+ source: "widget:entity-card"
152
+ }), typeof e.zone == "string" && t.push({
153
+ entityType: "zone",
154
+ entityId: e.zone,
155
+ source: "widget:entity-card"
156
+ });
157
+ break;
158
+ }
159
+ case "entity-list": {
160
+ const s = e.devices;
161
+ if (Array.isArray(s))
162
+ for (const o of s)
163
+ typeof o == "object" && o !== null && "mac" in o && typeof o.mac == "string" && t.push({
164
+ entityType: "device",
165
+ entityId: o.mac,
166
+ source: "widget:entity-list"
167
+ });
168
+ break;
169
+ }
170
+ case "scope-map": {
171
+ const s = e.highlight_zones;
172
+ if (Array.isArray(s))
173
+ for (const n of s)
174
+ typeof n == "string" && t.push({
175
+ entityType: "zone",
176
+ entityId: n,
177
+ source: "widget:scope-map"
178
+ });
179
+ const o = e.highlight_devices;
180
+ if (Array.isArray(o))
181
+ for (const n of o)
182
+ typeof n == "string" && t.push({
183
+ entityType: "device",
184
+ entityId: n,
185
+ source: "widget:scope-map"
186
+ });
187
+ break;
188
+ }
189
+ case "alert-card": {
190
+ const s = e.alert_id ?? e.id;
191
+ typeof s == "string" && t.push({
192
+ entityType: "alert",
193
+ entityId: s,
194
+ source: "widget:alert-card"
195
+ });
196
+ break;
197
+ }
198
+ }
199
+ }
200
+ function z(r, e) {
201
+ typeof r.zone == "string" && e.push({
202
+ entityType: "zone",
203
+ entityId: r.zone,
204
+ source: "tool:parameter"
205
+ }), typeof r.mac == "string" && e.push({
206
+ entityType: "device",
207
+ entityId: r.mac,
208
+ source: "tool:parameter"
209
+ });
210
+ }
211
+ /**
212
+ * @license
213
+ * Copyright 2025 Amodal Labs, Inc.
214
+ * SPDX-License-Identifier: MIT
215
+ */
216
+ class P extends S {
217
+ constructor() {
218
+ super(...arguments);
219
+ c(this, "extractors", [v]);
220
+ }
221
+ /**
222
+ * Process an agent-driven event: emit on its typed channel + '*',
223
+ * then run entity extractors and emit entity_referenced for each found entity.
224
+ */
225
+ processEvent(t) {
226
+ if (this.emit(t.type, t), this.emit("*", t), t.type === "tool_executed" || t.type === "skill_activated" || t.type === "widget_rendered" || t.type === "kb_proposal")
227
+ for (const s of this.extractors) {
228
+ const o = s(t);
229
+ for (const n of o) {
230
+ const l = {
231
+ type: "entity_referenced",
232
+ entity: n,
233
+ sourceEvent: t,
234
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
235
+ };
236
+ this.emit("entity_referenced", l), this.emit("*", l);
237
+ }
238
+ }
239
+ }
240
+ /**
241
+ * Emit an interaction event (entity_hovered, entity_unhovered, entity_clicked).
242
+ * These are emitted on their typed channel + '*' without running extractors,
243
+ * since interaction events already carry their EntityReference.
244
+ */
245
+ emitInteraction(t) {
246
+ this.emit(t.type, t), this.emit("*", t);
247
+ }
248
+ /** Add a custom entity extractor. */
249
+ addExtractor(t) {
250
+ this.extractors.push(t);
251
+ }
252
+ /** Replace all entity extractors (including the default). */
253
+ setExtractors(t) {
254
+ this.extractors = [...t];
255
+ }
256
+ }
257
+ /**
258
+ * @license
259
+ * Copyright 2025 Amodal Labs, Inc.
260
+ * SPDX-License-Identifier: MIT
261
+ */
262
+ class N {
263
+ constructor(e, t, s) {
264
+ c(this, "handlers", {
265
+ text: [],
266
+ tool_call: [],
267
+ tool_result: [],
268
+ skill_activated: [],
269
+ kb_proposal: [],
270
+ widget: [],
271
+ ask_user: [],
272
+ error: [],
273
+ done: []
274
+ });
275
+ c(this, "abortController");
276
+ c(this, "started", !1);
277
+ c(this, "response", {
278
+ text: "",
279
+ toolCalls: [],
280
+ skillsUsed: [],
281
+ kbProposals: []
282
+ });
283
+ c(this, "toolCallNames", /* @__PURE__ */ new Map());
284
+ c(this, "token");
285
+ this.serverUrl = e, this.request = t, this.abortController = new AbortController(), this.token = s, queueMicrotask(() => this.start());
286
+ }
287
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- overload implementation requires broad type
288
+ on(e, t) {
289
+ const s = e;
290
+ return s in this.handlers && this.handlers[s].push(t), this;
291
+ }
292
+ /** Cancel the stream. */
293
+ abort() {
294
+ this.abortController.abort();
295
+ }
296
+ async start() {
297
+ if (!this.started) {
298
+ this.started = !0;
299
+ try {
300
+ const e = u(
301
+ this.serverUrl,
302
+ this.request,
303
+ this.abortController.signal,
304
+ this.token
305
+ );
306
+ for await (const t of e)
307
+ this.processEvent(t);
308
+ for (const t of this.handlers.done)
309
+ t(this.response);
310
+ } catch (e) {
311
+ if (!(e instanceof DOMException && e.name === "AbortError")) {
312
+ const t = e instanceof Error ? e.message : "Unknown error";
313
+ for (const s of this.handlers.error)
314
+ s({ message: t });
315
+ }
316
+ }
317
+ }
318
+ }
319
+ processEvent(e) {
320
+ switch (e.type) {
321
+ case "text_delta":
322
+ this.response.text += e.content;
323
+ for (const t of this.handlers.text)
324
+ t({ text: e.content });
325
+ break;
326
+ case "tool_call_start":
327
+ this.toolCallNames.set(e.tool_id, e.tool_name);
328
+ for (const t of this.handlers.tool_call)
329
+ t({ tool: e.tool_name, params: e.parameters, toolId: e.tool_id });
330
+ this.response.toolCalls.push({
331
+ toolId: e.tool_id,
332
+ toolName: e.tool_name,
333
+ parameters: e.parameters,
334
+ status: "running"
335
+ });
336
+ break;
337
+ case "tool_call_result": {
338
+ const t = this.toolCallNames.get(e.tool_id) ?? "";
339
+ for (const o of this.handlers.tool_result)
340
+ o({ tool: t, data: e.result, duration_ms: e.duration_ms, toolId: e.tool_id });
341
+ const s = this.response.toolCalls.find((o) => o.toolId === e.tool_id);
342
+ s && (s.status = e.status, s.result = e.result, s.duration_ms = e.duration_ms, s.error = e.error);
343
+ break;
344
+ }
345
+ case "skill_activated":
346
+ this.response.skillsUsed.push(e.skill);
347
+ for (const t of this.handlers.skill_activated)
348
+ t({ name: e.skill });
349
+ break;
350
+ case "kb_proposal": {
351
+ const t = {
352
+ scope: e.scope,
353
+ title: e.title,
354
+ reasoning: e.reasoning
355
+ };
356
+ this.response.kbProposals.push(t);
357
+ for (const s of this.handlers.kb_proposal)
358
+ s(t);
359
+ break;
360
+ }
361
+ case "ask_user":
362
+ for (const t of this.handlers.ask_user)
363
+ t({ askId: e.ask_id, questions: e.questions });
364
+ break;
365
+ case "error":
366
+ for (const t of this.handlers.error)
367
+ t({ message: e.message });
368
+ break;
369
+ case "init":
370
+ case "done":
371
+ break;
372
+ default: {
373
+ const t = e;
374
+ if (t.type === "widget" && t.widget_type && t.data)
375
+ for (const s of this.handlers.widget)
376
+ s({ widgetType: t.widget_type, data: t.data });
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ }
382
+ /**
383
+ * @license
384
+ * Copyright 2025 Amodal Labs, Inc.
385
+ * SPDX-License-Identifier: MIT
386
+ */
387
+ let k = 0;
388
+ function p() {
389
+ return k++, `msg-${Date.now()}-${String(k)}`;
390
+ }
391
+ class D extends S {
392
+ constructor(t) {
393
+ super();
394
+ c(this, "config");
395
+ c(this, "sessionId", null);
396
+ c(this, "_messages", []);
397
+ c(this, "_isConnected", !1);
398
+ c(this, "_isStreaming", !1);
399
+ c(this, "connectAttempt", 0);
400
+ c(this, "maxReconnectAttempts", 3);
401
+ c(this, "_eventBus");
402
+ this.config = t, this._eventBus = new P(), t.entityExtractors && this._eventBus.setExtractors(t.entityExtractors), this._eventBus.on("entity_referenced", (s) => {
403
+ this.emit("entity_referenced", s);
404
+ });
405
+ }
406
+ /** The widget event bus. Subscribe to agent-driven events here. */
407
+ get events() {
408
+ return this._eventBus;
409
+ }
410
+ /** Whether the client has an active session. */
411
+ get isConnected() {
412
+ return this._isConnected;
413
+ }
414
+ /** Whether a response is currently streaming. */
415
+ get isStreaming() {
416
+ return this._isStreaming;
417
+ }
418
+ /** Current session ID, or null if not connected. */
419
+ getSessionId() {
420
+ return this.sessionId;
421
+ }
422
+ /** Readonly message history. */
423
+ get messages() {
424
+ return this._messages;
425
+ }
426
+ /** Establish a session with the server. */
427
+ async connect() {
428
+ try {
429
+ const t = await b(
430
+ this.config.serverUrl,
431
+ this.config.user,
432
+ this.config.token
433
+ );
434
+ this.sessionId = t.session_id, this._isConnected = !0, this.connectAttempt = 0, this.emit("connected", void 0);
435
+ } catch (t) {
436
+ const s = t instanceof Error ? t : new Error(String(t));
437
+ throw this.emit("error", s), s;
438
+ }
439
+ }
440
+ /** Disconnect and clean up. */
441
+ async disconnect() {
442
+ this.sessionId = null, this._isConnected = !1, this._isStreaming = !1, this.emit("disconnected", void 0);
443
+ }
444
+ /** Clear message history. */
445
+ clearHistory() {
446
+ this._messages = [];
447
+ }
448
+ /**
449
+ * Send a message and wait for the full response.
450
+ * Auto-connects if not already connected.
451
+ */
452
+ async send(t) {
453
+ this._isConnected || await this.connect();
454
+ const s = {
455
+ type: "user",
456
+ id: p(),
457
+ text: t,
458
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
459
+ };
460
+ this._messages.push(s), this.emit("message", s);
461
+ const o = {
462
+ type: "assistant_text",
463
+ id: p(),
464
+ text: "",
465
+ toolCalls: [],
466
+ skillActivations: [],
467
+ kbProposals: [],
468
+ widgets: [],
469
+ contentBlocks: [],
470
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
471
+ };
472
+ this._messages.push(o), this.emit("message", o), this._isStreaming = !0, this.emit("streaming_start", void 0);
473
+ try {
474
+ return await this.streamInternal(t, o);
475
+ } catch (n) {
476
+ if (this.connectAttempt < this.maxReconnectAttempts)
477
+ return await this.reconnectAndRetry(t, o);
478
+ throw n;
479
+ } finally {
480
+ this._isStreaming = !1, this.emit("streaming_end", void 0);
481
+ }
482
+ }
483
+ /**
484
+ * Stream a message, returning a ChatStream handle for event-based consumption.
485
+ */
486
+ stream(t) {
487
+ const s = {
488
+ type: "user",
489
+ id: p(),
490
+ text: t,
491
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
492
+ };
493
+ this._messages.push(s), this.emit("message", s), this._isStreaming = !0, this.emit("streaming_start", void 0);
494
+ const o = new N(this.config.serverUrl, {
495
+ message: t,
496
+ session_id: this.sessionId ?? void 0,
497
+ role: this.config.user.role
498
+ }, this.config.token);
499
+ return o.on("done", (n) => {
500
+ const l = {
501
+ type: "assistant_text",
502
+ id: p(),
503
+ text: n.text,
504
+ toolCalls: n.toolCalls,
505
+ skillActivations: n.skillsUsed,
506
+ kbProposals: n.kbProposals,
507
+ widgets: [],
508
+ contentBlocks: [],
509
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
510
+ };
511
+ this._messages.push(l), this.emit("message", l), this._isStreaming = !1, this.emit("streaming_end", void 0);
512
+ }), o.on("error", (n) => {
513
+ this._isStreaming = !1, this.emit("streaming_end", void 0), this.emit("error", new Error(n.message));
514
+ }), o;
515
+ }
516
+ async streamInternal(t, s) {
517
+ const o = {
518
+ text: "",
519
+ toolCalls: [],
520
+ skillsUsed: [],
521
+ kbProposals: []
522
+ }, n = /* @__PURE__ */ new Map(), l = u(
523
+ this.config.serverUrl,
524
+ {
525
+ message: t,
526
+ session_id: this.sessionId ?? void 0,
527
+ role: this.config.user.role
528
+ },
529
+ void 0,
530
+ this.config.token
531
+ );
532
+ for await (const i of l)
533
+ switch (i.type) {
534
+ case "init":
535
+ this.sessionId = i.session_id;
536
+ break;
537
+ case "text_delta":
538
+ o.text += i.content, s.text += i.content;
539
+ break;
540
+ case "tool_call_start": {
541
+ const a = {
542
+ toolId: i.tool_id,
543
+ toolName: i.tool_name,
544
+ parameters: i.parameters,
545
+ status: "running"
546
+ };
547
+ o.toolCalls.push(a), s.toolCalls = [...s.toolCalls, a], n.set(i.tool_id, {
548
+ toolName: i.tool_name,
549
+ parameters: i.parameters
550
+ });
551
+ break;
552
+ }
553
+ case "tool_call_result": {
554
+ const a = o.toolCalls.find((h) => h.toolId === i.tool_id);
555
+ a && (a.status = i.status, a.result = i.result, a.duration_ms = i.duration_ms, a.error = i.error), s.toolCalls = s.toolCalls.map(
556
+ (h) => h.toolId === i.tool_id ? { ...h, status: i.status, result: i.result, duration_ms: i.duration_ms, error: i.error } : h
557
+ );
558
+ const d = n.get(i.tool_id);
559
+ n.delete(i.tool_id);
560
+ const m = {
561
+ type: "tool_executed",
562
+ toolName: (d == null ? void 0 : d.toolName) ?? "",
563
+ toolId: i.tool_id,
564
+ parameters: (d == null ? void 0 : d.parameters) ?? {},
565
+ status: i.status,
566
+ result: i.result,
567
+ duration_ms: i.duration_ms,
568
+ error: i.error,
569
+ timestamp: i.timestamp
570
+ };
571
+ this._eventBus.processEvent(m), this.emit("tool_executed", m);
572
+ break;
573
+ }
574
+ case "skill_activated": {
575
+ o.skillsUsed.push(i.skill), s.skillActivations = [...s.skillActivations, i.skill];
576
+ const a = {
577
+ type: "skill_activated",
578
+ skill: i.skill,
579
+ timestamp: i.timestamp
580
+ };
581
+ this._eventBus.processEvent(a), this.emit("skill_activated", a);
582
+ break;
583
+ }
584
+ case "kb_proposal": {
585
+ const a = {
586
+ scope: i.scope,
587
+ title: i.title,
588
+ reasoning: i.reasoning
589
+ };
590
+ o.kbProposals.push(a), s.kbProposals = [...s.kbProposals, a];
591
+ const d = {
592
+ type: "kb_proposal",
593
+ proposal: a,
594
+ timestamp: i.timestamp
595
+ };
596
+ this._eventBus.processEvent(d), this.emit("kb_proposal_received", d);
597
+ break;
598
+ }
599
+ case "widget": {
600
+ const a = {
601
+ type: "widget_rendered",
602
+ widgetType: i.widget_type,
603
+ data: i.data,
604
+ timestamp: i.timestamp
605
+ };
606
+ this._eventBus.processEvent(a), this.emit("widget_rendered", a);
607
+ break;
608
+ }
609
+ case "error":
610
+ throw new Error(i.message);
611
+ }
612
+ return o;
613
+ }
614
+ async reconnectAndRetry(t, s) {
615
+ this.connectAttempt++, this.emit("reconnecting", this.connectAttempt);
616
+ const o = 100 * Math.pow(2, this.connectAttempt - 1);
617
+ await new Promise((n) => setTimeout(n, o));
618
+ try {
619
+ return await this.connect(), await this.streamInternal(t, s);
620
+ } catch (n) {
621
+ if (this.connectAttempt < this.maxReconnectAttempts)
622
+ return this.reconnectAndRetry(t, s);
623
+ throw n;
624
+ }
625
+ }
626
+ }
627
+ export {
628
+ D as C,
629
+ S as T,
630
+ P as W,
631
+ N as a,
632
+ b,
633
+ j as c,
634
+ v as d,
635
+ T as g,
636
+ A as l,
637
+ w as p,
638
+ u as s,
639
+ $ as u
640
+ };
641
+ //# sourceMappingURL=index-m6lGOMRo.js.map