@amodalai/react 0.1.0 → 0.1.2

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 (98) hide show
  1. package/README.md +40 -0
  2. package/dist/client/ChatClient.d.ts +76 -0
  3. package/dist/client/ChatClient.d.ts.map +1 -0
  4. package/dist/client/ChatStream.d.ts +63 -0
  5. package/dist/client/ChatStream.d.ts.map +1 -0
  6. package/dist/client/EventEmitter.d.ts +16 -0
  7. package/dist/client/EventEmitter.d.ts.map +1 -0
  8. package/dist/client/chat-api.d.ts +80 -0
  9. package/dist/client/chat-api.d.ts.map +1 -0
  10. package/dist/client/index.d.ts +7 -0
  11. package/dist/client/index.d.ts.map +1 -1
  12. package/dist/client.js +437 -123
  13. package/dist/client.js.map +1 -1
  14. package/dist/event-bus-h26clqbZ.js +297 -0
  15. package/dist/event-bus-h26clqbZ.js.map +1 -0
  16. package/dist/events/entity-extractor.d.ts +7 -0
  17. package/dist/events/entity-extractor.d.ts.map +1 -0
  18. package/dist/events/event-bus.d.ts +27 -0
  19. package/dist/events/event-bus.d.ts.map +1 -0
  20. package/dist/events/index.d.ts +9 -0
  21. package/dist/events/index.d.ts.map +1 -0
  22. package/dist/events/types.d.ts +72 -0
  23. package/dist/events/types.d.ts.map +1 -0
  24. package/dist/hooks/useAmodalChat.d.ts.map +1 -1
  25. package/dist/hooks/useChat.d.ts +52 -0
  26. package/dist/hooks/useChat.d.ts.map +1 -0
  27. package/dist/hooks/useSessionHistory.d.ts +17 -0
  28. package/dist/hooks/useSessionHistory.d.ts.map +1 -0
  29. package/dist/hooks/useWidgetEvents.d.ts +17 -0
  30. package/dist/hooks/useWidgetEvents.d.ts.map +1 -0
  31. package/dist/index.d.ts +17 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/react.css +5 -0
  34. package/dist/react.js +245 -222
  35. package/dist/react.js.map +1 -1
  36. package/dist/theme-BaBR_tym.js +691 -0
  37. package/dist/theme-BaBR_tym.js.map +1 -0
  38. package/dist/theme.d.ts +11 -0
  39. package/dist/theme.d.ts.map +1 -0
  40. package/dist/types.d.ts +106 -8
  41. package/dist/types.d.ts.map +1 -1
  42. package/dist/umd-entry.d.ts +21 -0
  43. package/dist/umd-entry.d.ts.map +1 -0
  44. package/dist/widget/AskUserCard.d.ts +8 -0
  45. package/dist/widget/AskUserCard.d.ts.map +1 -0
  46. package/dist/widget/ChatWidget.d.ts +9 -0
  47. package/dist/widget/ChatWidget.d.ts.map +1 -0
  48. package/dist/widget/FormattedText.d.ts +12 -0
  49. package/dist/widget/FormattedText.d.ts.map +1 -0
  50. package/dist/widget/InputBar.d.ts +15 -0
  51. package/dist/widget/InputBar.d.ts.map +1 -0
  52. package/dist/widget/KBProposalCard.d.ts +7 -0
  53. package/dist/widget/KBProposalCard.d.ts.map +1 -0
  54. package/dist/widget/MessageList.d.ts +15 -0
  55. package/dist/widget/MessageList.d.ts.map +1 -0
  56. package/dist/widget/SessionHistory.d.ts +12 -0
  57. package/dist/widget/SessionHistory.d.ts.map +1 -0
  58. package/dist/widget/SkillPill.d.ts +11 -0
  59. package/dist/widget/SkillPill.d.ts.map +1 -0
  60. package/dist/widget/StreamingIndicator.d.ts +7 -0
  61. package/dist/widget/StreamingIndicator.d.ts.map +1 -0
  62. package/dist/widget/TagEditor.d.ts +11 -0
  63. package/dist/widget/TagEditor.d.ts.map +1 -0
  64. package/dist/widget/ToolCallCard.d.ts +7 -0
  65. package/dist/widget/ToolCallCard.d.ts.map +1 -0
  66. package/dist/widget/index.d.ts +33 -0
  67. package/dist/widget/index.d.ts.map +1 -0
  68. package/dist/widget/widgets/AlertCard.d.ts +3 -0
  69. package/dist/widget/widgets/AlertCard.d.ts.map +1 -0
  70. package/dist/widget/widgets/Comparison.d.ts +3 -0
  71. package/dist/widget/widgets/Comparison.d.ts.map +1 -0
  72. package/dist/widget/widgets/CredentialInput.d.ts +3 -0
  73. package/dist/widget/widgets/CredentialInput.d.ts.map +1 -0
  74. package/dist/widget/widgets/DataTable.d.ts +3 -0
  75. package/dist/widget/widgets/DataTable.d.ts.map +1 -0
  76. package/dist/widget/widgets/DocumentPreview.d.ts +3 -0
  77. package/dist/widget/widgets/DocumentPreview.d.ts.map +1 -0
  78. package/dist/widget/widgets/EntityCard.d.ts +3 -0
  79. package/dist/widget/widgets/EntityCard.d.ts.map +1 -0
  80. package/dist/widget/widgets/EntityList.d.ts +3 -0
  81. package/dist/widget/widgets/EntityList.d.ts.map +1 -0
  82. package/dist/widget/widgets/InfoCard.d.ts +3 -0
  83. package/dist/widget/widgets/InfoCard.d.ts.map +1 -0
  84. package/dist/widget/widgets/Metric.d.ts +3 -0
  85. package/dist/widget/widgets/Metric.d.ts.map +1 -0
  86. package/dist/widget/widgets/ScopeMap.d.ts +3 -0
  87. package/dist/widget/widgets/ScopeMap.d.ts.map +1 -0
  88. package/dist/widget/widgets/ScoreBreakdown.d.ts +3 -0
  89. package/dist/widget/widgets/ScoreBreakdown.d.ts.map +1 -0
  90. package/dist/widget/widgets/StatusBoard.d.ts +3 -0
  91. package/dist/widget/widgets/StatusBoard.d.ts.map +1 -0
  92. package/dist/widget/widgets/Timeline.d.ts +3 -0
  93. package/dist/widget/widgets/Timeline.d.ts.map +1 -0
  94. package/dist/widget/widgets/WidgetRenderer.d.ts +28 -0
  95. package/dist/widget/widgets/WidgetRenderer.d.ts.map +1 -0
  96. package/dist/widget.js +1668 -0
  97. package/dist/widget.js.map +1 -0
  98. package/package.json +8 -1
