@aomi-labs/react 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18,438 +18,12 @@ var __spreadValues = (a, b) => {
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
 
21
- // packages/react/src/backend/sse.ts
22
- function extractSseData(rawEvent) {
23
- const dataLines = rawEvent.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart());
24
- if (!dataLines.length) return null;
25
- return dataLines.join("\n");
26
- }
27
- async function readSseStream(stream, signal, onMessage) {
28
- const reader = stream.getReader();
29
- const decoder = new TextDecoder();
30
- let buffer = "";
31
- try {
32
- while (!signal.aborted) {
33
- const { value, done } = await reader.read();
34
- if (done) break;
35
- buffer += decoder.decode(value, { stream: true });
36
- buffer = buffer.replace(/\r/g, "");
37
- let separatorIndex = buffer.indexOf("\n\n");
38
- while (separatorIndex >= 0) {
39
- const rawEvent = buffer.slice(0, separatorIndex);
40
- buffer = buffer.slice(separatorIndex + 2);
41
- const data = extractSseData(rawEvent);
42
- if (data) {
43
- onMessage(data);
44
- }
45
- separatorIndex = buffer.indexOf("\n\n");
46
- }
47
- }
48
- } finally {
49
- reader.releaseLock();
50
- }
51
- }
52
- function createSseSubscriber({
53
- backendUrl,
54
- getHeaders,
55
- shouldLog = process.env.NODE_ENV !== "production"
56
- }) {
57
- const subscriptions = /* @__PURE__ */ new Map();
58
- const subscribe2 = (sessionId, onUpdate, onError) => {
59
- const existing = subscriptions.get(sessionId);
60
- const listener = { onUpdate, onError };
61
- if (existing) {
62
- existing.listeners.add(listener);
63
- if (shouldLog) {
64
- console.debug("[aomi][sse] listener added", {
65
- sessionId,
66
- listeners: existing.listeners.size
67
- });
68
- }
69
- return () => {
70
- existing.listeners.delete(listener);
71
- if (shouldLog) {
72
- console.debug("[aomi][sse] listener removed", {
73
- sessionId,
74
- listeners: existing.listeners.size
75
- });
76
- }
77
- if (existing.listeners.size === 0) {
78
- existing.stop("unsubscribe");
79
- if (subscriptions.get(sessionId) === existing) {
80
- subscriptions.delete(sessionId);
81
- }
82
- }
83
- };
84
- }
85
- const subscription = {
86
- abortController: null,
87
- retries: 0,
88
- retryTimer: null,
89
- stopped: false,
90
- listeners: /* @__PURE__ */ new Set([listener]),
91
- stop: (reason) => {
92
- var _a;
93
- subscription.stopped = true;
94
- if (subscription.retryTimer) {
95
- clearTimeout(subscription.retryTimer);
96
- subscription.retryTimer = null;
97
- }
98
- (_a = subscription.abortController) == null ? void 0 : _a.abort();
99
- subscription.abortController = null;
100
- if (shouldLog) {
101
- console.debug("[aomi][sse] stop", {
102
- sessionId,
103
- reason,
104
- retries: subscription.retries
105
- });
106
- }
107
- }
108
- };
109
- const scheduleRetry = () => {
110
- if (subscription.stopped) return;
111
- subscription.retries += 1;
112
- const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 1e4);
113
- if (shouldLog) {
114
- console.debug("[aomi][sse] retry scheduled", {
115
- sessionId,
116
- delayMs,
117
- retries: subscription.retries
118
- });
119
- }
120
- subscription.retryTimer = setTimeout(() => {
121
- void open();
122
- }, delayMs);
123
- };
124
- const open = async () => {
125
- var _a;
126
- if (subscription.stopped) return;
127
- if (subscription.retryTimer) {
128
- clearTimeout(subscription.retryTimer);
129
- subscription.retryTimer = null;
130
- }
131
- const controller = new AbortController();
132
- subscription.abortController = controller;
133
- const openedAt = Date.now();
134
- try {
135
- const response = await fetch(`${backendUrl}/api/updates`, {
136
- headers: getHeaders(sessionId),
137
- signal: controller.signal
138
- });
139
- if (!response.ok) {
140
- throw new Error(
141
- `SSE HTTP ${response.status}: ${response.statusText}`
142
- );
143
- }
144
- if (!response.body) {
145
- throw new Error("SSE response missing body");
146
- }
147
- subscription.retries = 0;
148
- await readSseStream(response.body, controller.signal, (data) => {
149
- var _a2, _b;
150
- let parsed;
151
- try {
152
- parsed = JSON.parse(data);
153
- } catch (error) {
154
- for (const item of subscription.listeners) {
155
- (_a2 = item.onError) == null ? void 0 : _a2.call(item, error);
156
- }
157
- return;
158
- }
159
- for (const item of subscription.listeners) {
160
- try {
161
- item.onUpdate(parsed);
162
- } catch (error) {
163
- (_b = item.onError) == null ? void 0 : _b.call(item, error);
164
- }
165
- }
166
- });
167
- if (shouldLog) {
168
- console.debug("[aomi][sse] stream ended", {
169
- sessionId,
170
- aborted: controller.signal.aborted,
171
- stopped: subscription.stopped,
172
- durationMs: Date.now() - openedAt
173
- });
174
- }
175
- } catch (error) {
176
- if (!controller.signal.aborted && !subscription.stopped) {
177
- for (const item of subscription.listeners) {
178
- (_a = item.onError) == null ? void 0 : _a.call(item, error);
179
- }
180
- }
181
- }
182
- if (!subscription.stopped) {
183
- scheduleRetry();
184
- }
185
- };
186
- subscriptions.set(sessionId, subscription);
187
- void open();
188
- return () => {
189
- subscription.listeners.delete(listener);
190
- if (shouldLog) {
191
- console.debug("[aomi][sse] listener removed", {
192
- sessionId,
193
- listeners: subscription.listeners.size
194
- });
195
- }
196
- if (subscription.listeners.size === 0) {
197
- subscription.stop("unsubscribe");
198
- if (subscriptions.get(sessionId) === subscription) {
199
- subscriptions.delete(sessionId);
200
- }
201
- }
202
- };
203
- };
204
- return { subscribe: subscribe2 };
205
- }
206
-
207
- // packages/react/src/backend/client.ts
208
- var SESSION_ID_HEADER = "X-Session-Id";
209
- var API_KEY_HEADER = "X-API-Key";
210
- function toQueryString(payload) {
211
- const params = new URLSearchParams();
212
- for (const [key, value] of Object.entries(payload)) {
213
- if (value === void 0 || value === null) continue;
214
- params.set(key, String(value));
215
- }
216
- const qs = params.toString();
217
- return qs ? `?${qs}` : "";
218
- }
219
- function withSessionHeader(sessionId, init) {
220
- const headers = new Headers(init);
221
- headers.set(SESSION_ID_HEADER, sessionId);
222
- return headers;
223
- }
224
- async function postState(backendUrl, path, payload, sessionId, apiKey) {
225
- const query = toQueryString(payload);
226
- const url = `${backendUrl}${path}${query}`;
227
- const headers = new Headers(withSessionHeader(sessionId));
228
- if (apiKey) {
229
- headers.set(API_KEY_HEADER, apiKey);
230
- }
231
- const response = await fetch(url, {
232
- method: "POST",
233
- headers
234
- });
235
- if (!response.ok) {
236
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
237
- }
238
- return await response.json();
239
- }
240
- var BackendApi = class {
241
- constructor(backendUrl) {
242
- this.backendUrl = backendUrl;
243
- this.sseSubscriber = createSseSubscriber({
244
- backendUrl,
245
- getHeaders: (sessionId) => withSessionHeader(sessionId, { Accept: "text/event-stream" })
246
- });
247
- }
248
- async fetchState(sessionId, userState) {
249
- const url = new URL("/api/state", this.backendUrl);
250
- if (userState) {
251
- url.searchParams.set("user_state", JSON.stringify(userState));
252
- }
253
- const response = await fetch(url.toString(), {
254
- headers: withSessionHeader(sessionId)
255
- });
256
- if (!response.ok) {
257
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
258
- }
259
- return await response.json();
260
- }
261
- async postChatMessage(sessionId, message, namespace, publicKey, apiKey, userState) {
262
- const payload = { message, namespace };
263
- if (publicKey) {
264
- payload.public_key = publicKey;
265
- }
266
- if (userState) {
267
- payload.user_state = JSON.stringify(userState);
268
- }
269
- return postState(
270
- this.backendUrl,
271
- "/api/chat",
272
- payload,
273
- sessionId,
274
- apiKey
275
- );
276
- }
277
- async postSystemMessage(sessionId, message) {
278
- return postState(
279
- this.backendUrl,
280
- "/api/system",
281
- {
282
- message
283
- },
284
- sessionId
285
- );
286
- }
287
- async postInterrupt(sessionId) {
288
- return postState(
289
- this.backendUrl,
290
- "/api/interrupt",
291
- {},
292
- sessionId
293
- );
294
- }
295
- /**
296
- * Subscribe to SSE updates for a session.
297
- * Uses fetch streaming and reconnects on disconnects.
298
- * Returns an unsubscribe function.
299
- */
300
- subscribeSSE(sessionId, onUpdate, onError) {
301
- return this.sseSubscriber.subscribe(sessionId, onUpdate, onError);
302
- }
303
- async fetchThreads(publicKey) {
304
- const url = `${this.backendUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
305
- const response = await fetch(url);
306
- if (!response.ok) {
307
- throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
308
- }
309
- return await response.json();
310
- }
311
- async fetchThread(sessionId) {
312
- const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
313
- const response = await fetch(url, {
314
- headers: withSessionHeader(sessionId)
315
- });
316
- if (!response.ok) {
317
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
318
- }
319
- return await response.json();
320
- }
321
- async createThread(threadId, publicKey) {
322
- const body = {};
323
- if (publicKey) body.public_key = publicKey;
324
- const url = `${this.backendUrl}/api/sessions`;
325
- const response = await fetch(url, {
326
- method: "POST",
327
- headers: withSessionHeader(threadId, {
328
- "Content-Type": "application/json"
329
- }),
330
- body: JSON.stringify(body)
331
- });
332
- if (!response.ok) {
333
- throw new Error(`Failed to create thread: HTTP ${response.status}`);
334
- }
335
- return await response.json();
336
- }
337
- async archiveThread(sessionId) {
338
- const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
339
- const response = await fetch(url, {
340
- method: "POST",
341
- headers: withSessionHeader(sessionId)
342
- });
343
- if (!response.ok) {
344
- throw new Error(`Failed to archive thread: HTTP ${response.status}`);
345
- }
346
- }
347
- async unarchiveThread(sessionId) {
348
- const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
349
- const response = await fetch(url, {
350
- method: "POST",
351
- headers: withSessionHeader(sessionId)
352
- });
353
- if (!response.ok) {
354
- throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);
355
- }
356
- }
357
- async deleteThread(sessionId) {
358
- const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
359
- const response = await fetch(url, {
360
- method: "DELETE",
361
- headers: withSessionHeader(sessionId)
362
- });
363
- if (!response.ok) {
364
- throw new Error(`Failed to delete thread: HTTP ${response.status}`);
365
- }
366
- }
367
- async renameThread(sessionId, newTitle) {
368
- const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
369
- const response = await fetch(url, {
370
- method: "PATCH",
371
- headers: withSessionHeader(sessionId, {
372
- "Content-Type": "application/json"
373
- }),
374
- body: JSON.stringify({ title: newTitle })
375
- });
376
- if (!response.ok) {
377
- throw new Error(`Failed to rename thread: HTTP ${response.status}`);
378
- }
379
- }
380
- async getSystemEvents(sessionId, count) {
381
- const url = new URL("/api/events", this.backendUrl);
382
- if (count !== void 0) {
383
- url.searchParams.set("count", String(count));
384
- }
385
- const response = await fetch(url.toString(), {
386
- headers: withSessionHeader(sessionId)
387
- });
388
- if (!response.ok) {
389
- if (response.status === 404) return [];
390
- throw new Error(`Failed to get system events: HTTP ${response.status}`);
391
- }
392
- return await response.json();
393
- }
394
- // ===========================================================================
395
- // Control API
396
- // ===========================================================================
397
- /**
398
- * Get allowed namespaces for the current request context.
399
- */
400
- async getNamespaces(sessionId, publicKey, apiKey) {
401
- const url = new URL("/api/control/namespaces", this.backendUrl);
402
- if (publicKey) {
403
- url.searchParams.set("public_key", publicKey);
404
- }
405
- console.log("[BackendApi.getNamespaces]", {
406
- backendUrl: this.backendUrl,
407
- fullUrl: url.toString(),
408
- sessionId,
409
- publicKey
410
- });
411
- const headers = new Headers(withSessionHeader(sessionId));
412
- if (apiKey) {
413
- headers.set(API_KEY_HEADER, apiKey);
414
- }
415
- const response = await fetch(url.toString(), { headers });
416
- if (!response.ok) {
417
- throw new Error(`Failed to get namespaces: HTTP ${response.status}`);
418
- }
419
- return await response.json();
420
- }
421
- /**
422
- * Get available models.
423
- */
424
- async getModels(sessionId) {
425
- const url = new URL("/api/control/models", this.backendUrl);
426
- console.log("[BackendApi.getModels]", {
427
- backendUrl: this.backendUrl,
428
- fullUrl: url.toString(),
429
- sessionId
430
- });
431
- const response = await fetch(url.toString(), {
432
- headers: withSessionHeader(sessionId)
433
- });
434
- if (!response.ok) {
435
- throw new Error(`Failed to get models: HTTP ${response.status}`);
436
- }
437
- return await response.json();
438
- }
439
- /**
440
- * Set the model selection for a session.
441
- */
442
- async setModel(sessionId, rig, namespace, apiKey) {
443
- const payload = { rig };
444
- if (namespace) {
445
- payload.namespace = namespace;
446
- }
447
- return postState(this.backendUrl, "/api/control/model", payload, sessionId, apiKey);
448
- }
449
- };
21
+ // packages/react/src/index.ts
22
+ import { AomiClient as AomiClient2 } from "@aomi-labs/client";
450
23
 
451
24
  // packages/react/src/runtime/aomi-runtime.tsx
452
25
  import { useMemo as useMemo3 } from "react";
26
+ import { AomiClient } from "@aomi-labs/client";
453
27
 
454
28
  // packages/react/src/contexts/control-context.tsx
455
29
  import {
@@ -489,7 +63,7 @@ var logThreadMetadataChange = (source, threadId, prev, next) => {
489
63
  function initThreadControl() {
490
64
  return {
491
65
  model: null,
492
- namespace: null,
66
+ app: null,
493
67
  controlDirty: false,
494
68
  isProcessing: false
495
69
  };
@@ -645,7 +219,7 @@ function useControl() {
645
219
  }
646
220
  function ControlContextProvider({
647
221
  children,
648
- backendApi,
222
+ aomiClient,
649
223
  sessionId,
650
224
  publicKey,
651
225
  getThreadMetadata,
@@ -655,14 +229,14 @@ function ControlContextProvider({
655
229
  const [state, setStateInternal] = useState(() => ({
656
230
  apiKey: null,
657
231
  availableModels: [],
658
- authorizedNamespaces: [],
232
+ authorizedApps: [],
659
233
  defaultModel: null,
660
- defaultNamespace: null
234
+ defaultApp: null
661
235
  }));
662
236
  const stateRef = useRef(state);
663
237
  stateRef.current = state;
664
- const backendApiRef = useRef(backendApi);
665
- backendApiRef.current = backendApi;
238
+ const aomiClientRef = useRef(aomiClient);
239
+ aomiClientRef.current = aomiClient;
666
240
  const sessionIdRef = useRef(sessionId);
667
241
  sessionIdRef.current = sessionId;
668
242
  const publicKeyRef = useRef(publicKey);
@@ -696,33 +270,32 @@ function ControlContextProvider({
696
270
  }
697
271
  }, [state.apiKey]);
698
272
  useEffect(() => {
699
- const fetchNamespaces = async () => {
273
+ const fetchApps = async () => {
700
274
  var _a2, _b2;
701
275
  try {
702
- const namespaces = await backendApiRef.current.getNamespaces(
276
+ const apps = await aomiClientRef.current.getApps(
703
277
  sessionIdRef.current,
704
- publicKeyRef.current,
705
- (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
278
+ { publicKey: publicKeyRef.current, apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0 }
706
279
  );
707
- const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
280
+ const defaultApp = apps.includes("default") ? "default" : (_b2 = apps[0]) != null ? _b2 : null;
708
281
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
709
- authorizedNamespaces: namespaces,
710
- defaultNamespace: defaultNs
282
+ authorizedApps: apps,
283
+ defaultApp
711
284
  }));
712
285
  } catch (error) {
713
- console.error("Failed to fetch namespaces:", error);
286
+ console.error("Failed to fetch apps:", error);
714
287
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
715
- authorizedNamespaces: ["default"],
716
- defaultNamespace: "default"
288
+ authorizedApps: ["default"],
289
+ defaultApp: "default"
717
290
  }));
718
291
  }
719
292
  };
720
- void fetchNamespaces();
293
+ void fetchApps();
721
294
  }, [state.apiKey]);
722
295
  useEffect(() => {
723
296
  const fetchModels = async () => {
724
297
  try {
725
- const models = await backendApiRef.current.getModels(
298
+ const models = await aomiClientRef.current.getModels(
726
299
  sessionIdRef.current
727
300
  );
728
301
  setStateInternal((prev) => {
@@ -747,7 +320,7 @@ function ControlContextProvider({
747
320
  }, []);
748
321
  const getAvailableModels = useCallback(async () => {
749
322
  try {
750
- const models = await backendApiRef.current.getModels(
323
+ const models = await aomiClientRef.current.getModels(
751
324
  sessionIdRef.current
752
325
  );
753
326
  setStateInternal((prev) => {
@@ -763,25 +336,24 @@ function ControlContextProvider({
763
336
  return [];
764
337
  }
765
338
  }, []);
766
- const getAuthorizedNamespaces = useCallback(async () => {
339
+ const getAuthorizedApps = useCallback(async () => {
767
340
  var _a2, _b2;
768
341
  try {
769
- const namespaces = await backendApiRef.current.getNamespaces(
342
+ const apps = await aomiClientRef.current.getApps(
770
343
  sessionIdRef.current,
771
- publicKeyRef.current,
772
- (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
344
+ { publicKey: publicKeyRef.current, apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0 }
773
345
  );
774
- const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
346
+ const defaultApp = apps.includes("default") ? "default" : (_b2 = apps[0]) != null ? _b2 : null;
775
347
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
776
- authorizedNamespaces: namespaces,
777
- defaultNamespace: defaultNs
348
+ authorizedApps: apps,
349
+ defaultApp
778
350
  }));
779
- return namespaces;
351
+ return apps;
780
352
  } catch (error) {
781
- console.error("Failed to fetch namespaces:", error);
353
+ console.error("Failed to fetch apps:", error);
782
354
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
783
- authorizedNamespaces: ["default"],
784
- defaultNamespace: "default"
355
+ authorizedApps: ["default"],
356
+ defaultApp: "default"
785
357
  }));
786
358
  return ["default"];
787
359
  }
@@ -805,32 +377,31 @@ function ControlContextProvider({
805
377
  console.warn("[control-context] Cannot switch model while processing");
806
378
  return;
807
379
  }
808
- const namespace = (_d = (_c = currentControl.namespace) != null ? _c : stateRef.current.defaultNamespace) != null ? _d : "default";
380
+ const app = (_d = (_c = currentControl.app) != null ? _c : stateRef.current.defaultApp) != null ? _d : "default";
809
381
  console.log("[control-context] onModelSelect updating metadata", {
810
382
  threadId,
811
383
  model,
812
- namespace,
384
+ app,
813
385
  currentControl
814
386
  });
815
387
  updateThreadMetadataRef.current(threadId, {
816
388
  control: __spreadProps(__spreadValues({}, currentControl), {
817
389
  model,
818
- namespace,
390
+ app,
819
391
  controlDirty: true
820
392
  })
821
393
  });
822
394
  console.log("[control-context] onModelSelect calling backend setModel", {
823
395
  threadId,
824
396
  model,
825
- namespace,
826
- backendUrl: backendApiRef.current
397
+ app,
398
+ backendUrl: aomiClientRef.current
827
399
  });
828
400
  try {
829
- const result = await backendApiRef.current.setModel(
401
+ const result = await aomiClientRef.current.setModel(
830
402
  threadId,
831
403
  model,
832
- namespace,
833
- (_e = stateRef.current.apiKey) != null ? _e : void 0
404
+ { app, apiKey: (_e = stateRef.current.apiKey) != null ? _e : void 0 }
834
405
  );
835
406
  console.log("[control-context] onModelSelect backend result", result);
836
407
  } catch (err) {
@@ -838,34 +409,34 @@ function ControlContextProvider({
838
409
  throw err;
839
410
  }
840
411
  }, []);
841
- const onNamespaceSelect = useCallback((namespace) => {
412
+ const onAppSelect = useCallback((app) => {
842
413
  var _a2, _b2;
843
414
  const threadId = sessionIdRef.current;
844
415
  const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
845
416
  const isProcessing2 = currentControl.isProcessing;
846
- console.log("[control-context] onNamespaceSelect called", {
847
- namespace,
417
+ console.log("[control-context] onAppSelect called", {
418
+ app,
848
419
  isProcessing: isProcessing2,
849
420
  threadId
850
421
  });
851
422
  if (isProcessing2) {
852
423
  console.warn(
853
- "[control-context] Cannot switch namespace while processing"
424
+ "[control-context] Cannot switch app while processing"
854
425
  );
855
426
  return;
856
427
  }
857
- console.log("[control-context] onNamespaceSelect updating metadata", {
428
+ console.log("[control-context] onAppSelect updating metadata", {
858
429
  threadId,
859
- namespace,
430
+ app,
860
431
  currentControl
861
432
  });
862
433
  updateThreadMetadataRef.current(threadId, {
863
434
  control: __spreadProps(__spreadValues({}, currentControl), {
864
- namespace,
435
+ app,
865
436
  controlDirty: true
866
437
  })
867
438
  });
868
- console.log("[control-context] onNamespaceSelect metadata updated");
439
+ console.log("[control-context] onAppSelect metadata updated");
869
440
  }, []);
870
441
  const markControlSynced = useCallback(() => {
871
442
  var _a2, _b2;
@@ -895,11 +466,11 @@ function ControlContextProvider({
895
466
  if ("apiKey" in updates) {
896
467
  setApiKey((_a2 = updates.apiKey) != null ? _a2 : null);
897
468
  }
898
- if ("namespace" in updates && updates.namespace !== void 0 && updates.namespace !== null) {
899
- onNamespaceSelect(updates.namespace);
469
+ if ("app" in updates && updates.app !== void 0 && updates.app !== null) {
470
+ onAppSelect(updates.app);
900
471
  }
901
472
  },
902
- [setApiKey, onNamespaceSelect]
473
+ [setApiKey, onAppSelect]
903
474
  );
904
475
  return /* @__PURE__ */ jsx(
905
476
  ControlContext.Provider,
@@ -908,10 +479,10 @@ function ControlContextProvider({
908
479
  state,
909
480
  setApiKey,
910
481
  getAvailableModels,
911
- getAuthorizedNamespaces,
482
+ getAuthorizedApps,
912
483
  getCurrentThreadControl,
913
484
  onModelSelect,
914
- onNamespaceSelect,
485
+ onAppSelect,
915
486
  isProcessing,
916
487
  markControlSynced,
917
488
  getControlState,
@@ -932,20 +503,12 @@ import {
932
503
  useRef as useRef2,
933
504
  useState as useState2
934
505
  } from "react";
935
-
936
- // packages/react/src/backend/types.ts
937
- function isInlineCall(event) {
938
- return "InlineCall" in event;
939
- }
940
- function isSystemNotice(event) {
941
- return "SystemNotice" in event;
942
- }
943
- function isSystemError(event) {
944
- return "SystemError" in event;
945
- }
946
- function isAsyncCallback(event) {
947
- return "AsyncCallback" in event;
948
- }
506
+ import {
507
+ isInlineCall,
508
+ isSystemNotice,
509
+ isSystemError,
510
+ isAsyncCallback
511
+ } from "@aomi-labs/client";
949
512
 
950
513
  // packages/react/src/state/event-buffer.ts
951
514
  function createEventBuffer() {
@@ -1005,7 +568,7 @@ function useEventContext() {
1005
568
  }
1006
569
  function EventContextProvider({
1007
570
  children,
1008
- backendApi,
571
+ aomiClient,
1009
572
  sessionId
1010
573
  }) {
1011
574
  const bufferRef = useRef2(null);
@@ -1017,7 +580,7 @@ function EventContextProvider({
1017
580
  useEffect2(() => {
1018
581
  setSSEStatus(buffer, "connecting");
1019
582
  setSseStatus("connecting");
1020
- const unsubscribe = backendApi.subscribeSSE(
583
+ const unsubscribe = aomiClient.subscribeSSE(
1021
584
  sessionId,
1022
585
  (event) => {
1023
586
  enqueueInbound(buffer, {
@@ -1047,7 +610,7 @@ function EventContextProvider({
1047
610
  setSSEStatus(buffer, "disconnected");
1048
611
  setSseStatus("disconnected");
1049
612
  };
1050
- }, [backendApi, sessionId, buffer]);
613
+ }, [aomiClient, sessionId, buffer]);
1051
614
  const subscribeCallback = useCallback2(
1052
615
  (type, callback) => {
1053
616
  return subscribe(buffer, type, callback);
@@ -1061,12 +624,12 @@ function EventContextProvider({
1061
624
  type: event.type,
1062
625
  payload: event.payload
1063
626
  });
1064
- await backendApi.postSystemMessage(event.sessionId, message);
627
+ await aomiClient.sendSystemMessage(event.sessionId, message);
1065
628
  } catch (error) {
1066
629
  console.error("Failed to send outbound event:", error);
1067
630
  }
1068
631
  },
1069
- [backendApi]
632
+ [aomiClient]
1070
633
  );
1071
634
  const dispatchSystemEvents = useCallback2(
1072
635
  (sessionId2, events) => {
@@ -1452,19 +1015,16 @@ var MessageController = class {
1452
1015
  lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
1453
1016
  });
1454
1017
  const backendThreadId = resolveThreadId(backendState, threadId);
1455
- const namespace = this.config.getNamespace();
1018
+ const app = this.config.getApp();
1456
1019
  const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
1457
1020
  const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
1458
1021
  const userState = (_g = (_f = this.config).getUserState) == null ? void 0 : _g.call(_f);
1459
1022
  try {
1460
1023
  this.markRunning(threadId, true);
1461
- const response = await this.config.backendApiRef.current.postChatMessage(
1024
+ const response = await this.config.aomiClientRef.current.sendMessage(
1462
1025
  backendThreadId,
1463
1026
  text,
1464
- namespace,
1465
- publicKey,
1466
- apiKey,
1467
- userState
1027
+ { app, publicKey, apiKey, userState }
1468
1028
  );
1469
1029
  if (response == null ? void 0 : response.messages) {
1470
1030
  this.inbound(threadId, response.messages);
@@ -1488,7 +1048,7 @@ var MessageController = class {
1488
1048
  const backendState = this.config.backendStateRef.current;
1489
1049
  const backendThreadId = resolveThreadId(backendState, threadId);
1490
1050
  try {
1491
- const response = await this.config.backendApiRef.current.postInterrupt(backendThreadId);
1051
+ const response = await this.config.aomiClientRef.current.interrupt(backendThreadId);
1492
1052
  if (response == null ? void 0 : response.messages) {
1493
1053
  this.inbound(threadId, response.messages);
1494
1054
  }
@@ -1536,7 +1096,7 @@ var PollingController = class {
1536
1096
  threadId
1537
1097
  );
1538
1098
  const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
1539
- const state = await this.config.backendApiRef.current.fetchState(
1099
+ const state = await this.config.aomiClientRef.current.fetchState(
1540
1100
  backendThreadId,
1541
1101
  userState
1542
1102
  );
@@ -1584,12 +1144,12 @@ var PollingController = class {
1584
1144
  };
1585
1145
 
1586
1146
  // packages/react/src/runtime/orchestrator.ts
1587
- function useRuntimeOrchestrator(backendApi, options) {
1147
+ function useRuntimeOrchestrator(aomiClient, options) {
1588
1148
  const threadContext = useThreadContext();
1589
1149
  const threadContextRef = useRef5(threadContext);
1590
1150
  threadContextRef.current = threadContext;
1591
- const backendApiRef = useRef5(backendApi);
1592
- backendApiRef.current = backendApi;
1151
+ const aomiClientRef = useRef5(aomiClient);
1152
+ aomiClientRef.current = aomiClient;
1593
1153
  const backendStateRef = useRef5(createBackendState());
1594
1154
  const [isRunning, setIsRunning] = useState5(false);
1595
1155
  const messageControllerRef = useRef5(null);
@@ -1597,7 +1157,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1597
1157
  const pendingFetches = useRef5(/* @__PURE__ */ new Set());
1598
1158
  if (!pollingRef.current) {
1599
1159
  pollingRef.current = new PollingController({
1600
- backendApiRef,
1160
+ aomiClientRef,
1601
1161
  backendStateRef,
1602
1162
  applyMessages: (threadId, msgs) => {
1603
1163
  var _a;
@@ -1619,13 +1179,13 @@ function useRuntimeOrchestrator(backendApi, options) {
1619
1179
  }
1620
1180
  if (!messageControllerRef.current) {
1621
1181
  messageControllerRef.current = new MessageController({
1622
- backendApiRef,
1182
+ aomiClientRef,
1623
1183
  backendStateRef,
1624
1184
  threadContextRef,
1625
1185
  polling: pollingRef.current,
1626
1186
  setGlobalIsRunning: setIsRunning,
1627
1187
  getPublicKey: options.getPublicKey,
1628
- getNamespace: options.getNamespace,
1188
+ getApp: options.getApp,
1629
1189
  getApiKey: options.getApiKey,
1630
1190
  getUserState: options.getUserState,
1631
1191
  onSyncEvents: options.onSyncEvents
@@ -1638,7 +1198,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1638
1198
  pendingFetches.current.add(threadId);
1639
1199
  try {
1640
1200
  const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
1641
- const state = await backendApiRef.current.fetchState(
1201
+ const state = await aomiClientRef.current.fetchState(
1642
1202
  backendThreadId,
1643
1203
  userState
1644
1204
  );
@@ -1670,7 +1230,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1670
1230
  isRunning,
1671
1231
  setIsRunning,
1672
1232
  ensureInitialState,
1673
- backendApiRef
1233
+ aomiClientRef
1674
1234
  };
1675
1235
  }
1676
1236
 
@@ -1701,7 +1261,7 @@ function buildThreadLists(threadMetadata) {
1701
1261
  return { regularThreads, archivedThreads };
1702
1262
  }
1703
1263
  function buildThreadListAdapter({
1704
- backendApiRef,
1264
+ aomiClientRef,
1705
1265
  threadContext,
1706
1266
  setIsRunning
1707
1267
  }) {
@@ -1729,6 +1289,7 @@ function buildThreadListAdapter({
1729
1289
  },
1730
1290
  onSwitchToThread: (threadId) => {
1731
1291
  threadContext.setCurrentThreadId(threadId);
1292
+ threadContext.bumpThreadViewKey();
1732
1293
  },
1733
1294
  onRename: async (threadId, newTitle) => {
1734
1295
  var _a, _b;
@@ -1738,7 +1299,7 @@ function buildThreadListAdapter({
1738
1299
  title: normalizedTitle
1739
1300
  });
1740
1301
  try {
1741
- await backendApiRef.current.renameThread(threadId, newTitle);
1302
+ await aomiClientRef.current.renameThread(threadId, newTitle);
1742
1303
  } catch (error) {
1743
1304
  console.error("Failed to rename thread:", error);
1744
1305
  threadContext.updateThreadMetadata(threadId, {
@@ -1749,7 +1310,7 @@ function buildThreadListAdapter({
1749
1310
  onArchive: async (threadId) => {
1750
1311
  threadContext.updateThreadMetadata(threadId, { status: "archived" });
1751
1312
  try {
1752
- await backendApiRef.current.archiveThread(threadId);
1313
+ await aomiClientRef.current.archiveThread(threadId);
1753
1314
  } catch (error) {
1754
1315
  console.error("Failed to archive thread:", error);
1755
1316
  threadContext.updateThreadMetadata(threadId, { status: "regular" });
@@ -1758,7 +1319,7 @@ function buildThreadListAdapter({
1758
1319
  onUnarchive: async (threadId) => {
1759
1320
  threadContext.updateThreadMetadata(threadId, { status: "regular" });
1760
1321
  try {
1761
- await backendApiRef.current.unarchiveThread(threadId);
1322
+ await aomiClientRef.current.unarchiveThread(threadId);
1762
1323
  } catch (error) {
1763
1324
  console.error("Failed to unarchive thread:", error);
1764
1325
  threadContext.updateThreadMetadata(threadId, { status: "archived" });
@@ -1766,7 +1327,7 @@ function buildThreadListAdapter({
1766
1327
  },
1767
1328
  onDelete: async (threadId) => {
1768
1329
  try {
1769
- await backendApiRef.current.deleteThread(threadId);
1330
+ await aomiClientRef.current.deleteThread(threadId);
1770
1331
  threadContext.setThreadMetadata((prev) => {
1771
1332
  const next = new Map(prev);
1772
1333
  next.delete(threadId);
@@ -1853,6 +1414,68 @@ function getAll(buffer) {
1853
1414
  }
1854
1415
 
1855
1416
  // packages/react/src/handlers/wallet-handler.ts
1417
+ function asRecord(value) {
1418
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1419
+ return value;
1420
+ }
1421
+ function getToolArgs(payload) {
1422
+ const root = asRecord(payload);
1423
+ const nestedArgs = asRecord(root == null ? void 0 : root.args);
1424
+ return nestedArgs != null ? nestedArgs : root != null ? root : {};
1425
+ }
1426
+ function parseChainId(value) {
1427
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1428
+ if (typeof value !== "string") return void 0;
1429
+ const trimmed = value.trim();
1430
+ if (!trimmed) return void 0;
1431
+ if (trimmed.startsWith("0x")) {
1432
+ const parsedHex = Number.parseInt(trimmed.slice(2), 16);
1433
+ return Number.isFinite(parsedHex) ? parsedHex : void 0;
1434
+ }
1435
+ const parsed = Number.parseInt(trimmed, 10);
1436
+ return Number.isFinite(parsed) ? parsed : void 0;
1437
+ }
1438
+ function normalizeTxPayload(payload) {
1439
+ var _a, _b, _c;
1440
+ const root = asRecord(payload);
1441
+ const args = getToolArgs(payload);
1442
+ const ctx = asRecord(root == null ? void 0 : root.ctx);
1443
+ const to = typeof args.to === "string" ? args.to : void 0;
1444
+ if (!to) return null;
1445
+ const valueRaw = args.value;
1446
+ const value = typeof valueRaw === "string" ? valueRaw : typeof valueRaw === "number" && Number.isFinite(valueRaw) ? String(Math.trunc(valueRaw)) : void 0;
1447
+ const data = typeof args.data === "string" ? args.data : void 0;
1448
+ const chainId = (_c = (_b = (_a = parseChainId(args.chainId)) != null ? _a : parseChainId(args.chain_id)) != null ? _b : parseChainId(ctx == null ? void 0 : ctx.user_chain_id)) != null ? _c : parseChainId(ctx == null ? void 0 : ctx.userChainId);
1449
+ return {
1450
+ to,
1451
+ value,
1452
+ data,
1453
+ chainId
1454
+ };
1455
+ }
1456
+ function normalizeEip712Payload(payload) {
1457
+ var _a;
1458
+ const args = getToolArgs(payload);
1459
+ const typedDataRaw = (_a = args.typed_data) != null ? _a : args.typedData;
1460
+ let typedData;
1461
+ if (typeof typedDataRaw === "string") {
1462
+ try {
1463
+ const parsed = JSON.parse(typedDataRaw);
1464
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1465
+ typedData = parsed;
1466
+ }
1467
+ } catch (e) {
1468
+ typedData = void 0;
1469
+ }
1470
+ } else if (typedDataRaw && typeof typedDataRaw === "object" && !Array.isArray(typedDataRaw)) {
1471
+ typedData = typedDataRaw;
1472
+ }
1473
+ const description = typeof args.description === "string" ? args.description : void 0;
1474
+ return {
1475
+ typed_data: typedData,
1476
+ description
1477
+ };
1478
+ }
1856
1479
  function useWalletHandler({
1857
1480
  sessionId,
1858
1481
  onRequestComplete
@@ -1867,7 +1490,11 @@ function useWalletHandler({
1867
1490
  const unsubscribe = subscribe2(
1868
1491
  "wallet_tx_request",
1869
1492
  (event) => {
1870
- const payload = event.payload;
1493
+ const payload = normalizeTxPayload(event.payload);
1494
+ if (!payload) {
1495
+ console.warn("[aomi][wallet] Ignoring tx request with invalid payload", event.payload);
1496
+ return;
1497
+ }
1871
1498
  enqueue(bufferRef.current, "transaction", payload);
1872
1499
  syncState();
1873
1500
  }
@@ -1879,7 +1506,7 @@ function useWalletHandler({
1879
1506
  "wallet_eip712_request",
1880
1507
  (event) => {
1881
1508
  var _a;
1882
- const payload = (_a = event.payload) != null ? _a : {};
1509
+ const payload = normalizeEip712Payload((_a = event.payload) != null ? _a : {});
1883
1510
  enqueue(bufferRef.current, "eip712_sign", payload);
1884
1511
  syncState();
1885
1512
  }
@@ -1969,7 +1596,7 @@ function useWalletHandler({
1969
1596
  import { jsx as jsx6 } from "react/jsx-runtime";
1970
1597
  function AomiRuntimeCore({
1971
1598
  children,
1972
- backendApi
1599
+ aomiClient
1973
1600
  }) {
1974
1601
  const threadContext = useThreadContext();
1975
1602
  const eventContext = useEventContext();
@@ -1984,14 +1611,14 @@ function AomiRuntimeCore({
1984
1611
  isRunning,
1985
1612
  setIsRunning,
1986
1613
  ensureInitialState,
1987
- backendApiRef
1988
- } = useRuntimeOrchestrator(backendApi, {
1614
+ aomiClientRef
1615
+ } = useRuntimeOrchestrator(aomiClient, {
1989
1616
  onSyncEvents: dispatchSystemEvents,
1990
1617
  getPublicKey: () => getUserState().address,
1991
1618
  getUserState,
1992
- getNamespace: () => {
1619
+ getApp: () => {
1993
1620
  var _a, _b;
1994
- return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
1621
+ return (_b = (_a = getCurrentThreadControl().app) != null ? _a : getControlState().defaultApp) != null ? _b : "default";
1995
1622
  },
1996
1623
  getApiKey: () => getControlState().apiKey
1997
1624
  });
@@ -2007,10 +1634,10 @@ function AomiRuntimeCore({
2007
1634
  ensName: newUser.ensName
2008
1635
  }
2009
1636
  });
2010
- await backendApiRef.current.postSystemMessage(sessionId, message);
1637
+ await aomiClientRef.current.sendSystemMessage(sessionId, message);
2011
1638
  });
2012
1639
  return unsubscribe;
2013
- }, [onUserStateChange, backendApiRef, threadContext.currentThreadId]);
1640
+ }, [onUserStateChange, aomiClientRef, threadContext.currentThreadId]);
2014
1641
  const threadContextRef = useRef7(threadContext);
2015
1642
  threadContextRef.current = threadContext;
2016
1643
  const currentThreadIdRef = useRef7(threadContext.currentThreadId);
@@ -2058,21 +1685,13 @@ function AomiRuntimeCore({
2058
1685
  const currentMessages = threadContext.getThreadMessages(
2059
1686
  threadContext.currentThreadId
2060
1687
  );
2061
- const resolvedSessionId = useMemo2(
2062
- () => resolveThreadId(backendStateRef.current, threadContext.currentThreadId),
2063
- [
2064
- backendStateRef,
2065
- threadContext.currentThreadId,
2066
- threadContext.allThreadsMetadata
2067
- ]
2068
- );
2069
1688
  useEffect4(() => {
2070
1689
  const userAddress = user.address;
2071
1690
  if (!userAddress) return;
2072
1691
  const fetchThreadList = async () => {
2073
1692
  var _a, _b, _c;
2074
1693
  try {
2075
- const threadList = await backendApiRef.current.fetchThreads(userAddress);
1694
+ const threadList = await aomiClientRef.current.listThreads(userAddress);
2076
1695
  const currentContext = threadContextRef.current;
2077
1696
  const newMetadata = new Map(currentContext.allThreadsMetadata);
2078
1697
  let maxChatNum = currentContext.threadCnt;
@@ -2104,25 +1723,25 @@ function AomiRuntimeCore({
2104
1723
  }
2105
1724
  };
2106
1725
  void fetchThreadList();
2107
- }, [user.address, backendApiRef]);
1726
+ }, [user.address, aomiClientRef]);
2108
1727
  const threadListAdapter = useMemo2(
2109
1728
  () => buildThreadListAdapter({
2110
1729
  backendStateRef,
2111
- backendApiRef,
1730
+ aomiClientRef,
2112
1731
  threadContext,
2113
1732
  currentThreadIdRef,
2114
1733
  polling,
2115
1734
  userAddress: user.address,
2116
1735
  setIsRunning,
2117
- getNamespace: () => {
1736
+ getApp: () => {
2118
1737
  var _a, _b;
2119
- return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
1738
+ return (_b = (_a = getCurrentThreadControl().app) != null ? _a : getControlState().defaultApp) != null ? _b : "default";
2120
1739
  },
2121
1740
  getApiKey: () => getControlState().apiKey,
2122
1741
  getUserState
2123
1742
  }),
2124
1743
  [
2125
- backendApiRef,
1744
+ aomiClientRef,
2126
1745
  polling,
2127
1746
  user.address,
2128
1747
  backendStateRef,
@@ -2136,58 +1755,38 @@ function AomiRuntimeCore({
2136
1755
  );
2137
1756
  useEffect4(() => {
2138
1757
  const backendState = backendStateRef.current;
2139
- const currentSessionId = threadContext.currentThreadId;
2140
- if (process.env.NODE_ENV !== "production") {
2141
- console.debug("[aomi][sse] subscribe", {
2142
- currentSessionId,
2143
- resolvedSessionId,
2144
- hasMapping: currentSessionId !== resolvedSessionId
2145
- });
2146
- }
2147
- const unsubscribe = backendApiRef.current.subscribeSSE(
2148
- resolvedSessionId,
2149
- (event) => {
2150
- const eventType = event.type;
2151
- const sessionId = event.session_id;
2152
- if (eventType === "title_changed") {
2153
- const newTitle = event.new_title;
2154
- const targetThreadId = resolveThreadId(backendState, sessionId);
2155
- const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
2156
- if (process.env.NODE_ENV !== "production") {
2157
- console.debug("[aomi][sse] title_changed", {
2158
- sessionId,
2159
- newTitle,
2160
- normalizedTitle,
2161
- currentThreadId: threadContextRef.current.currentThreadId,
2162
- targetThreadId,
2163
- hasMapping: sessionId !== targetThreadId
2164
- });
2165
- }
2166
- threadContextRef.current.setThreadMetadata((prev) => {
2167
- var _a, _b;
2168
- const next = new Map(prev);
2169
- const existing = next.get(targetThreadId);
2170
- const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
2171
- next.set(targetThreadId, {
2172
- title: normalizedTitle,
2173
- status: nextStatus,
2174
- lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
2175
- control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
2176
- });
2177
- return next;
2178
- });
2179
- }
1758
+ const unsubscribe = eventContext.subscribe("title_changed", (event) => {
1759
+ const sessionId = event.sessionId;
1760
+ const payload = event.payload;
1761
+ const newTitle = payload == null ? void 0 : payload.new_title;
1762
+ if (typeof newTitle !== "string") return;
1763
+ const targetThreadId = resolveThreadId(backendState, sessionId);
1764
+ const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
1765
+ if (process.env.NODE_ENV !== "production") {
1766
+ console.debug("[aomi][sse] title_changed", {
1767
+ sessionId,
1768
+ newTitle,
1769
+ normalizedTitle,
1770
+ currentThreadId: threadContextRef.current.currentThreadId,
1771
+ targetThreadId
1772
+ });
2180
1773
  }
2181
- );
2182
- return () => {
2183
- unsubscribe == null ? void 0 : unsubscribe();
2184
- };
2185
- }, [
2186
- backendApiRef,
2187
- backendStateRef,
2188
- threadContext.currentThreadId,
2189
- resolvedSessionId
2190
- ]);
1774
+ threadContextRef.current.setThreadMetadata((prev) => {
1775
+ var _a, _b;
1776
+ const next = new Map(prev);
1777
+ const existing = next.get(targetThreadId);
1778
+ const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
1779
+ next.set(targetThreadId, {
1780
+ title: normalizedTitle,
1781
+ status: nextStatus,
1782
+ lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
1783
+ control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
1784
+ });
1785
+ return next;
1786
+ });
1787
+ });
1788
+ return unsubscribe;
1789
+ }, [eventContext, backendStateRef]);
2191
1790
  useEffect4(() => {
2192
1791
  const showToolNotification = (eventType) => (event) => {
2193
1792
  const payload = event.payload;
@@ -2356,12 +1955,12 @@ function AomiRuntimeProvider({
2356
1955
  children,
2357
1956
  backendUrl = "http://localhost:8080"
2358
1957
  }) {
2359
- const backendApi = useMemo3(() => new BackendApi(backendUrl), [backendUrl]);
2360
- return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, { backendApi, children }) }) }) });
1958
+ const aomiClient = useMemo3(() => new AomiClient({ baseUrl: backendUrl }), [backendUrl]);
1959
+ return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, { aomiClient, children }) }) }) });
2361
1960
  }
2362
1961
  function AomiRuntimeInner({
2363
1962
  children,
2364
- backendApi
1963
+ aomiClient
2365
1964
  }) {
2366
1965
  var _a;
2367
1966
  const threadContext = useThreadContext();
@@ -2369,7 +1968,7 @@ function AomiRuntimeInner({
2369
1968
  return /* @__PURE__ */ jsx7(
2370
1969
  ControlContextProvider,
2371
1970
  {
2372
- backendApi,
1971
+ aomiClient,
2373
1972
  sessionId: threadContext.currentThreadId,
2374
1973
  publicKey: (_a = user.address) != null ? _a : void 0,
2375
1974
  getThreadMetadata: threadContext.getThreadMetadata,
@@ -2377,9 +1976,9 @@ function AomiRuntimeInner({
2377
1976
  children: /* @__PURE__ */ jsx7(
2378
1977
  EventContextProvider,
2379
1978
  {
2380
- backendApi,
1979
+ aomiClient,
2381
1980
  sessionId: threadContext.currentThreadId,
2382
- children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { backendApi, children })
1981
+ children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { aomiClient, children })
2383
1982
  }
2384
1983
  )
2385
1984
  }
@@ -2428,8 +2027,8 @@ function useNotificationHandler({
2428
2027
  };
2429
2028
  }
2430
2029
  export {
2030
+ AomiClient2 as AomiClient,
2431
2031
  AomiRuntimeProvider,
2432
- BackendApi,
2433
2032
  ControlContextProvider,
2434
2033
  EventContextProvider,
2435
2034
  NotificationContextProvider,