@amodalai/react 0.1.17 → 0.1.19

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.
@@ -1,16 +1,13 @@
1
1
  import { SSEEvent, TaskStatus, StoreDefinitionInfo, StoreListResult, StoreDocumentResult } from '../types';
2
2
  export interface RuntimeClientOptions {
3
3
  runtimeUrl: string;
4
- appId: string;
5
4
  getToken?: () => string | Promise<string> | null | undefined;
6
5
  }
7
6
  /**
8
7
  * Client for the Amodal runtime's repo routes.
9
- * Targets POST /chat, POST /task, GET /task/:id, GET /task/:id/stream.
10
8
  */
11
9
  export declare class RuntimeClient {
12
10
  private readonly runtimeUrl;
13
- private readonly appId;
14
11
  private readonly getToken?;
15
12
  constructor(options: RuntimeClientOptions);
16
13
  private authHeaders;
@@ -25,7 +22,7 @@ export declare class RuntimeClient {
25
22
  /**
26
23
  * Start a fire-and-forget task via POST /task.
27
24
  */
28
- startTask(prompt: string, appToken?: string): Promise<{
25
+ startTask(prompt: string): Promise<{
29
26
  task_id: string;
30
27
  }>;
31
28
  /**
@@ -36,13 +33,7 @@ export declare class RuntimeClient {
36
33
  * Stream task events via GET /task/:id/stream.
37
34
  */
38
35
  streamTask(taskId: string, signal?: AbortSignal): AsyncGenerator<SSEEvent>;
39
- /**
40
- * List all store definitions with document counts.
41
- */
42
36
  getStores(signal?: AbortSignal): Promise<StoreDefinitionInfo[]>;
43
- /**
44
- * List documents from a store with optional filtering.
45
- */
46
37
  getStoreDocuments(storeName: string, options?: {
47
38
  filter?: Record<string, unknown>;
48
39
  sort?: string;
@@ -50,9 +41,6 @@ export declare class RuntimeClient {
50
41
  offset?: number;
51
42
  signal?: AbortSignal;
52
43
  }): Promise<StoreListResult>;
53
- /**
54
- * Get a single document by key, optionally with version history.
55
- */
56
44
  getStoreDocument(storeName: string, key: string, signal?: AbortSignal): Promise<StoreDocumentResult>;
57
45
  }
58
46
  //# sourceMappingURL=runtime-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-client.d.ts","sourceRoot":"","sources":["../../src/client/runtime-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGhH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC9D;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAoD;gBAElE,OAAO,EAAE,oBAAoB;YAM3B,WAAW;IAWzB;;OAEG;IACI,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,cAAc,CAAC,QAAQ,CAAC;IAqB3B;;OAEG;IACG,SAAS,CACb,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA0B/B;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBxD;;OAEG;IACI,UAAU,CACf,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,QAAQ,CAAC;IAW3B;;OAEG;IACG,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAcrE;;OAEG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,eAAe,CAAC;IA4B3B;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC;CAehC"}
1
+ {"version":3,"file":"runtime-client.d.ts","sourceRoot":"","sources":["../../src/client/runtime-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGhH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC9D;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAoD;gBAElE,OAAO,EAAE,oBAAoB;YAK3B,WAAW;IAWzB;;OAEG;IACI,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,cAAc,CAAC,QAAQ,CAAC;IAoB3B;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB7D;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAcxD;;OAEG;IACI,UAAU,CACf,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,QAAQ,CAAC;IAUrB,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAY/D,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,eAAe,CAAC;IA0BrB,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC;CAahC"}
package/dist/client.js CHANGED
@@ -1,19 +1,18 @@
1
- var g = Object.defineProperty;
2
- var p = (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) => p(h, typeof s != "symbol" ? s + "" : s, t);
4
- import { b as k, 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";
1
+ var f = Object.defineProperty;
2
+ var k = (h, s, t) => s in h ? f(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 g, 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 H, u as P } from "./event-bus-h26clqbZ.js";
6
6
  /**
7
7
  * @license
8
8
  * Copyright 2025 Amodal Labs, Inc.
9
9
  * SPDX-License-Identifier: MIT
10
10
  */
11
- class x {
11
+ class I {
12
12
  constructor(s) {
13
13
  n(this, "runtimeUrl");
14
- n(this, "appId");
15
14
  n(this, "getToken");
16
- this.runtimeUrl = s.runtimeUrl.replace(/\/$/, ""), this.appId = s.appId, this.getToken = s.getToken;
15
+ this.runtimeUrl = s.runtimeUrl.replace(/\/$/, ""), this.getToken = s.getToken;
17
16
  }
18
17
  async authHeaders() {
19
18
  const s = {};
@@ -28,12 +27,11 @@ class x {
28
27
  */
29
28
  async *chatStream(s, t) {
30
29
  const e = `${this.runtimeUrl}/chat`, a = {
31
- message: s,
32
- app_id: this.appId
30
+ message: s
33
31
  };
34
32
  t != null && t.sessionId && (a.session_id = t.sessionId), t != null && t.context && (a.context = t.context);
35
33
  const o = await this.authHeaders();
36
- yield* k(e, a, {
34
+ yield* p(e, a, {
37
35
  signal: t == null ? void 0 : t.signal,
38
36
  headers: o
39
37
  });
@@ -41,29 +39,21 @@ class x {
41
39
  /**
42
40
  * Start a fire-and-forget task via POST /task.
43
41
  */
44
- async startTask(s, t) {
45
- const e = `${this.runtimeUrl}/task`, a = await this.authHeaders(), o = {
46
- prompt: s,
47
- app_id: this.appId
48
- };
49
- t && (o.app_token = t);
50
- const l = await fetch(e, {
42
+ async startTask(s) {
43
+ const t = `${this.runtimeUrl}/task`, e = { prompt: s }, a = await this.authHeaders(), o = await fetch(t, {
51
44
  method: "POST",
52
45
  headers: { "Content-Type": "application/json", ...a },
53
- body: JSON.stringify(o)
46
+ body: JSON.stringify(e)
54
47
  });
55
- if (!l.ok)
56
- throw new Error(`Start task failed: ${String(l.status)} ${l.statusText}`);
57
- return await l.json();
48
+ if (!o.ok)
49
+ throw new Error(`Start task failed: ${String(o.status)} ${o.statusText}`);
50
+ return await o.json();
58
51
  }
59
52
  /**
60
53
  * Get task status via GET /task/:id.
61
54
  */
62
55
  async getTaskStatus(s) {
63
- const t = `${this.runtimeUrl}/task/${s}`, e = await this.authHeaders(), a = await fetch(t, {
64
- method: "GET",
65
- headers: e
66
- });
56
+ const t = `${this.runtimeUrl}/task/${s}`, e = await this.authHeaders(), a = await fetch(t, { headers: e });
67
57
  if (!a.ok)
68
58
  throw new Error(`Get task status failed: ${String(a.status)} ${a.statusText}`);
69
59
  return await a.json();
@@ -78,18 +68,12 @@ class x {
78
68
  // ---------------------------------------------------------------------------
79
69
  // Store API
80
70
  // ---------------------------------------------------------------------------
81
- /**
82
- * List all store definitions with document counts.
83
- */
84
71
  async getStores(s) {
85
72
  const t = `${this.runtimeUrl}/api/stores`, e = await this.authHeaders(), a = await fetch(t, { headers: e, signal: s });
86
73
  if (!a.ok)
87
74
  throw new Error(`Failed to fetch stores: ${String(a.status)}`);
88
75
  return (await a.json()).stores;
89
76
  }
90
- /**
91
- * List documents from a store with optional filtering.
92
- */
93
77
  async getStoreDocuments(s, t) {
94
78
  const e = new URLSearchParams();
95
79
  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));
@@ -98,9 +82,6 @@ class x {
98
82
  throw new Error(`Failed to fetch store documents: ${String(r.status)}`);
99
83
  return await r.json();
100
84
  }
101
- /**
102
- * Get a single document by key, optionally with version history.
103
- */
104
85
  async getStoreDocument(s, t, e) {
105
86
  const a = `${this.runtimeUrl}/api/stores/${s}/${encodeURIComponent(t)}`, o = await this.authHeaders(), l = await fetch(a, { headers: o, signal: e });
106
87
  if (!l.ok) {
@@ -154,7 +135,7 @@ class C {
154
135
  if (!this.started) {
155
136
  this.started = !0;
156
137
  try {
157
- const s = f(
138
+ const s = g(
158
139
  this.serverUrl,
159
140
  this.request,
160
141
  this.abortController.signal,
@@ -372,7 +353,7 @@ class $ extends y {
372
353
  toolCalls: [],
373
354
  skillsUsed: [],
374
355
  kbProposals: []
375
- }, o = /* @__PURE__ */ new Map(), l = f(
356
+ }, o = /* @__PURE__ */ new Map(), l = g(
376
357
  this.config.serverUrl,
377
358
  {
378
359
  message: t,
@@ -480,16 +461,16 @@ class $ extends y {
480
461
  export {
481
462
  $ as ChatClient,
482
463
  C as ChatStream,
483
- x as RuntimeClient,
464
+ I as RuntimeClient,
484
465
  y as TypedEventEmitter,
485
466
  A as createChatClient,
486
467
  b as createSession,
487
468
  T as getSessionHistory,
488
469
  B as listSessions,
489
- P as parseSSELine,
490
- f as streamChat,
491
- k as streamSSE,
470
+ H as parseSSELine,
471
+ g as streamChat,
472
+ p as streamSSE,
492
473
  w as streamSSEGet,
493
- N as updateSession
474
+ P as updateSession
494
475
  };
495
476
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../src/client/runtime-client.ts","../src/client/ChatStream.ts","../src/client/ChatClient.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport type { SSEEvent, TaskStatus, StoreDefinitionInfo, StoreListResult, StoreDocumentResult } from '../types';\nimport { streamSSE, streamSSEGet } from './sse-client';\n\nexport interface RuntimeClientOptions {\n runtimeUrl: string;\n appId: string;\n getToken?: () => string | Promise<string> | null | undefined;\n}\n\n/**\n * Client for the Amodal runtime's repo routes.\n * Targets POST /chat, POST /task, GET /task/:id, GET /task/:id/stream.\n */\nexport class RuntimeClient {\n private readonly runtimeUrl: string;\n private readonly appId: string;\n private readonly getToken?: () => string | Promise<string> | null | undefined;\n\n constructor(options: RuntimeClientOptions) {\n this.runtimeUrl = options.runtimeUrl.replace(/\\/$/, '');\n this.appId = options.appId;\n this.getToken = options.getToken;\n }\n\n private async authHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n if (this.getToken) {\n const token = await this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n return headers;\n }\n\n /**\n * Stream a chat message via POST /chat.\n */\n async *chatStream(\n message: string,\n options?: {\n sessionId?: string;\n context?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): AsyncGenerator<SSEEvent> {\n const url = `${this.runtimeUrl}/chat`;\n const body: Record<string, unknown> = {\n message,\n app_id: this.appId,\n };\n if (options?.sessionId) {\n body['session_id'] = options.sessionId;\n }\n if (options?.context) {\n body['context'] = options.context;\n }\n\n const headers = await this.authHeaders();\n\n yield* streamSSE(url, body, {\n signal: options?.signal,\n headers,\n });\n }\n\n /**\n * Start a fire-and-forget task via POST /task.\n */\n async startTask(\n prompt: string,\n appToken?: string,\n ): Promise<{ task_id: string }> {\n const url = `${this.runtimeUrl}/task`;\n const headers = await this.authHeaders();\n\n const body: Record<string, unknown> = {\n prompt,\n app_id: this.appId,\n };\n if (appToken) {\n body['app_token'] = appToken;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Start task failed: ${String(response.status)} ${response.statusText}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as { task_id: string };\n }\n\n /**\n * Get task status via GET /task/:id.\n */\n async getTaskStatus(taskId: string): Promise<TaskStatus> {\n const url = `${this.runtimeUrl}/task/${taskId}`;\n const headers = await this.authHeaders();\n\n const response = await fetch(url, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n throw new Error(`Get task status failed: ${String(response.status)} ${response.statusText}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as TaskStatus;\n }\n\n /**\n * Stream task events via GET /task/:id/stream.\n */\n async *streamTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<SSEEvent> {\n const url = `${this.runtimeUrl}/task/${taskId}/stream`;\n const headers = await this.authHeaders();\n\n yield* streamSSEGet(url, { signal, headers });\n }\n\n // ---------------------------------------------------------------------------\n // Store API\n // ---------------------------------------------------------------------------\n\n /**\n * List all store definitions with document counts.\n */\n async getStores(signal?: AbortSignal): Promise<StoreDefinitionInfo[]> {\n const url = `${this.runtimeUrl}/api/stores`;\n const headers = await this.authHeaders();\n\n const response = await fetch(url, { headers, signal });\n if (!response.ok) {\n throw new Error(`Failed to fetch stores: ${String(response.status)}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n const body = (await response.json()) as { stores: StoreDefinitionInfo[] };\n return body.stores;\n }\n\n /**\n * List documents from a store with optional filtering.\n */\n async getStoreDocuments(\n storeName: string,\n options?: {\n filter?: Record<string, unknown>;\n sort?: string;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n },\n ): Promise<StoreListResult> {\n const params = new URLSearchParams();\n if (options?.filter) {\n params.set('filter', JSON.stringify(options.filter));\n }\n if (options?.sort) {\n params.set('sort', options.sort);\n }\n if (options?.limit !== undefined) {\n params.set('limit', String(options.limit));\n }\n if (options?.offset !== undefined) {\n params.set('offset', String(options.offset));\n }\n\n const qs = params.toString();\n const url = `${this.runtimeUrl}/api/stores/${storeName}${qs ? `?${qs}` : ''}`;\n const headers = await this.authHeaders();\n\n const response = await fetch(url, { headers, signal: options?.signal });\n if (!response.ok) {\n throw new Error(`Failed to fetch store documents: ${String(response.status)}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as StoreListResult;\n }\n\n /**\n * Get a single document by key, optionally with version history.\n */\n async getStoreDocument(\n storeName: string,\n key: string,\n signal?: AbortSignal,\n ): Promise<StoreDocumentResult> {\n const url = `${this.runtimeUrl}/api/stores/${storeName}/${encodeURIComponent(key)}`;\n const headers = await this.authHeaders();\n\n const response = await fetch(url, { headers, signal });\n if (!response.ok) {\n if (response.status === 404) {\n return { document: null, history: [] };\n }\n throw new Error(`Failed to fetch store document: ${String(response.status)}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as StoreDocumentResult;\n }\n}\n","/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport type {\n SSEEvent,\n ToolCallInfo,\n KBProposalInfo,\n AskUserQuestion,\n} from '../types';\nimport type { ChatStreamRequest } from './chat-api';\nimport { streamChat } from './chat-api';\n\n/**\n * Full response from a completed chat stream.\n */\nexport interface ChatResponse {\n text: string;\n toolCalls: ToolCallInfo[];\n skillsUsed: string[];\n kbProposals: KBProposalInfo[];\n}\n\ntype StreamEventHandler<T> = (data: T) => void;\n\n/**\n * A streaming chat response handle.\n * Register `.on()` handlers then the stream starts automatically.\n */\nexport class ChatStream {\n private handlers: {\n text: Array<StreamEventHandler<{ text: string }>>;\n tool_call: Array<StreamEventHandler<{ tool: string; params: Record<string, unknown>; toolId: string }>>;\n tool_result: Array<StreamEventHandler<{ tool: string; data: unknown; duration_ms?: number; toolId: string }>>;\n skill_activated: Array<StreamEventHandler<{ name: string }>>;\n kb_proposal: Array<StreamEventHandler<KBProposalInfo>>;\n widget: Array<StreamEventHandler<{ widgetType: string; data: Record<string, unknown> }>>;\n ask_user: Array<StreamEventHandler<{ askId: string; questions: AskUserQuestion[] }>>;\n error: Array<StreamEventHandler<{ message: string }>>;\n done: Array<StreamEventHandler<ChatResponse>>;\n } = {\n text: [],\n tool_call: [],\n tool_result: [],\n skill_activated: [],\n kb_proposal: [],\n widget: [],\n ask_user: [],\n error: [],\n done: [],\n };\n\n private abortController: AbortController;\n private started = false;\n private response: ChatResponse = {\n text: '',\n toolCalls: [],\n skillsUsed: [],\n kbProposals: [],\n };\n private toolCallNames = new Map<string, string>();\n\n private token?: string;\n\n constructor(\n private serverUrl: string,\n private request: ChatStreamRequest,\n token?: string,\n ) {\n this.abortController = new AbortController();\n this.token = token;\n // Start on next microtick so .on() calls can register first\n queueMicrotask(() => this.start());\n }\n\n on(event: 'text', handler: StreamEventHandler<{ text: string }>): this;\n on(event: 'tool_call', handler: StreamEventHandler<{ tool: string; params: Record<string, unknown>; toolId: string }>): this;\n on(event: 'tool_result', handler: StreamEventHandler<{ tool: string; data: unknown; duration_ms?: number; toolId: string }>): this;\n on(event: 'skill_activated', handler: StreamEventHandler<{ name: string }>): this;\n on(event: 'kb_proposal', handler: StreamEventHandler<KBProposalInfo>): this;\n on(event: 'widget', handler: StreamEventHandler<{ widgetType: string; data: Record<string, unknown> }>): this;\n on(event: 'ask_user', handler: StreamEventHandler<{ askId: string; questions: AskUserQuestion[] }>): this;\n on(event: 'error', handler: StreamEventHandler<{ message: string }>): this;\n on(event: 'done', handler: StreamEventHandler<ChatResponse>): this;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- overload implementation requires broad type\n on(event: string, handler: StreamEventHandler<any>): this {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- overload dispatch key narrowing\n const key = event as keyof typeof this.handlers;\n if (key in this.handlers) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- overload dispatch\n (this.handlers[key] as Array<StreamEventHandler<unknown>>).push(handler);\n }\n return this;\n }\n\n /** Cancel the stream. */\n abort(): void {\n this.abortController.abort();\n }\n\n private async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n try {\n const stream = streamChat(\n this.serverUrl,\n this.request,\n this.abortController.signal,\n this.token,\n );\n\n for await (const event of stream) {\n this.processEvent(event);\n }\n\n // Emit done\n for (const handler of this.handlers.done) {\n handler(this.response);\n }\n } catch (err) {\n if (!(err instanceof DOMException && err.name === 'AbortError')) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n for (const handler of this.handlers.error) {\n handler({ message });\n }\n }\n }\n }\n\n private processEvent(event: SSEEvent): void {\n switch (event.type) {\n case 'text_delta':\n this.response.text += event.content;\n for (const handler of this.handlers.text) {\n handler({ text: event.content });\n }\n break;\n case 'tool_call_start':\n this.toolCallNames.set(event.tool_id, event.tool_name);\n for (const handler of this.handlers.tool_call) {\n handler({ tool: event.tool_name, params: event.parameters, toolId: event.tool_id });\n }\n this.response.toolCalls.push({\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n status: 'running',\n });\n break;\n case 'tool_call_result': {\n const toolName = this.toolCallNames.get(event.tool_id) ?? '';\n for (const handler of this.handlers.tool_result) {\n handler({ tool: toolName, data: event.result, duration_ms: event.duration_ms, toolId: event.tool_id });\n }\n // Update status in response\n const tc = this.response.toolCalls.find((t) => t.toolId === event.tool_id);\n if (tc) {\n tc.status = event.status;\n tc.result = event.result;\n tc.duration_ms = event.duration_ms;\n tc.error = event.error;\n }\n break;\n }\n case 'skill_activated':\n this.response.skillsUsed.push(event.skill);\n for (const handler of this.handlers.skill_activated) {\n handler({ name: event.skill });\n }\n break;\n case 'kb_proposal': {\n const proposal: KBProposalInfo = {\n scope: event.scope,\n title: event.title,\n reasoning: event.reasoning,\n };\n this.response.kbProposals.push(proposal);\n for (const handler of this.handlers.kb_proposal) {\n handler(proposal);\n }\n break;\n }\n case 'ask_user':\n for (const handler of this.handlers.ask_user) {\n handler({ askId: event.ask_id, questions: event.questions });\n }\n break;\n case 'widget':\n for (const handler of this.handlers.widget) {\n handler({ widgetType: event.widget_type, data: event.data });\n }\n break;\n case 'error':\n for (const handler of this.handlers.error) {\n handler({ message: event.message });\n }\n break;\n case 'init':\n case 'done':\n // Init handled by ChatClient, done triggers after loop\n break;\n default:\n break;\n }\n }\n}\n","/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport { TypedEventEmitter } from './EventEmitter';\nimport { ChatStream } from './ChatStream';\nimport type { ChatResponse } from './ChatStream';\nimport { createSession, streamChat } from './chat-api';\nimport type { ChatUser, ChatMessage, AssistantTextMessage, ToolCallInfo, KBProposalInfo } from '../types';\nimport { WidgetEventBus } from '../events/event-bus';\nimport type { WidgetEvent, EntityExtractor, ToolExecutedEvent, SkillActivatedEvent, WidgetRenderedEvent, KBProposalEvent } from '../events/types';\n\n/**\n * Configuration for the ChatClient.\n */\nexport interface ChatClientConfig {\n serverUrl: string;\n user: ChatUser;\n /** Bearer token (API key or JWT) for authenticated requests. */\n token?: string;\n /** Custom entity extractors. If provided, replaces the default extractor. */\n entityExtractors?: EntityExtractor[];\n}\n\n/**\n * Events emitted by the ChatClient.\n */\nexport interface ClientEvents {\n connected: undefined;\n disconnected: undefined;\n reconnecting: number;\n message: ChatMessage;\n streaming_start: undefined;\n streaming_end: undefined;\n error: Error;\n tool_executed: ToolExecutedEvent;\n skill_activated: SkillActivatedEvent;\n widget_rendered: WidgetRenderedEvent;\n kb_proposal_received: KBProposalEvent;\n entity_referenced: WidgetEvent;\n}\n\nlet msgCounter = 0;\nfunction makeId(): string {\n msgCounter++;\n return `msg-${Date.now()}-${String(msgCounter)}`;\n}\n\n/**\n * Headless chat client for framework-agnostic integrations.\n * Manages session lifecycle, message history, and SSE streaming.\n */\nexport class ChatClient extends TypedEventEmitter<ClientEvents> {\n private config: ChatClientConfig;\n private sessionId: string | null = null;\n private _messages: ChatMessage[] = [];\n private _isConnected = false;\n private _isStreaming = false;\n private connectAttempt = 0;\n private maxReconnectAttempts = 3;\n private _eventBus: WidgetEventBus;\n\n constructor(config: ChatClientConfig) {\n super();\n this.config = config;\n this._eventBus = new WidgetEventBus();\n if (config.entityExtractors) {\n this._eventBus.setExtractors(config.entityExtractors);\n }\n // Forward entity_referenced events from bus to client events\n this._eventBus.on('entity_referenced', (e) => {\n this.emit('entity_referenced', e);\n });\n }\n\n /** The widget event bus. Subscribe to agent-driven events here. */\n get events(): WidgetEventBus {\n return this._eventBus;\n }\n\n /** Whether the client has an active session. */\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /** Whether a response is currently streaming. */\n get isStreaming(): boolean {\n return this._isStreaming;\n }\n\n /** Current session ID, or null if not connected. */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n /** Readonly message history. */\n get messages(): readonly ChatMessage[] {\n return this._messages;\n }\n\n /** Establish a session with the server. */\n async connect(): Promise<void> {\n try {\n const session = await createSession(\n this.config.serverUrl,\n this.config.user,\n this.config.token,\n );\n this.sessionId = session.session_id;\n this._isConnected = true;\n this.connectAttempt = 0;\n this.emit('connected', undefined);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n throw error;\n }\n }\n\n /** Disconnect and clean up. */\n async disconnect(): Promise<void> {\n this.sessionId = null;\n this._isConnected = false;\n this._isStreaming = false;\n this.emit('disconnected', undefined);\n }\n\n /** Clear message history. */\n clearHistory(): void {\n this._messages = [];\n }\n\n /**\n * Send a message and wait for the full response.\n * Auto-connects if not already connected.\n */\n async send(text: string): Promise<ChatResponse> {\n if (!this._isConnected) {\n await this.connect();\n }\n\n // Add user message\n const userMsg: ChatMessage = {\n type: 'user',\n id: makeId(),\n text,\n timestamp: new Date().toISOString(),\n };\n this._messages.push(userMsg);\n this.emit('message', userMsg);\n\n // Create assistant message placeholder\n const assistantMsg: AssistantTextMessage = {\n type: 'assistant_text',\n id: makeId(),\n text: '',\n toolCalls: [],\n confirmations: [],\n skillActivations: [],\n kbProposals: [],\n widgets: [],\n contentBlocks: [],\n timestamp: new Date().toISOString(),\n };\n this._messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n\n this._isStreaming = true;\n this.emit('streaming_start', undefined);\n\n try {\n const response = await this.streamInternal(text, assistantMsg);\n return response;\n } catch (err) {\n // Try reconnection\n if (this.connectAttempt < this.maxReconnectAttempts) {\n return await this.reconnectAndRetry(text, assistantMsg);\n }\n throw err;\n } finally {\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n }\n }\n\n /**\n * Stream a message, returning a ChatStream handle for event-based consumption.\n */\n stream(text: string): ChatStream {\n // Add user message\n const userMsg: ChatMessage = {\n type: 'user',\n id: makeId(),\n text,\n timestamp: new Date().toISOString(),\n };\n this._messages.push(userMsg);\n this.emit('message', userMsg);\n\n this._isStreaming = true;\n this.emit('streaming_start', undefined);\n\n const chatStream = new ChatStream(this.config.serverUrl, {\n message: text,\n session_id: this.sessionId ?? undefined,\n role: this.config.user.role,\n }, this.config.token);\n\n // Track streaming state\n chatStream.on('done', (response) => {\n // Add assistant message to history\n const assistantMsg: AssistantTextMessage = {\n type: 'assistant_text',\n id: makeId(),\n text: response.text,\n toolCalls: response.toolCalls,\n confirmations: [],\n skillActivations: response.skillsUsed,\n kbProposals: response.kbProposals,\n widgets: [],\n contentBlocks: [],\n timestamp: new Date().toISOString(),\n };\n this._messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n });\n\n chatStream.on('error', (err) => {\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n this.emit('error', new Error(err.message));\n });\n\n return chatStream;\n }\n\n private async streamInternal(\n text: string,\n assistantMsg: AssistantTextMessage,\n ): Promise<ChatResponse> {\n const response: ChatResponse = {\n text: '',\n toolCalls: [],\n skillsUsed: [],\n kbProposals: [],\n };\n\n const pendingToolCalls = new Map<string, { toolName: string; parameters: Record<string, unknown> }>();\n\n const stream = streamChat(\n this.config.serverUrl,\n {\n message: text,\n session_id: this.sessionId ?? undefined,\n role: this.config.user.role,\n },\n undefined,\n this.config.token,\n );\n\n for await (const event of stream) {\n switch (event.type) {\n case 'init':\n this.sessionId = event.session_id;\n break;\n case 'text_delta':\n response.text += event.content;\n assistantMsg.text += event.content;\n break;\n case 'tool_call_start': {\n const tc: ToolCallInfo = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n status: 'running',\n };\n response.toolCalls.push(tc);\n assistantMsg.toolCalls = [...assistantMsg.toolCalls, tc];\n pendingToolCalls.set(event.tool_id, {\n toolName: event.tool_name,\n parameters: event.parameters,\n });\n break;\n }\n case 'tool_call_result': {\n const existing = response.toolCalls.find((t) => t.toolId === event.tool_id);\n if (existing) {\n existing.status = event.status;\n existing.result = event.result;\n existing.duration_ms = event.duration_ms;\n existing.error = event.error;\n }\n assistantMsg.toolCalls = assistantMsg.toolCalls.map((t) =>\n t.toolId === event.tool_id\n ? { ...t, status: event.status, result: event.result, duration_ms: event.duration_ms, error: event.error }\n : t,\n );\n\n const pending = pendingToolCalls.get(event.tool_id);\n pendingToolCalls.delete(event.tool_id);\n const toolEvent: ToolExecutedEvent = {\n type: 'tool_executed',\n toolName: pending?.toolName ?? '',\n toolId: event.tool_id,\n parameters: pending?.parameters ?? {},\n status: event.status,\n result: event.result,\n duration_ms: event.duration_ms,\n error: event.error,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(toolEvent);\n this.emit('tool_executed', toolEvent);\n break;\n }\n case 'skill_activated': {\n response.skillsUsed.push(event.skill);\n assistantMsg.skillActivations = [...assistantMsg.skillActivations, event.skill];\n const skillEvent: SkillActivatedEvent = {\n type: 'skill_activated',\n skill: event.skill,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(skillEvent);\n this.emit('skill_activated', skillEvent);\n break;\n }\n case 'kb_proposal': {\n const proposal: KBProposalInfo = {\n scope: event.scope,\n title: event.title,\n reasoning: event.reasoning,\n };\n response.kbProposals.push(proposal);\n assistantMsg.kbProposals = [...assistantMsg.kbProposals, proposal];\n const kbEvent: KBProposalEvent = {\n type: 'kb_proposal',\n proposal,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(kbEvent);\n this.emit('kb_proposal_received', kbEvent);\n break;\n }\n case 'widget': {\n const widgetEvent: WidgetRenderedEvent = {\n type: 'widget_rendered',\n widgetType: event.widget_type,\n data: event.data,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(widgetEvent);\n this.emit('widget_rendered', widgetEvent);\n break;\n }\n case 'error':\n throw new Error(event.message);\n case 'done':\n break;\n default:\n break;\n }\n }\n\n return response;\n }\n\n private async reconnectAndRetry(\n text: string,\n assistantMsg: AssistantTextMessage,\n ): Promise<ChatResponse> {\n this.connectAttempt++;\n this.emit('reconnecting', this.connectAttempt);\n\n // Exponential backoff: 100ms, 200ms, 400ms\n const delay = 100 * Math.pow(2, this.connectAttempt - 1);\n await new Promise((resolve) => setTimeout(resolve, delay));\n\n try {\n await this.connect();\n return await this.streamInternal(text, assistantMsg);\n } catch (err) {\n if (this.connectAttempt < this.maxReconnectAttempts) {\n return this.reconnectAndRetry(text, assistantMsg);\n }\n throw err;\n }\n }\n}\n"],"names":["RuntimeClient","options","__publicField","headers","token","message","url","body","streamSSE","prompt","appToken","response","taskId","signal","streamSSEGet","storeName","params","qs","key","ChatStream","serverUrl","request","event","handler","stream","streamChat","err","toolName","tc","t","proposal","msgCounter","makeId","ChatClient","TypedEventEmitter","config","WidgetEventBus","session","createSession","error","text","userMsg","assistantMsg","chatStream","pendingToolCalls","existing","pending","toolEvent","skillEvent","kbEvent","widgetEvent","delay","resolve"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sources":["../src/client/runtime-client.ts","../src/client/ChatStream.ts","../src/client/ChatClient.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport type { SSEEvent, TaskStatus, StoreDefinitionInfo, StoreListResult, StoreDocumentResult } from '../types';\nimport { streamSSE, streamSSEGet } from './sse-client';\n\nexport interface RuntimeClientOptions {\n runtimeUrl: string;\n getToken?: () => string | Promise<string> | null | undefined;\n}\n\n/**\n * Client for the Amodal runtime's repo routes.\n */\nexport class RuntimeClient {\n private readonly runtimeUrl: string;\n private readonly getToken?: () => string | Promise<string> | null | undefined;\n\n constructor(options: RuntimeClientOptions) {\n this.runtimeUrl = options.runtimeUrl.replace(/\\/$/, '');\n this.getToken = options.getToken;\n }\n\n private async authHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n if (this.getToken) {\n const token = await this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n }\n return headers;\n }\n\n /**\n * Stream a chat message via POST /chat.\n */\n async *chatStream(\n message: string,\n options?: {\n sessionId?: string;\n context?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): AsyncGenerator<SSEEvent> {\n const url = `${this.runtimeUrl}/chat`;\n const body: Record<string, unknown> = {\n message,\n };\n if (options?.sessionId) {\n body['session_id'] = options.sessionId;\n }\n if (options?.context) {\n body['context'] = options.context;\n }\n\n const headers = await this.authHeaders();\n\n yield* streamSSE(url, body, {\n signal: options?.signal,\n headers,\n });\n }\n\n /**\n * Start a fire-and-forget task via POST /task.\n */\n async startTask(prompt: string): Promise<{ task_id: string }> {\n const url = `${this.runtimeUrl}/task`;\n const body: Record<string, unknown> = { prompt };\n const headers = await this.authHeaders();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Start task failed: ${String(response.status)} ${response.statusText}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as { task_id: string };\n }\n\n /**\n * Get task status via GET /task/:id.\n */\n async getTaskStatus(taskId: string): Promise<TaskStatus> {\n const url = `${this.runtimeUrl}/task/${taskId}`;\n\n const headers = await this.authHeaders();\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n throw new Error(`Get task status failed: ${String(response.status)} ${response.statusText}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as TaskStatus;\n }\n\n /**\n * Stream task events via GET /task/:id/stream.\n */\n async *streamTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<SSEEvent> {\n const url = `${this.runtimeUrl}/task/${taskId}/stream`;\n const headers = await this.authHeaders();\n yield* streamSSEGet(url, { signal, headers });\n }\n\n // ---------------------------------------------------------------------------\n // Store API\n // ---------------------------------------------------------------------------\n\n async getStores(signal?: AbortSignal): Promise<StoreDefinitionInfo[]> {\n const url = `${this.runtimeUrl}/api/stores`;\n const authH = await this.authHeaders();\n const response = await fetch(url, { headers: authH, signal });\n if (!response.ok) {\n throw new Error(`Failed to fetch stores: ${String(response.status)}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n const body = (await response.json()) as { stores: StoreDefinitionInfo[] };\n return body.stores;\n }\n\n async getStoreDocuments(\n storeName: string,\n options?: {\n filter?: Record<string, unknown>;\n sort?: string;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n },\n ): Promise<StoreListResult> {\n const params = new URLSearchParams();\n if (options?.filter) {\n params.set('filter', JSON.stringify(options.filter));\n }\n if (options?.sort) {\n params.set('sort', options.sort);\n }\n if (options?.limit !== undefined) {\n params.set('limit', String(options.limit));\n }\n if (options?.offset !== undefined) {\n params.set('offset', String(options.offset));\n }\n\n const qs = params.toString();\n const url = `${this.runtimeUrl}/api/stores/${storeName}${qs ? `?${qs}` : ''}`;\n const authH = await this.authHeaders();\n const response = await fetch(url, { headers: authH, signal: options?.signal });\n if (!response.ok) {\n throw new Error(`Failed to fetch store documents: ${String(response.status)}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as StoreListResult;\n }\n\n async getStoreDocument(\n storeName: string,\n key: string,\n signal?: AbortSignal,\n ): Promise<StoreDocumentResult> {\n const url = `${this.runtimeUrl}/api/stores/${storeName}/${encodeURIComponent(key)}`;\n const authH = await this.authHeaders();\n const response = await fetch(url, { headers: authH, signal });\n if (!response.ok) {\n if (response.status === 404) {\n return { document: null, history: [] };\n }\n throw new Error(`Failed to fetch store document: ${String(response.status)}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Server response\n return (await response.json()) as StoreDocumentResult;\n }\n}\n","/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport type {\n SSEEvent,\n ToolCallInfo,\n KBProposalInfo,\n AskUserQuestion,\n} from '../types';\nimport type { ChatStreamRequest } from './chat-api';\nimport { streamChat } from './chat-api';\n\n/**\n * Full response from a completed chat stream.\n */\nexport interface ChatResponse {\n text: string;\n toolCalls: ToolCallInfo[];\n skillsUsed: string[];\n kbProposals: KBProposalInfo[];\n}\n\ntype StreamEventHandler<T> = (data: T) => void;\n\n/**\n * A streaming chat response handle.\n * Register `.on()` handlers then the stream starts automatically.\n */\nexport class ChatStream {\n private handlers: {\n text: Array<StreamEventHandler<{ text: string }>>;\n tool_call: Array<StreamEventHandler<{ tool: string; params: Record<string, unknown>; toolId: string }>>;\n tool_result: Array<StreamEventHandler<{ tool: string; data: unknown; duration_ms?: number; toolId: string }>>;\n skill_activated: Array<StreamEventHandler<{ name: string }>>;\n kb_proposal: Array<StreamEventHandler<KBProposalInfo>>;\n widget: Array<StreamEventHandler<{ widgetType: string; data: Record<string, unknown> }>>;\n ask_user: Array<StreamEventHandler<{ askId: string; questions: AskUserQuestion[] }>>;\n error: Array<StreamEventHandler<{ message: string }>>;\n done: Array<StreamEventHandler<ChatResponse>>;\n } = {\n text: [],\n tool_call: [],\n tool_result: [],\n skill_activated: [],\n kb_proposal: [],\n widget: [],\n ask_user: [],\n error: [],\n done: [],\n };\n\n private abortController: AbortController;\n private started = false;\n private response: ChatResponse = {\n text: '',\n toolCalls: [],\n skillsUsed: [],\n kbProposals: [],\n };\n private toolCallNames = new Map<string, string>();\n\n private token?: string;\n\n constructor(\n private serverUrl: string,\n private request: ChatStreamRequest,\n token?: string,\n ) {\n this.abortController = new AbortController();\n this.token = token;\n // Start on next microtick so .on() calls can register first\n queueMicrotask(() => this.start());\n }\n\n on(event: 'text', handler: StreamEventHandler<{ text: string }>): this;\n on(event: 'tool_call', handler: StreamEventHandler<{ tool: string; params: Record<string, unknown>; toolId: string }>): this;\n on(event: 'tool_result', handler: StreamEventHandler<{ tool: string; data: unknown; duration_ms?: number; toolId: string }>): this;\n on(event: 'skill_activated', handler: StreamEventHandler<{ name: string }>): this;\n on(event: 'kb_proposal', handler: StreamEventHandler<KBProposalInfo>): this;\n on(event: 'widget', handler: StreamEventHandler<{ widgetType: string; data: Record<string, unknown> }>): this;\n on(event: 'ask_user', handler: StreamEventHandler<{ askId: string; questions: AskUserQuestion[] }>): this;\n on(event: 'error', handler: StreamEventHandler<{ message: string }>): this;\n on(event: 'done', handler: StreamEventHandler<ChatResponse>): this;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- overload implementation requires broad type\n on(event: string, handler: StreamEventHandler<any>): this {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- overload dispatch key narrowing\n const key = event as keyof typeof this.handlers;\n if (key in this.handlers) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- overload dispatch\n (this.handlers[key] as Array<StreamEventHandler<unknown>>).push(handler);\n }\n return this;\n }\n\n /** Cancel the stream. */\n abort(): void {\n this.abortController.abort();\n }\n\n private async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n try {\n const stream = streamChat(\n this.serverUrl,\n this.request,\n this.abortController.signal,\n this.token,\n );\n\n for await (const event of stream) {\n this.processEvent(event);\n }\n\n // Emit done\n for (const handler of this.handlers.done) {\n handler(this.response);\n }\n } catch (err) {\n if (!(err instanceof DOMException && err.name === 'AbortError')) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n for (const handler of this.handlers.error) {\n handler({ message });\n }\n }\n }\n }\n\n private processEvent(event: SSEEvent): void {\n switch (event.type) {\n case 'text_delta':\n this.response.text += event.content;\n for (const handler of this.handlers.text) {\n handler({ text: event.content });\n }\n break;\n case 'tool_call_start':\n this.toolCallNames.set(event.tool_id, event.tool_name);\n for (const handler of this.handlers.tool_call) {\n handler({ tool: event.tool_name, params: event.parameters, toolId: event.tool_id });\n }\n this.response.toolCalls.push({\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n status: 'running',\n });\n break;\n case 'tool_call_result': {\n const toolName = this.toolCallNames.get(event.tool_id) ?? '';\n for (const handler of this.handlers.tool_result) {\n handler({ tool: toolName, data: event.result, duration_ms: event.duration_ms, toolId: event.tool_id });\n }\n // Update status in response\n const tc = this.response.toolCalls.find((t) => t.toolId === event.tool_id);\n if (tc) {\n tc.status = event.status;\n tc.result = event.result;\n tc.duration_ms = event.duration_ms;\n tc.error = event.error;\n }\n break;\n }\n case 'skill_activated':\n this.response.skillsUsed.push(event.skill);\n for (const handler of this.handlers.skill_activated) {\n handler({ name: event.skill });\n }\n break;\n case 'kb_proposal': {\n const proposal: KBProposalInfo = {\n scope: event.scope,\n title: event.title,\n reasoning: event.reasoning,\n };\n this.response.kbProposals.push(proposal);\n for (const handler of this.handlers.kb_proposal) {\n handler(proposal);\n }\n break;\n }\n case 'ask_user':\n for (const handler of this.handlers.ask_user) {\n handler({ askId: event.ask_id, questions: event.questions });\n }\n break;\n case 'widget':\n for (const handler of this.handlers.widget) {\n handler({ widgetType: event.widget_type, data: event.data });\n }\n break;\n case 'error':\n for (const handler of this.handlers.error) {\n handler({ message: event.message });\n }\n break;\n case 'init':\n case 'done':\n // Init handled by ChatClient, done triggers after loop\n break;\n default:\n break;\n }\n }\n}\n","/**\n * @license\n * Copyright 2025 Amodal Labs, Inc.\n * SPDX-License-Identifier: MIT\n */\n\nimport { TypedEventEmitter } from './EventEmitter';\nimport { ChatStream } from './ChatStream';\nimport type { ChatResponse } from './ChatStream';\nimport { createSession, streamChat } from './chat-api';\nimport type { ChatUser, ChatMessage, AssistantTextMessage, ToolCallInfo, KBProposalInfo } from '../types';\nimport { WidgetEventBus } from '../events/event-bus';\nimport type { WidgetEvent, EntityExtractor, ToolExecutedEvent, SkillActivatedEvent, WidgetRenderedEvent, KBProposalEvent } from '../events/types';\n\n/**\n * Configuration for the ChatClient.\n */\nexport interface ChatClientConfig {\n serverUrl: string;\n user: ChatUser;\n /** Bearer token (API key or JWT) for authenticated requests. */\n token?: string;\n /** Custom entity extractors. If provided, replaces the default extractor. */\n entityExtractors?: EntityExtractor[];\n}\n\n/**\n * Events emitted by the ChatClient.\n */\nexport interface ClientEvents {\n connected: undefined;\n disconnected: undefined;\n reconnecting: number;\n message: ChatMessage;\n streaming_start: undefined;\n streaming_end: undefined;\n error: Error;\n tool_executed: ToolExecutedEvent;\n skill_activated: SkillActivatedEvent;\n widget_rendered: WidgetRenderedEvent;\n kb_proposal_received: KBProposalEvent;\n entity_referenced: WidgetEvent;\n}\n\nlet msgCounter = 0;\nfunction makeId(): string {\n msgCounter++;\n return `msg-${Date.now()}-${String(msgCounter)}`;\n}\n\n/**\n * Headless chat client for framework-agnostic integrations.\n * Manages session lifecycle, message history, and SSE streaming.\n */\nexport class ChatClient extends TypedEventEmitter<ClientEvents> {\n private config: ChatClientConfig;\n private sessionId: string | null = null;\n private _messages: ChatMessage[] = [];\n private _isConnected = false;\n private _isStreaming = false;\n private connectAttempt = 0;\n private maxReconnectAttempts = 3;\n private _eventBus: WidgetEventBus;\n\n constructor(config: ChatClientConfig) {\n super();\n this.config = config;\n this._eventBus = new WidgetEventBus();\n if (config.entityExtractors) {\n this._eventBus.setExtractors(config.entityExtractors);\n }\n // Forward entity_referenced events from bus to client events\n this._eventBus.on('entity_referenced', (e) => {\n this.emit('entity_referenced', e);\n });\n }\n\n /** The widget event bus. Subscribe to agent-driven events here. */\n get events(): WidgetEventBus {\n return this._eventBus;\n }\n\n /** Whether the client has an active session. */\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /** Whether a response is currently streaming. */\n get isStreaming(): boolean {\n return this._isStreaming;\n }\n\n /** Current session ID, or null if not connected. */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n /** Readonly message history. */\n get messages(): readonly ChatMessage[] {\n return this._messages;\n }\n\n /** Establish a session with the server. */\n async connect(): Promise<void> {\n try {\n const session = await createSession(\n this.config.serverUrl,\n this.config.user,\n this.config.token,\n );\n this.sessionId = session.session_id;\n this._isConnected = true;\n this.connectAttempt = 0;\n this.emit('connected', undefined);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n throw error;\n }\n }\n\n /** Disconnect and clean up. */\n async disconnect(): Promise<void> {\n this.sessionId = null;\n this._isConnected = false;\n this._isStreaming = false;\n this.emit('disconnected', undefined);\n }\n\n /** Clear message history. */\n clearHistory(): void {\n this._messages = [];\n }\n\n /**\n * Send a message and wait for the full response.\n * Auto-connects if not already connected.\n */\n async send(text: string): Promise<ChatResponse> {\n if (!this._isConnected) {\n await this.connect();\n }\n\n // Add user message\n const userMsg: ChatMessage = {\n type: 'user',\n id: makeId(),\n text,\n timestamp: new Date().toISOString(),\n };\n this._messages.push(userMsg);\n this.emit('message', userMsg);\n\n // Create assistant message placeholder\n const assistantMsg: AssistantTextMessage = {\n type: 'assistant_text',\n id: makeId(),\n text: '',\n toolCalls: [],\n confirmations: [],\n skillActivations: [],\n kbProposals: [],\n widgets: [],\n contentBlocks: [],\n timestamp: new Date().toISOString(),\n };\n this._messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n\n this._isStreaming = true;\n this.emit('streaming_start', undefined);\n\n try {\n const response = await this.streamInternal(text, assistantMsg);\n return response;\n } catch (err) {\n // Try reconnection\n if (this.connectAttempt < this.maxReconnectAttempts) {\n return await this.reconnectAndRetry(text, assistantMsg);\n }\n throw err;\n } finally {\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n }\n }\n\n /**\n * Stream a message, returning a ChatStream handle for event-based consumption.\n */\n stream(text: string): ChatStream {\n // Add user message\n const userMsg: ChatMessage = {\n type: 'user',\n id: makeId(),\n text,\n timestamp: new Date().toISOString(),\n };\n this._messages.push(userMsg);\n this.emit('message', userMsg);\n\n this._isStreaming = true;\n this.emit('streaming_start', undefined);\n\n const chatStream = new ChatStream(this.config.serverUrl, {\n message: text,\n session_id: this.sessionId ?? undefined,\n role: this.config.user.role,\n }, this.config.token);\n\n // Track streaming state\n chatStream.on('done', (response) => {\n // Add assistant message to history\n const assistantMsg: AssistantTextMessage = {\n type: 'assistant_text',\n id: makeId(),\n text: response.text,\n toolCalls: response.toolCalls,\n confirmations: [],\n skillActivations: response.skillsUsed,\n kbProposals: response.kbProposals,\n widgets: [],\n contentBlocks: [],\n timestamp: new Date().toISOString(),\n };\n this._messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n });\n\n chatStream.on('error', (err) => {\n this._isStreaming = false;\n this.emit('streaming_end', undefined);\n this.emit('error', new Error(err.message));\n });\n\n return chatStream;\n }\n\n private async streamInternal(\n text: string,\n assistantMsg: AssistantTextMessage,\n ): Promise<ChatResponse> {\n const response: ChatResponse = {\n text: '',\n toolCalls: [],\n skillsUsed: [],\n kbProposals: [],\n };\n\n const pendingToolCalls = new Map<string, { toolName: string; parameters: Record<string, unknown> }>();\n\n const stream = streamChat(\n this.config.serverUrl,\n {\n message: text,\n session_id: this.sessionId ?? undefined,\n role: this.config.user.role,\n },\n undefined,\n this.config.token,\n );\n\n for await (const event of stream) {\n switch (event.type) {\n case 'init':\n this.sessionId = event.session_id;\n break;\n case 'text_delta':\n response.text += event.content;\n assistantMsg.text += event.content;\n break;\n case 'tool_call_start': {\n const tc: ToolCallInfo = {\n toolId: event.tool_id,\n toolName: event.tool_name,\n parameters: event.parameters,\n status: 'running',\n };\n response.toolCalls.push(tc);\n assistantMsg.toolCalls = [...assistantMsg.toolCalls, tc];\n pendingToolCalls.set(event.tool_id, {\n toolName: event.tool_name,\n parameters: event.parameters,\n });\n break;\n }\n case 'tool_call_result': {\n const existing = response.toolCalls.find((t) => t.toolId === event.tool_id);\n if (existing) {\n existing.status = event.status;\n existing.result = event.result;\n existing.duration_ms = event.duration_ms;\n existing.error = event.error;\n }\n assistantMsg.toolCalls = assistantMsg.toolCalls.map((t) =>\n t.toolId === event.tool_id\n ? { ...t, status: event.status, result: event.result, duration_ms: event.duration_ms, error: event.error }\n : t,\n );\n\n const pending = pendingToolCalls.get(event.tool_id);\n pendingToolCalls.delete(event.tool_id);\n const toolEvent: ToolExecutedEvent = {\n type: 'tool_executed',\n toolName: pending?.toolName ?? '',\n toolId: event.tool_id,\n parameters: pending?.parameters ?? {},\n status: event.status,\n result: event.result,\n duration_ms: event.duration_ms,\n error: event.error,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(toolEvent);\n this.emit('tool_executed', toolEvent);\n break;\n }\n case 'skill_activated': {\n response.skillsUsed.push(event.skill);\n assistantMsg.skillActivations = [...assistantMsg.skillActivations, event.skill];\n const skillEvent: SkillActivatedEvent = {\n type: 'skill_activated',\n skill: event.skill,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(skillEvent);\n this.emit('skill_activated', skillEvent);\n break;\n }\n case 'kb_proposal': {\n const proposal: KBProposalInfo = {\n scope: event.scope,\n title: event.title,\n reasoning: event.reasoning,\n };\n response.kbProposals.push(proposal);\n assistantMsg.kbProposals = [...assistantMsg.kbProposals, proposal];\n const kbEvent: KBProposalEvent = {\n type: 'kb_proposal',\n proposal,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(kbEvent);\n this.emit('kb_proposal_received', kbEvent);\n break;\n }\n case 'widget': {\n const widgetEvent: WidgetRenderedEvent = {\n type: 'widget_rendered',\n widgetType: event.widget_type,\n data: event.data,\n timestamp: event.timestamp,\n };\n this._eventBus.processEvent(widgetEvent);\n this.emit('widget_rendered', widgetEvent);\n break;\n }\n case 'error':\n throw new Error(event.message);\n case 'done':\n break;\n default:\n break;\n }\n }\n\n return response;\n }\n\n private async reconnectAndRetry(\n text: string,\n assistantMsg: AssistantTextMessage,\n ): Promise<ChatResponse> {\n this.connectAttempt++;\n this.emit('reconnecting', this.connectAttempt);\n\n // Exponential backoff: 100ms, 200ms, 400ms\n const delay = 100 * Math.pow(2, this.connectAttempt - 1);\n await new Promise((resolve) => setTimeout(resolve, delay));\n\n try {\n await this.connect();\n return await this.streamInternal(text, assistantMsg);\n } catch (err) {\n if (this.connectAttempt < this.maxReconnectAttempts) {\n return this.reconnectAndRetry(text, assistantMsg);\n }\n throw err;\n }\n }\n}\n"],"names":["RuntimeClient","options","__publicField","headers","token","message","url","body","streamSSE","prompt","response","taskId","signal","streamSSEGet","authH","storeName","params","qs","key","ChatStream","serverUrl","request","event","handler","stream","streamChat","err","toolName","tc","t","proposal","msgCounter","makeId","ChatClient","TypedEventEmitter","config","WidgetEventBus","session","createSession","error","text","userMsg","assistantMsg","chatStream","pendingToolCalls","existing","pending","toolEvent","skillEvent","kbEvent","widgetEvent","delay","resolve"],"mappings":"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"}
@@ -3,21 +3,18 @@ import { RuntimeClient } from './client/runtime-client';
3
3
  export interface AmodalProviderProps {
4
4
  /** Base URL of the Amodal runtime server (e.g., "http://localhost:3001"). */
5
5
  runtimeUrl: string;
6
- /** App identifier sent in every request body. */
7
- appId: string;
8
- /** Optional async token getter for auth headers. */
6
+ /** Optional token getter for auth (hosted mode). */
9
7
  getToken?: () => string | Promise<string> | null | undefined;
10
8
  children: ReactNode;
11
9
  }
12
10
  interface AmodalContextValue {
13
11
  client: RuntimeClient;
14
12
  runtimeUrl: string;
15
- appId: string;
16
13
  }
17
14
  /**
18
15
  * Provides a RuntimeClient to all child hooks and components.
19
16
  */
20
- export declare function AmodalProvider({ runtimeUrl, appId, getToken, children }: AmodalProviderProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function AmodalProvider({ runtimeUrl, getToken, children }: AmodalProviderProps): import("react/jsx-runtime").JSX.Element;
21
18
  /**
22
19
  * Access the RuntimeClient and config from the nearest AmodalProvider.
23
20
  * Throws if called outside of an AmodalProvider.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CAY5F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CAYrF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}