package/dist/client.js CHANGED
@@ -1,140 +1,79 @@
1
- var m = Object.defineProperty;
2
- var S = (s, e, t) => e in s ? m(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var d = (s, e, t) => S(s, typeof e != "symbol" ? e + "" : e, t);
1
+ var g = Object.defineProperty;
2
+ var k = (h, s, t) => s in h ? g(h, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[s] = t;
3
+ var n = (h, s, t) => k(h, typeof s != "symbol" ? s + "" : s, t);
4
+ import { b as p, e as w, s as f, T as y, W as S, a as b } from "./event-bus-h26clqbZ.js";
5
+ import { c as A, g as T, l as B, p as P, u as N } from "./event-bus-h26clqbZ.js";
4
6
  /**
5
7
  * @license
6
8
  * Copyright 2025 Amodal Labs, Inc.
7
9
  * SPDX-License-Identifier: MIT
8
10
  */
9
- function l(s) {
10
- if (!s.startsWith("data: ")) return null;
11
- const e = s.slice(6).trim();
12
- return e.length === 0 ? null : JSON.parse(e);
13
- }
14
- async function* g(s, e, t) {
15
- const a = {
16
- "Content-Type": "application/json",
17
- ...t == null ? void 0 : t.headers
18
- }, r = await fetch(s, {
19
- method: "POST",
20
- headers: a,
21
- body: JSON.stringify(e),
22
- signal: t == null ? void 0 : t.signal
23
- });
24
- if (!r.ok)
25
- throw new Error(`SSE request failed: ${String(r.status)} ${r.statusText}`);
26
- yield* f(r);
27
- }
28
- async function* y(s, e) {
29
- const t = await fetch(s, {
30
- method: "GET",
31
- headers: e == null ? void 0 : e.headers,
32
- signal: e == null ? void 0 : e.signal
33
- });
34
- if (!t.ok)
35
- throw new Error(`SSE request failed: ${String(t.status)} ${t.statusText}`);
36
- yield* f(t);
37
- }
38
- async function* f(s) {
39
- const e = s.body;
40
- if (!e)
41
- throw new Error("Response body is null");
42
- const t = e.getReader(), a = new TextDecoder();
43
- let r = "";
44
- try {
45
- for (; ; ) {
46
- const { done: n, value: i } = await t.read();
47
- if (n) break;
48
- r += a.decode(i, { stream: !0 });
49
- const c = r.split(`
50
- `);
51
- r = c.pop() ?? "";
52
- for (const w of c) {
53
- const h = w.trim();
54
- if (h.length === 0) continue;
55
- const u = l(h);
56
- u && (yield u);
57
- }
58
- }
59
- if (r.trim().length > 0) {
60
- const n = l(r.trim());
61
- n && (yield n);
62
- }
63
- } finally {
64
- t.releaseLock();
65
- }
66
- }
67
- /**
68
- * @license
69
- * Copyright 2025 Amodal Labs, Inc.
70
- * SPDX-License-Identifier: MIT
71
- */
72
- class $ {
73
- constructor(e) {
74
- d(this, "runtimeUrl");
75
- d(this, "tenantId");
76
- d(this, "getToken");
77
- this.runtimeUrl = e.runtimeUrl.replace(/\/$/, ""), this.tenantId = e.tenantId, this.getToken = e.getToken;
11
+ class x {
12
+ constructor(s) {
13
+ n(this, "runtimeUrl");
14
+ n(this, "tenantId");
15
+ n(this, "getToken");
16
+ this.runtimeUrl = s.runtimeUrl.replace(/\/$/, ""), this.tenantId = s.tenantId, this.getToken = s.getToken;
78
17
  }
79
18
  async authHeaders() {
80
- const e = {};
19
+ const s = {};
81
20
  if (this.getToken) {
82
21
  const t = await this.getToken();
83
- t && (e.Authorization = `Bearer ${t}`);
22
+ t && (s.Authorization = `Bearer ${t}`);
84
23
  }
85
- return e;
24
+ return s;
86
25
  }
87
26
  /**
88
27
  * Stream a chat message via POST /chat.
89
28
  */
90
- async *chatStream(e, t) {
91
- const a = `${this.runtimeUrl}/chat`, r = {
92
- message: e,
29
+ async *chatStream(s, t) {
30
+ const e = `${this.runtimeUrl}/chat`, a = {
31
+ message: s,
93
32
  tenant_id: this.tenantId
94
33
  };
95
- t != null && t.sessionId && (r.session_id = t.sessionId), t != null && t.context && (r.context = t.context);
96
- const n = await this.authHeaders();
97
- yield* g(a, r, {
34
+ t != null && t.sessionId && (a.session_id = t.sessionId), t != null && t.context && (a.context = t.context);
35
+ const o = await this.authHeaders();
36
+ yield* p(e, a, {
98
37
  signal: t == null ? void 0 : t.signal,
99
- headers: n
38
+ headers: o
100
39
  });
101
40
  }
102
41
  /**
103
42
  * Start a fire-and-forget task via POST /task.
104
43
  */
105
- async startTask(e, t) {
106
- const a = `${this.runtimeUrl}/task`, r = await this.authHeaders(), n = {
107
- prompt: e,
44
+ async startTask(s, t) {
45
+ const e = `${this.runtimeUrl}/task`, a = await this.authHeaders(), o = {
46
+ prompt: s,
108
47
  tenant_id: this.tenantId
109
48
  };
110
- t && (n.tenant_token = t);
111
- const i = await fetch(a, {
49
+ t && (o.tenant_token = t);
50
+ const l = await fetch(e, {
112
51
  method: "POST",
113
- headers: { "Content-Type": "application/json", ...r },
114
- body: JSON.stringify(n)
52
+ headers: { "Content-Type": "application/json", ...a },
53
+ body: JSON.stringify(o)
115
54
  });
116
- if (!i.ok)
117
- throw new Error(`Start task failed: ${String(i.status)} ${i.statusText}`);
118
- return await i.json();
55
+ if (!l.ok)
56
+ throw new Error(`Start task failed: ${String(l.status)} ${l.statusText}`);
57
+ return await l.json();
119
58
  }
120
59
  /**
121
60
  * Get task status via GET /task/:id.
122
61
  */
123
- async getTaskStatus(e) {
124
- const t = `${this.runtimeUrl}/task/${e}`, a = await this.authHeaders(), r = await fetch(t, {
62
+ async getTaskStatus(s) {
63
+ const t = `${this.runtimeUrl}/task/${s}`, e = await this.authHeaders(), a = await fetch(t, {
125
64
  method: "GET",
126
- headers: a
65
+ headers: e
127
66
  });
128
- if (!r.ok)
129
- throw new Error(`Get task status failed: ${String(r.status)} ${r.statusText}`);
130
- return await r.json();
67
+ if (!a.ok)
68
+ throw new Error(`Get task status failed: ${String(a.status)} ${a.statusText}`);
69
+ return await a.json();
131
70
  }
132
71
  /**
133
72
  * Stream task events via GET /task/:id/stream.
134
73
  */
135
- async *streamTask(e, t) {
136
- const a = `${this.runtimeUrl}/task/${e}/stream`, r = await this.authHeaders();
137
- yield* y(a, { signal: t, headers: r });
74
+ async *streamTask(s, t) {
75
+ const e = `${this.runtimeUrl}/task/${s}/stream`, a = await this.authHeaders();
76
+ yield* w(e, { signal: t, headers: a });
138
77
  }
139
78
  // ---------------------------------------------------------------------------
140
79
  // Store API
@@ -142,40 +81,415 @@ class $ {
142
81
  /**
143
82
  * List all store definitions with document counts.
144
83
  */
145
- async getStores(e) {
146
- const t = `${this.runtimeUrl}/api/stores`, a = await this.authHeaders(), r = await fetch(t, { headers: a, signal: e });
147
- if (!r.ok)
148
- throw new Error(`Failed to fetch stores: ${String(r.status)}`);
149
- return (await r.json()).stores;
84
+ async getStores(s) {
85
+ const t = `${this.runtimeUrl}/api/stores`, e = await this.authHeaders(), a = await fetch(t, { headers: e, signal: s });
86
+ if (!a.ok)
87
+ throw new Error(`Failed to fetch stores: ${String(a.status)}`);
88
+ return (await a.json()).stores;
150
89
  }
151
90
  /**
152
91
  * List documents from a store with optional filtering.
153
92
  */
154
- async getStoreDocuments(e, t) {
155
- const a = new URLSearchParams();
156
- t != null && t.filter && a.set("filter", JSON.stringify(t.filter)), t != null && t.sort && a.set("sort", t.sort), (t == null ? void 0 : t.limit) !== void 0 && a.set("limit", String(t.limit)), (t == null ? void 0 : t.offset) !== void 0 && a.set("offset", String(t.offset));
157
- const r = a.toString(), n = `${this.runtimeUrl}/api/stores/${e}${r ? `?${r}` : ""}`, i = await this.authHeaders(), c = await fetch(n, { headers: i, signal: t == null ? void 0 : t.signal });
158
- if (!c.ok)
159
- throw new Error(`Failed to fetch store documents: ${String(c.status)}`);
160
- return await c.json();
93
+ async getStoreDocuments(s, t) {
94
+ const e = new URLSearchParams();
95
+ t != null && t.filter && e.set("filter", JSON.stringify(t.filter)), t != null && t.sort && e.set("sort", t.sort), (t == null ? void 0 : t.limit) !== void 0 && e.set("limit", String(t.limit)), (t == null ? void 0 : t.offset) !== void 0 && e.set("offset", String(t.offset));
96
+ const a = e.toString(), o = `${this.runtimeUrl}/api/stores/${s}${a ? `?${a}` : ""}`, l = await this.authHeaders(), r = await fetch(o, { headers: l, signal: t == null ? void 0 : t.signal });
97
+ if (!r.ok)
98
+ throw new Error(`Failed to fetch store documents: ${String(r.status)}`);
99
+ return await r.json();
161
100
  }
162
101
  /**
163
102
  * Get a single document by key, optionally with version history.
164
103
  */
165
- async getStoreDocument(e, t, a) {
166
- const r = `${this.runtimeUrl}/api/stores/${e}/${encodeURIComponent(t)}`, n = await this.authHeaders(), i = await fetch(r, { headers: n, signal: a });
167
- if (!i.ok) {
168
- if (i.status === 404)
104
+ async getStoreDocument(s, t, e) {
105
+ const a = `${this.runtimeUrl}/api/stores/${s}/${encodeURIComponent(t)}`, o = await this.authHeaders(), l = await fetch(a, { headers: o, signal: e });
106
+ if (!l.ok) {
107
+ if (l.status === 404)
169
108
  return { document: null, history: [] };
170
- throw new Error(`Failed to fetch store document: ${String(i.status)}`);
109
+ throw new Error(`Failed to fetch store document: ${String(l.status)}`);
110
+ }
111
+ return await l.json();
112
+ }
113
+ }
114
+ /**
115
+ * @license
116
+ * Copyright 2025 Amodal Labs, Inc.
117
+ * SPDX-License-Identifier: MIT
118
+ */
119
+ class C {
120
+ constructor(s, t, e) {
121
+ n(this, "handlers", {
122
+ text: [],
123
+ tool_call: [],
124
+ tool_result: [],
125
+ skill_activated: [],
126
+ kb_proposal: [],
127
+ widget: [],
128
+ ask_user: [],
129
+ error: [],
130
+ done: []
131
+ });
132
+ n(this, "abortController");
133
+ n(this, "started", !1);
134
+ n(this, "response", {
135
+ text: "",
136
+ toolCalls: [],
137
+ skillsUsed: [],
138
+ kbProposals: []
139
+ });
140
+ n(this, "toolCallNames", /* @__PURE__ */ new Map());
141
+ n(this, "token");
142
+ this.serverUrl = s, this.request = t, this.abortController = new AbortController(), this.token = e, queueMicrotask(() => this.start());
143
+ }
144
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- overload implementation requires broad type
145
+ on(s, t) {
146
+ const e = s;
147
+ return e in this.handlers && this.handlers[e].push(t), this;
148
+ }
149
+ /** Cancel the stream. */
150
+ abort() {
151
+ this.abortController.abort();
152
+ }
153
+ async start() {
154
+ if (!this.started) {
155
+ this.started = !0;
156
+ try {
157
+ const s = f(
158
+ this.serverUrl,
159
+ this.request,
160
+ this.abortController.signal,
161
+ this.token
162
+ );
163
+ for await (const t of s)
164
+ this.processEvent(t);
165
+ for (const t of this.handlers.done)
166
+ t(this.response);
167
+ } catch (s) {
168
+ if (!(s instanceof DOMException && s.name === "AbortError")) {
169
+ const t = s instanceof Error ? s.message : "Unknown error";
170
+ for (const e of this.handlers.error)
171
+ e({ message: t });
172
+ }
173
+ }
174
+ }
175
+ }
176
+ processEvent(s) {
177
+ switch (s.type) {
178
+ case "text_delta":
179
+ this.response.text += s.content;
180
+ for (const t of this.handlers.text)
181
+ t({ text: s.content });
182
+ break;
183
+ case "tool_call_start":
184
+ this.toolCallNames.set(s.tool_id, s.tool_name);
185
+ for (const t of this.handlers.tool_call)
186
+ t({ tool: s.tool_name, params: s.parameters, toolId: s.tool_id });
187
+ this.response.toolCalls.push({
188
+ toolId: s.tool_id,
189
+ toolName: s.tool_name,
190
+ parameters: s.parameters,
191
+ status: "running"
192
+ });
193
+ break;
194
+ case "tool_call_result": {
195
+ const t = this.toolCallNames.get(s.tool_id) ?? "";
196
+ for (const a of this.handlers.tool_result)
197
+ a({ tool: t, data: s.result, duration_ms: s.duration_ms, toolId: s.tool_id });
198
+ const e = this.response.toolCalls.find((a) => a.toolId === s.tool_id);
199
+ e && (e.status = s.status, e.result = s.result, e.duration_ms = s.duration_ms, e.error = s.error);
200
+ break;
201
+ }
202
+ case "skill_activated":
203
+ this.response.skillsUsed.push(s.skill);
204
+ for (const t of this.handlers.skill_activated)
205
+ t({ name: s.skill });
206
+ break;
207
+ case "kb_proposal": {
208
+ const t = {
209
+ scope: s.scope,
210
+ title: s.title,
211
+ reasoning: s.reasoning
212
+ };
213
+ this.response.kbProposals.push(t);
214
+ for (const e of this.handlers.kb_proposal)
215
+ e(t);
216
+ break;
217
+ }
218
+ case "ask_user":
219
+ for (const t of this.handlers.ask_user)
220
+ t({ askId: s.ask_id, questions: s.questions });
221
+ break;
222
+ case "widget":
223
+ for (const t of this.handlers.widget)
224
+ t({ widgetType: s.widget_type, data: s.data });
225
+ break;
226
+ case "error":
227
+ for (const t of this.handlers.error)
228
+ t({ message: s.message });
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ /**
234
+ * @license
235
+ * Copyright 2025 Amodal Labs, Inc.
236
+ * SPDX-License-Identifier: MIT
237
+ */
238
+ let _ = 0;
239
+ function m() {
240
+ return _++, `msg-${Date.now()}-${String(_)}`;
241
+ }
242
+ class $ extends y {
243
+ constructor(t) {
244
+ super();
245
+ n(this, "config");
246
+ n(this, "sessionId", null);
247
+ n(this, "_messages", []);
248
+ n(this, "_isConnected", !1);
249
+ n(this, "_isStreaming", !1);
250
+ n(this, "connectAttempt", 0);
251
+ n(this, "maxReconnectAttempts", 3);
252
+ n(this, "_eventBus");
253
+ this.config = t, this._eventBus = new S(), t.entityExtractors && this._eventBus.setExtractors(t.entityExtractors), this._eventBus.on("entity_referenced", (e) => {
254
+ this.emit("entity_referenced", e);
255
+ });
256
+ }
257
+ /** The widget event bus. Subscribe to agent-driven events here. */
258
+ get events() {
259
+ return this._eventBus;
260
+ }
261
+ /** Whether the client has an active session. */
262
+ get isConnected() {
263
+ return this._isConnected;
264
+ }
265
+ /** Whether a response is currently streaming. */
266
+ get isStreaming() {
267
+ return this._isStreaming;
268
+ }
269
+ /** Current session ID, or null if not connected. */
270
+ getSessionId() {
271
+ return this.sessionId;
272
+ }
273
+ /** Readonly message history. */
274
+ get messages() {
275
+ return this._messages;
276
+ }
277
+ /** Establish a session with the server. */
278
+ async connect() {
279
+ try {
280
+ const t = await b(
281
+ this.config.serverUrl,
282
+ this.config.user,
283
+ this.config.token
284
+ );
285
+ this.sessionId = t.session_id, this._isConnected = !0, this.connectAttempt = 0, this.emit("connected", void 0);
286
+ } catch (t) {
287
+ const e = t instanceof Error ? t : new Error(String(t));
288
+ throw this.emit("error", e), e;
289
+ }
290
+ }
291
+ /** Disconnect and clean up. */
292
+ async disconnect() {
293
+ this.sessionId = null, this._isConnected = !1, this._isStreaming = !1, this.emit("disconnected", void 0);
294
+ }
295
+ /** Clear message history. */
296
+ clearHistory() {
297
+ this._messages = [];
298
+ }
299
+ /**
300
+ * Send a message and wait for the full response.
301
+ * Auto-connects if not already connected.
302
+ */
303
+ async send(t) {
304
+ this._isConnected || await this.connect();
305
+ const e = {
306
+ type: "user",
307
+ id: m(),
308
+ text: t,
309
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
310
+ };
311
+ this._messages.push(e), this.emit("message", e);
312
+ const a = {
313
+ type: "assistant_text",
314
+ id: m(),
315
+ text: "",
316
+ toolCalls: [],
317
+ confirmations: [],
318
+ skillActivations: [],
319
+ kbProposals: [],
320
+ widgets: [],
321
+ contentBlocks: [],
322
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
323
+ };
324
+ this._messages.push(a), this.emit("message", a), this._isStreaming = !0, this.emit("streaming_start", void 0);
325
+ try {
326
+ return await this.streamInternal(t, a);
327
+ } catch (o) {
328
+ if (this.connectAttempt < this.maxReconnectAttempts)
329
+ return await this.reconnectAndRetry(t, a);
330
+ throw o;
331
+ } finally {
332
+ this._isStreaming = !1, this.emit("streaming_end", void 0);
333
+ }
334
+ }
335
+ /**
336
+ * Stream a message, returning a ChatStream handle for event-based consumption.
337
+ */
338
+ stream(t) {
339
+ const e = {
340
+ type: "user",
341
+ id: m(),
342
+ text: t,
343
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
344
+ };
345
+ this._messages.push(e), this.emit("message", e), this._isStreaming = !0, this.emit("streaming_start", void 0);
346
+ const a = new C(this.config.serverUrl, {
347
+ message: t,
348
+ session_id: this.sessionId ?? void 0,
349
+ role: this.config.user.role
350
+ }, this.config.token);
351
+ return a.on("done", (o) => {
352
+ const l = {
353
+ type: "assistant_text",
354
+ id: m(),
355
+ text: o.text,
356
+ toolCalls: o.toolCalls,
357
+ confirmations: [],
358
+ skillActivations: o.skillsUsed,
359
+ kbProposals: o.kbProposals,
360
+ widgets: [],
361
+ contentBlocks: [],
362
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
363
+ };
364
+ this._messages.push(l), this.emit("message", l), this._isStreaming = !1, this.emit("streaming_end", void 0);
365
+ }), a.on("error", (o) => {
366
+ this._isStreaming = !1, this.emit("streaming_end", void 0), this.emit("error", new Error(o.message));
367
+ }), a;
368
+ }
369
+ async streamInternal(t, e) {
370
+ const a = {
371
+ text: "",
372
+ toolCalls: [],
373
+ skillsUsed: [],
374
+ kbProposals: []
375
+ }, o = /* @__PURE__ */ new Map(), l = f(
376
+ this.config.serverUrl,
377
+ {
378
+ message: t,
379
+ session_id: this.sessionId ?? void 0,
380
+ role: this.config.user.role
381
+ },
382
+ void 0,
383
+ this.config.token
384
+ );
385
+ for await (const r of l)
386
+ switch (r.type) {
387
+ case "init":
388
+ this.sessionId = r.session_id;
389
+ break;
390
+ case "text_delta":
391
+ a.text += r.content, e.text += r.content;
392
+ break;
393
+ case "tool_call_start": {
394
+ const i = {
395
+ toolId: r.tool_id,
396
+ toolName: r.tool_name,
397
+ parameters: r.parameters,
398
+ status: "running"
399
+ };
400
+ a.toolCalls.push(i), e.toolCalls = [...e.toolCalls, i], o.set(r.tool_id, {
401
+ toolName: r.tool_name,
402
+ parameters: r.parameters
403
+ });
404
+ break;
405
+ }
406
+ case "tool_call_result": {
407
+ const i = a.toolCalls.find((d) => d.toolId === r.tool_id);
408
+ i && (i.status = r.status, i.result = r.result, i.duration_ms = r.duration_ms, i.error = r.error), e.toolCalls = e.toolCalls.map(
409
+ (d) => d.toolId === r.tool_id ? { ...d, status: r.status, result: r.result, duration_ms: r.duration_ms, error: r.error } : d
410
+ );
411
+ const c = o.get(r.tool_id);
412
+ o.delete(r.tool_id);
413
+ const u = {
414
+ type: "tool_executed",
415
+ toolName: (c == null ? void 0 : c.toolName) ?? "",
416
+ toolId: r.tool_id,
417
+ parameters: (c == null ? void 0 : c.parameters) ?? {},
418
+ status: r.status,
419
+ result: r.result,
420
+ duration_ms: r.duration_ms,
421
+ error: r.error,
422
+ timestamp: r.timestamp
423
+ };
424
+ this._eventBus.processEvent(u), this.emit("tool_executed", u);
425
+ break;
426
+ }
427
+ case "skill_activated": {
428
+ a.skillsUsed.push(r.skill), e.skillActivations = [...e.skillActivations, r.skill];
429
+ const i = {
430
+ type: "skill_activated",
431
+ skill: r.skill,
432
+ timestamp: r.timestamp
433
+ };
434
+ this._eventBus.processEvent(i), this.emit("skill_activated", i);
435
+ break;
436
+ }
437
+ case "kb_proposal": {
438
+ const i = {
439
+ scope: r.scope,
440
+ title: r.title,
441
+ reasoning: r.reasoning
442
+ };
443
+ a.kbProposals.push(i), e.kbProposals = [...e.kbProposals, i];
444
+ const c = {
445
+ type: "kb_proposal",
446
+ proposal: i,
447
+ timestamp: r.timestamp
448
+ };
449
+ this._eventBus.processEvent(c), this.emit("kb_proposal_received", c);
450
+ break;
451
+ }
452
+ case "widget": {
453
+ const i = {
454
+ type: "widget_rendered",
455
+ widgetType: r.widget_type,
456
+ data: r.data,
457
+ timestamp: r.timestamp
458
+ };
459
+ this._eventBus.processEvent(i), this.emit("widget_rendered", i);
460
+ break;
461
+ }
462
+ case "error":
463
+ throw new Error(r.message);
464
+ }
465
+ return a;
466
+ }
467
+ async reconnectAndRetry(t, e) {
468
+ this.connectAttempt++, this.emit("reconnecting", this.connectAttempt);
469
+ const a = 100 * Math.pow(2, this.connectAttempt - 1);
470
+ await new Promise((o) => setTimeout(o, a));
471
+ try {
472
+ return await this.connect(), await this.streamInternal(t, e);
473
+ } catch (o) {
474
+ if (this.connectAttempt < this.maxReconnectAttempts)
475
+ return this.reconnectAndRetry(t, e);
476
+ throw o;
171
477
  }
172
- return await i.json();
173
478
  }
174
479
  }
175
480
  export {
176
- $ as RuntimeClient,
177
- l as parseSSELine,
178
- g as streamSSE,
179
- y as streamSSEGet
481
+ $ as ChatClient,
482
+ C as ChatStream,
483
+ x as RuntimeClient,
484
+ y as TypedEventEmitter,
485
+ A as createChatClient,
486
+ b as createSession,
487
+ T as getSessionHistory,
488
+ B as listSessions,
489
+ P as parseSSELine,
490
+ f as streamChat,
491
+ p as streamSSE,
492
+ w as streamSSEGet,
493
+ N as updateSession
180
494
  };
181
495
  //# sourceMappingURL=client.js.map