@aomi-labs/react 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18,438 +18,13 @@ 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";
23
+ import { toViemSignTypedDataArgs } from "@aomi-labs/client";
450
24
 
451
25
  // packages/react/src/runtime/aomi-runtime.tsx
452
26
  import { useMemo as useMemo3 } from "react";
27
+ import { AomiClient } from "@aomi-labs/client";
453
28
 
454
29
  // packages/react/src/contexts/control-context.tsx
455
30
  import {
@@ -489,7 +64,7 @@ var logThreadMetadataChange = (source, threadId, prev, next) => {
489
64
  function initThreadControl() {
490
65
  return {
491
66
  model: null,
492
- namespace: null,
67
+ app: null,
493
68
  controlDirty: false,
494
69
  isProcessing: false
495
70
  };
@@ -635,6 +210,16 @@ var ThreadStore = class {
635
210
  // packages/react/src/contexts/control-context.tsx
636
211
  import { jsx } from "react/jsx-runtime";
637
212
  var API_KEY_STORAGE_KEY = "aomi_api_key";
213
+ function getDefaultApp(apps) {
214
+ var _a;
215
+ return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
216
+ }
217
+ function resolveAuthorizedApp(app, authorizedApps, defaultApp) {
218
+ if (app && authorizedApps.includes(app)) {
219
+ return app;
220
+ }
221
+ return defaultApp;
222
+ }
638
223
  var ControlContext = createContext(null);
639
224
  function useControl() {
640
225
  const ctx = useContext(ControlContext);
@@ -645,7 +230,7 @@ function useControl() {
645
230
  }
646
231
  function ControlContextProvider({
647
232
  children,
648
- backendApi,
233
+ aomiClient,
649
234
  sessionId,
650
235
  publicKey,
651
236
  getThreadMetadata,
@@ -655,14 +240,14 @@ function ControlContextProvider({
655
240
  const [state, setStateInternal] = useState(() => ({
656
241
  apiKey: null,
657
242
  availableModels: [],
658
- authorizedNamespaces: [],
243
+ authorizedApps: [],
659
244
  defaultModel: null,
660
- defaultNamespace: null
245
+ defaultApp: null
661
246
  }));
662
247
  const stateRef = useRef(state);
663
248
  stateRef.current = state;
664
- const backendApiRef = useRef(backendApi);
665
- backendApiRef.current = backendApi;
249
+ const aomiClientRef = useRef(aomiClient);
250
+ aomiClientRef.current = aomiClient;
666
251
  const sessionIdRef = useRef(sessionId);
667
252
  sessionIdRef.current = sessionId;
668
253
  const publicKeyRef = useRef(publicKey);
@@ -696,33 +281,35 @@ function ControlContextProvider({
696
281
  }
697
282
  }, [state.apiKey]);
698
283
  useEffect(() => {
699
- const fetchNamespaces = async () => {
700
- var _a2, _b2;
284
+ const fetchApps = async () => {
285
+ var _a2;
701
286
  try {
702
- const namespaces = await backendApiRef.current.getNamespaces(
287
+ const apps = await aomiClientRef.current.getApps(
703
288
  sessionIdRef.current,
704
- publicKeyRef.current,
705
- (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
289
+ {
290
+ publicKey: publicKeyRef.current,
291
+ apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
292
+ }
706
293
  );
707
- const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
294
+ const defaultApp = getDefaultApp(apps);
708
295
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
709
- authorizedNamespaces: namespaces,
710
- defaultNamespace: defaultNs
296
+ authorizedApps: apps,
297
+ defaultApp
711
298
  }));
712
299
  } catch (error) {
713
- console.error("Failed to fetch namespaces:", error);
300
+ console.error("Failed to fetch apps:", error);
714
301
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
715
- authorizedNamespaces: ["default"],
716
- defaultNamespace: "default"
302
+ authorizedApps: ["default"],
303
+ defaultApp: "default"
717
304
  }));
718
305
  }
719
306
  };
720
- void fetchNamespaces();
721
- }, [state.apiKey]);
307
+ void fetchApps();
308
+ }, [state.apiKey, publicKey, sessionId]);
722
309
  useEffect(() => {
723
310
  const fetchModels = async () => {
724
311
  try {
725
- const models = await backendApiRef.current.getModels(
312
+ const models = await aomiClientRef.current.getModels(
726
313
  sessionIdRef.current
727
314
  );
728
315
  setStateInternal((prev) => {
@@ -747,7 +334,7 @@ function ControlContextProvider({
747
334
  }, []);
748
335
  const getAvailableModels = useCallback(async () => {
749
336
  try {
750
- const models = await backendApiRef.current.getModels(
337
+ const models = await aomiClientRef.current.getModels(
751
338
  sessionIdRef.current
752
339
  );
753
340
  setStateInternal((prev) => {
@@ -763,25 +350,27 @@ function ControlContextProvider({
763
350
  return [];
764
351
  }
765
352
  }, []);
766
- const getAuthorizedNamespaces = useCallback(async () => {
767
- var _a2, _b2;
353
+ const getAuthorizedApps = useCallback(async () => {
354
+ var _a2;
768
355
  try {
769
- const namespaces = await backendApiRef.current.getNamespaces(
356
+ const apps = await aomiClientRef.current.getApps(
770
357
  sessionIdRef.current,
771
- publicKeyRef.current,
772
- (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
358
+ {
359
+ publicKey: publicKeyRef.current,
360
+ apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
361
+ }
773
362
  );
774
- const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
363
+ const defaultApp = getDefaultApp(apps);
775
364
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
776
- authorizedNamespaces: namespaces,
777
- defaultNamespace: defaultNs
365
+ authorizedApps: apps,
366
+ defaultApp
778
367
  }));
779
- return namespaces;
368
+ return apps;
780
369
  } catch (error) {
781
- console.error("Failed to fetch namespaces:", error);
370
+ console.error("Failed to fetch apps:", error);
782
371
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
783
- authorizedNamespaces: ["default"],
784
- defaultNamespace: "default"
372
+ authorizedApps: ["default"],
373
+ defaultApp: "default"
785
374
  }));
786
375
  return ["default"];
787
376
  }
@@ -791,8 +380,17 @@ function ControlContextProvider({
791
380
  const metadata = getThreadMetadataRef.current(sessionIdRef.current);
792
381
  return (_a2 = metadata == null ? void 0 : metadata.control) != null ? _a2 : initThreadControl();
793
382
  }, []);
383
+ const getCurrentThreadApp = useCallback(() => {
384
+ var _a2, _b2, _c;
385
+ const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(sessionIdRef.current)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
386
+ return (_c = resolveAuthorizedApp(
387
+ currentControl.app,
388
+ stateRef.current.authorizedApps,
389
+ stateRef.current.defaultApp
390
+ )) != null ? _c : "default";
391
+ }, []);
794
392
  const onModelSelect = useCallback(async (model) => {
795
- var _a2, _b2, _c, _d, _e;
393
+ var _a2, _b2, _c, _d;
796
394
  const threadId = sessionIdRef.current;
797
395
  const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
798
396
  const isProcessing2 = currentControl.isProcessing;
@@ -805,32 +403,35 @@ function ControlContextProvider({
805
403
  console.warn("[control-context] Cannot switch model while processing");
806
404
  return;
807
405
  }
808
- const namespace = (_d = (_c = currentControl.namespace) != null ? _c : stateRef.current.defaultNamespace) != null ? _d : "default";
406
+ const app = (_c = resolveAuthorizedApp(
407
+ currentControl.app,
408
+ stateRef.current.authorizedApps,
409
+ stateRef.current.defaultApp
410
+ )) != null ? _c : "default";
809
411
  console.log("[control-context] onModelSelect updating metadata", {
810
412
  threadId,
811
413
  model,
812
- namespace,
414
+ app,
813
415
  currentControl
814
416
  });
815
417
  updateThreadMetadataRef.current(threadId, {
816
418
  control: __spreadProps(__spreadValues({}, currentControl), {
817
419
  model,
818
- namespace,
420
+ app,
819
421
  controlDirty: true
820
422
  })
821
423
  });
822
424
  console.log("[control-context] onModelSelect calling backend setModel", {
823
425
  threadId,
824
426
  model,
825
- namespace,
826
- backendUrl: backendApiRef.current
427
+ app,
428
+ backendUrl: aomiClientRef.current
827
429
  });
828
430
  try {
829
- const result = await backendApiRef.current.setModel(
431
+ const result = await aomiClientRef.current.setModel(
830
432
  threadId,
831
433
  model,
832
- namespace,
833
- (_e = stateRef.current.apiKey) != null ? _e : void 0
434
+ { app, apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0 }
834
435
  );
835
436
  console.log("[control-context] onModelSelect backend result", result);
836
437
  } catch (err) {
@@ -838,34 +439,38 @@ function ControlContextProvider({
838
439
  throw err;
839
440
  }
840
441
  }, []);
841
- const onNamespaceSelect = useCallback((namespace) => {
442
+ const onAppSelect = useCallback((app) => {
842
443
  var _a2, _b2;
843
444
  const threadId = sessionIdRef.current;
844
445
  const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
845
446
  const isProcessing2 = currentControl.isProcessing;
846
- console.log("[control-context] onNamespaceSelect called", {
847
- namespace,
447
+ console.log("[control-context] onAppSelect called", {
448
+ app,
848
449
  isProcessing: isProcessing2,
849
450
  threadId
850
451
  });
851
452
  if (isProcessing2) {
852
453
  console.warn(
853
- "[control-context] Cannot switch namespace while processing"
454
+ "[control-context] Cannot switch app while processing"
854
455
  );
855
456
  return;
856
457
  }
857
- console.log("[control-context] onNamespaceSelect updating metadata", {
458
+ if (stateRef.current.authorizedApps.length > 0 && !stateRef.current.authorizedApps.includes(app)) {
459
+ console.warn("[control-context] Cannot select unauthorized app", { app });
460
+ return;
461
+ }
462
+ console.log("[control-context] onAppSelect updating metadata", {
858
463
  threadId,
859
- namespace,
464
+ app,
860
465
  currentControl
861
466
  });
862
467
  updateThreadMetadataRef.current(threadId, {
863
468
  control: __spreadProps(__spreadValues({}, currentControl), {
864
- namespace,
469
+ app,
865
470
  controlDirty: true
866
471
  })
867
472
  });
868
- console.log("[control-context] onNamespaceSelect metadata updated");
473
+ console.log("[control-context] onAppSelect metadata updated");
869
474
  }, []);
870
475
  const markControlSynced = useCallback(() => {
871
476
  var _a2, _b2;
@@ -895,11 +500,11 @@ function ControlContextProvider({
895
500
  if ("apiKey" in updates) {
896
501
  setApiKey((_a2 = updates.apiKey) != null ? _a2 : null);
897
502
  }
898
- if ("namespace" in updates && updates.namespace !== void 0 && updates.namespace !== null) {
899
- onNamespaceSelect(updates.namespace);
503
+ if ("app" in updates && updates.app !== void 0 && updates.app !== null) {
504
+ onAppSelect(updates.app);
900
505
  }
901
506
  },
902
- [setApiKey, onNamespaceSelect]
507
+ [setApiKey, onAppSelect]
903
508
  );
904
509
  return /* @__PURE__ */ jsx(
905
510
  ControlContext.Provider,
@@ -908,10 +513,11 @@ function ControlContextProvider({
908
513
  state,
909
514
  setApiKey,
910
515
  getAvailableModels,
911
- getAuthorizedNamespaces,
516
+ getAuthorizedApps,
912
517
  getCurrentThreadControl,
518
+ getCurrentThreadApp,
913
519
  onModelSelect,
914
- onNamespaceSelect,
520
+ onAppSelect,
915
521
  isProcessing,
916
522
  markControlSynced,
917
523
  getControlState,
@@ -932,20 +538,12 @@ import {
932
538
  useRef as useRef2,
933
539
  useState as useState2
934
540
  } 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
- }
541
+ import {
542
+ isInlineCall,
543
+ isSystemNotice,
544
+ isSystemError,
545
+ isAsyncCallback
546
+ } from "@aomi-labs/client";
949
547
 
950
548
  // packages/react/src/state/event-buffer.ts
951
549
  function createEventBuffer() {
@@ -1005,7 +603,7 @@ function useEventContext() {
1005
603
  }
1006
604
  function EventContextProvider({
1007
605
  children,
1008
- backendApi,
606
+ aomiClient,
1009
607
  sessionId
1010
608
  }) {
1011
609
  const bufferRef = useRef2(null);
@@ -1017,7 +615,7 @@ function EventContextProvider({
1017
615
  useEffect2(() => {
1018
616
  setSSEStatus(buffer, "connecting");
1019
617
  setSseStatus("connecting");
1020
- const unsubscribe = backendApi.subscribeSSE(
618
+ const unsubscribe = aomiClient.subscribeSSE(
1021
619
  sessionId,
1022
620
  (event) => {
1023
621
  enqueueInbound(buffer, {
@@ -1047,7 +645,7 @@ function EventContextProvider({
1047
645
  setSSEStatus(buffer, "disconnected");
1048
646
  setSseStatus("disconnected");
1049
647
  };
1050
- }, [backendApi, sessionId, buffer]);
648
+ }, [aomiClient, sessionId, buffer]);
1051
649
  const subscribeCallback = useCallback2(
1052
650
  (type, callback) => {
1053
651
  return subscribe(buffer, type, callback);
@@ -1061,12 +659,12 @@ function EventContextProvider({
1061
659
  type: event.type,
1062
660
  payload: event.payload
1063
661
  });
1064
- await backendApi.postSystemMessage(event.sessionId, message);
662
+ await aomiClient.sendSystemMessage(event.sessionId, message);
1065
663
  } catch (error) {
1066
664
  console.error("Failed to send outbound event:", error);
1067
665
  }
1068
666
  },
1069
- [backendApi]
667
+ [aomiClient]
1070
668
  );
1071
669
  const dispatchSystemEvents = useCallback2(
1072
670
  (sessionId2, events) => {
@@ -1452,19 +1050,16 @@ var MessageController = class {
1452
1050
  lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
1453
1051
  });
1454
1052
  const backendThreadId = resolveThreadId(backendState, threadId);
1455
- const namespace = this.config.getNamespace();
1053
+ const app = this.config.getApp();
1456
1054
  const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
1457
1055
  const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
1458
1056
  const userState = (_g = (_f = this.config).getUserState) == null ? void 0 : _g.call(_f);
1459
1057
  try {
1460
1058
  this.markRunning(threadId, true);
1461
- const response = await this.config.backendApiRef.current.postChatMessage(
1059
+ const response = await this.config.aomiClientRef.current.sendMessage(
1462
1060
  backendThreadId,
1463
1061
  text,
1464
- namespace,
1465
- publicKey,
1466
- apiKey,
1467
- userState
1062
+ { app, publicKey, apiKey, userState }
1468
1063
  );
1469
1064
  if (response == null ? void 0 : response.messages) {
1470
1065
  this.inbound(threadId, response.messages);
@@ -1488,7 +1083,7 @@ var MessageController = class {
1488
1083
  const backendState = this.config.backendStateRef.current;
1489
1084
  const backendThreadId = resolveThreadId(backendState, threadId);
1490
1085
  try {
1491
- const response = await this.config.backendApiRef.current.postInterrupt(backendThreadId);
1086
+ const response = await this.config.aomiClientRef.current.interrupt(backendThreadId);
1492
1087
  if (response == null ? void 0 : response.messages) {
1493
1088
  this.inbound(threadId, response.messages);
1494
1089
  }
@@ -1536,7 +1131,7 @@ var PollingController = class {
1536
1131
  threadId
1537
1132
  );
1538
1133
  const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
1539
- const state = await this.config.backendApiRef.current.fetchState(
1134
+ const state = await this.config.aomiClientRef.current.fetchState(
1540
1135
  backendThreadId,
1541
1136
  userState
1542
1137
  );
@@ -1584,12 +1179,12 @@ var PollingController = class {
1584
1179
  };
1585
1180
 
1586
1181
  // packages/react/src/runtime/orchestrator.ts
1587
- function useRuntimeOrchestrator(backendApi, options) {
1182
+ function useRuntimeOrchestrator(aomiClient, options) {
1588
1183
  const threadContext = useThreadContext();
1589
1184
  const threadContextRef = useRef5(threadContext);
1590
1185
  threadContextRef.current = threadContext;
1591
- const backendApiRef = useRef5(backendApi);
1592
- backendApiRef.current = backendApi;
1186
+ const aomiClientRef = useRef5(aomiClient);
1187
+ aomiClientRef.current = aomiClient;
1593
1188
  const backendStateRef = useRef5(createBackendState());
1594
1189
  const [isRunning, setIsRunning] = useState5(false);
1595
1190
  const messageControllerRef = useRef5(null);
@@ -1597,7 +1192,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1597
1192
  const pendingFetches = useRef5(/* @__PURE__ */ new Set());
1598
1193
  if (!pollingRef.current) {
1599
1194
  pollingRef.current = new PollingController({
1600
- backendApiRef,
1195
+ aomiClientRef,
1601
1196
  backendStateRef,
1602
1197
  applyMessages: (threadId, msgs) => {
1603
1198
  var _a;
@@ -1619,13 +1214,13 @@ function useRuntimeOrchestrator(backendApi, options) {
1619
1214
  }
1620
1215
  if (!messageControllerRef.current) {
1621
1216
  messageControllerRef.current = new MessageController({
1622
- backendApiRef,
1217
+ aomiClientRef,
1623
1218
  backendStateRef,
1624
1219
  threadContextRef,
1625
1220
  polling: pollingRef.current,
1626
1221
  setGlobalIsRunning: setIsRunning,
1627
1222
  getPublicKey: options.getPublicKey,
1628
- getNamespace: options.getNamespace,
1223
+ getApp: options.getApp,
1629
1224
  getApiKey: options.getApiKey,
1630
1225
  getUserState: options.getUserState,
1631
1226
  onSyncEvents: options.onSyncEvents
@@ -1638,7 +1233,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1638
1233
  pendingFetches.current.add(threadId);
1639
1234
  try {
1640
1235
  const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
1641
- const state = await backendApiRef.current.fetchState(
1236
+ const state = await aomiClientRef.current.fetchState(
1642
1237
  backendThreadId,
1643
1238
  userState
1644
1239
  );
@@ -1670,7 +1265,7 @@ function useRuntimeOrchestrator(backendApi, options) {
1670
1265
  isRunning,
1671
1266
  setIsRunning,
1672
1267
  ensureInitialState,
1673
- backendApiRef
1268
+ aomiClientRef
1674
1269
  };
1675
1270
  }
1676
1271
 
@@ -1701,7 +1296,7 @@ function buildThreadLists(threadMetadata) {
1701
1296
  return { regularThreads, archivedThreads };
1702
1297
  }
1703
1298
  function buildThreadListAdapter({
1704
- backendApiRef,
1299
+ aomiClientRef,
1705
1300
  threadContext,
1706
1301
  setIsRunning
1707
1302
  }) {
@@ -1729,6 +1324,7 @@ function buildThreadListAdapter({
1729
1324
  },
1730
1325
  onSwitchToThread: (threadId) => {
1731
1326
  threadContext.setCurrentThreadId(threadId);
1327
+ threadContext.bumpThreadViewKey();
1732
1328
  },
1733
1329
  onRename: async (threadId, newTitle) => {
1734
1330
  var _a, _b;
@@ -1738,7 +1334,7 @@ function buildThreadListAdapter({
1738
1334
  title: normalizedTitle
1739
1335
  });
1740
1336
  try {
1741
- await backendApiRef.current.renameThread(threadId, newTitle);
1337
+ await aomiClientRef.current.renameThread(threadId, newTitle);
1742
1338
  } catch (error) {
1743
1339
  console.error("Failed to rename thread:", error);
1744
1340
  threadContext.updateThreadMetadata(threadId, {
@@ -1749,7 +1345,7 @@ function buildThreadListAdapter({
1749
1345
  onArchive: async (threadId) => {
1750
1346
  threadContext.updateThreadMetadata(threadId, { status: "archived" });
1751
1347
  try {
1752
- await backendApiRef.current.archiveThread(threadId);
1348
+ await aomiClientRef.current.archiveThread(threadId);
1753
1349
  } catch (error) {
1754
1350
  console.error("Failed to archive thread:", error);
1755
1351
  threadContext.updateThreadMetadata(threadId, { status: "regular" });
@@ -1758,7 +1354,7 @@ function buildThreadListAdapter({
1758
1354
  onUnarchive: async (threadId) => {
1759
1355
  threadContext.updateThreadMetadata(threadId, { status: "regular" });
1760
1356
  try {
1761
- await backendApiRef.current.unarchiveThread(threadId);
1357
+ await aomiClientRef.current.unarchiveThread(threadId);
1762
1358
  } catch (error) {
1763
1359
  console.error("Failed to unarchive thread:", error);
1764
1360
  threadContext.updateThreadMetadata(threadId, { status: "archived" });
@@ -1766,7 +1362,7 @@ function buildThreadListAdapter({
1766
1362
  },
1767
1363
  onDelete: async (threadId) => {
1768
1364
  try {
1769
- await backendApiRef.current.deleteThread(threadId);
1365
+ await aomiClientRef.current.deleteThread(threadId);
1770
1366
  threadContext.setThreadMetadata((prev) => {
1771
1367
  const next = new Map(prev);
1772
1368
  next.delete(threadId);
@@ -1821,6 +1417,10 @@ function useAomiRuntime() {
1821
1417
 
1822
1418
  // packages/react/src/handlers/wallet-handler.ts
1823
1419
  import { useCallback as useCallback6, useEffect as useEffect3, useRef as useRef6, useState as useState6 } from "react";
1420
+ import {
1421
+ normalizeEip712Payload,
1422
+ normalizeTxPayload
1423
+ } from "@aomi-labs/client";
1824
1424
 
1825
1425
  // packages/react/src/state/wallet-buffer.ts
1826
1426
  function createWalletBuffer() {
@@ -1867,7 +1467,11 @@ function useWalletHandler({
1867
1467
  const unsubscribe = subscribe2(
1868
1468
  "wallet_tx_request",
1869
1469
  (event) => {
1870
- const payload = event.payload;
1470
+ const payload = normalizeTxPayload(event.payload);
1471
+ if (!payload) {
1472
+ console.warn("[aomi][wallet] Ignoring tx request with invalid payload", event.payload);
1473
+ return;
1474
+ }
1871
1475
  enqueue(bufferRef.current, "transaction", payload);
1872
1476
  syncState();
1873
1477
  }
@@ -1879,7 +1483,7 @@ function useWalletHandler({
1879
1483
  "wallet_eip712_request",
1880
1484
  (event) => {
1881
1485
  var _a;
1882
- const payload = (_a = event.payload) != null ? _a : {};
1486
+ const payload = normalizeEip712Payload((_a = event.payload) != null ? _a : {});
1883
1487
  enqueue(bufferRef.current, "eip712_sign", payload);
1884
1488
  syncState();
1885
1489
  }
@@ -1969,14 +1573,14 @@ function useWalletHandler({
1969
1573
  import { jsx as jsx6 } from "react/jsx-runtime";
1970
1574
  function AomiRuntimeCore({
1971
1575
  children,
1972
- backendApi
1576
+ aomiClient
1973
1577
  }) {
1974
1578
  const threadContext = useThreadContext();
1975
1579
  const eventContext = useEventContext();
1976
1580
  const notificationContext = useNotification();
1977
1581
  const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
1978
1582
  const { user, onUserStateChange, getUserState } = useUser();
1979
- const { getControlState, getCurrentThreadControl } = useControl();
1583
+ const { getControlState, getCurrentThreadApp } = useControl();
1980
1584
  const {
1981
1585
  backendStateRef,
1982
1586
  polling,
@@ -1984,15 +1588,12 @@ function AomiRuntimeCore({
1984
1588
  isRunning,
1985
1589
  setIsRunning,
1986
1590
  ensureInitialState,
1987
- backendApiRef
1988
- } = useRuntimeOrchestrator(backendApi, {
1591
+ aomiClientRef
1592
+ } = useRuntimeOrchestrator(aomiClient, {
1989
1593
  onSyncEvents: dispatchSystemEvents,
1990
1594
  getPublicKey: () => getUserState().address,
1991
1595
  getUserState,
1992
- getNamespace: () => {
1993
- var _a, _b;
1994
- return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
1995
- },
1596
+ getApp: getCurrentThreadApp,
1996
1597
  getApiKey: () => getControlState().apiKey
1997
1598
  });
1998
1599
  useEffect4(() => {
@@ -2007,10 +1608,10 @@ function AomiRuntimeCore({
2007
1608
  ensName: newUser.ensName
2008
1609
  }
2009
1610
  });
2010
- await backendApiRef.current.postSystemMessage(sessionId, message);
1611
+ await aomiClientRef.current.sendSystemMessage(sessionId, message);
2011
1612
  });
2012
1613
  return unsubscribe;
2013
- }, [onUserStateChange, backendApiRef, threadContext.currentThreadId]);
1614
+ }, [onUserStateChange, aomiClientRef, threadContext.currentThreadId]);
2014
1615
  const threadContextRef = useRef7(threadContext);
2015
1616
  threadContextRef.current = threadContext;
2016
1617
  const currentThreadIdRef = useRef7(threadContext.currentThreadId);
@@ -2058,21 +1659,13 @@ function AomiRuntimeCore({
2058
1659
  const currentMessages = threadContext.getThreadMessages(
2059
1660
  threadContext.currentThreadId
2060
1661
  );
2061
- const resolvedSessionId = useMemo2(
2062
- () => resolveThreadId(backendStateRef.current, threadContext.currentThreadId),
2063
- [
2064
- backendStateRef,
2065
- threadContext.currentThreadId,
2066
- threadContext.allThreadsMetadata
2067
- ]
2068
- );
2069
1662
  useEffect4(() => {
2070
1663
  const userAddress = user.address;
2071
1664
  if (!userAddress) return;
2072
1665
  const fetchThreadList = async () => {
2073
1666
  var _a, _b, _c;
2074
1667
  try {
2075
- const threadList = await backendApiRef.current.fetchThreads(userAddress);
1668
+ const threadList = await aomiClientRef.current.listThreads(userAddress);
2076
1669
  const currentContext = threadContextRef.current;
2077
1670
  const newMetadata = new Map(currentContext.allThreadsMetadata);
2078
1671
  let maxChatNum = currentContext.threadCnt;
@@ -2104,25 +1697,22 @@ function AomiRuntimeCore({
2104
1697
  }
2105
1698
  };
2106
1699
  void fetchThreadList();
2107
- }, [user.address, backendApiRef]);
1700
+ }, [user.address, aomiClientRef]);
2108
1701
  const threadListAdapter = useMemo2(
2109
1702
  () => buildThreadListAdapter({
2110
1703
  backendStateRef,
2111
- backendApiRef,
1704
+ aomiClientRef,
2112
1705
  threadContext,
2113
1706
  currentThreadIdRef,
2114
1707
  polling,
2115
1708
  userAddress: user.address,
2116
1709
  setIsRunning,
2117
- getNamespace: () => {
2118
- var _a, _b;
2119
- return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
2120
- },
1710
+ getApp: getCurrentThreadApp,
2121
1711
  getApiKey: () => getControlState().apiKey,
2122
1712
  getUserState
2123
1713
  }),
2124
1714
  [
2125
- backendApiRef,
1715
+ aomiClientRef,
2126
1716
  polling,
2127
1717
  user.address,
2128
1718
  backendStateRef,
@@ -2131,63 +1721,44 @@ function AomiRuntimeCore({
2131
1721
  threadContext.currentThreadId,
2132
1722
  threadContext.allThreadsMetadata,
2133
1723
  getControlState,
1724
+ getCurrentThreadApp,
2134
1725
  getUserState
2135
1726
  ]
2136
1727
  );
2137
1728
  useEffect4(() => {
2138
1729
  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
- }
1730
+ const unsubscribe = eventContext.subscribe("title_changed", (event) => {
1731
+ const sessionId = event.sessionId;
1732
+ const payload = event.payload;
1733
+ const newTitle = payload == null ? void 0 : payload.new_title;
1734
+ if (typeof newTitle !== "string") return;
1735
+ const targetThreadId = resolveThreadId(backendState, sessionId);
1736
+ const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
1737
+ if (process.env.NODE_ENV !== "production") {
1738
+ console.debug("[aomi][sse] title_changed", {
1739
+ sessionId,
1740
+ newTitle,
1741
+ normalizedTitle,
1742
+ currentThreadId: threadContextRef.current.currentThreadId,
1743
+ targetThreadId
1744
+ });
2180
1745
  }
2181
- );
2182
- return () => {
2183
- unsubscribe == null ? void 0 : unsubscribe();
2184
- };
2185
- }, [
2186
- backendApiRef,
2187
- backendStateRef,
2188
- threadContext.currentThreadId,
2189
- resolvedSessionId
2190
- ]);
1746
+ threadContextRef.current.setThreadMetadata((prev) => {
1747
+ var _a, _b;
1748
+ const next = new Map(prev);
1749
+ const existing = next.get(targetThreadId);
1750
+ const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
1751
+ next.set(targetThreadId, {
1752
+ title: normalizedTitle,
1753
+ status: nextStatus,
1754
+ lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
1755
+ control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
1756
+ });
1757
+ return next;
1758
+ });
1759
+ });
1760
+ return unsubscribe;
1761
+ }, [eventContext, backendStateRef]);
2191
1762
  useEffect4(() => {
2192
1763
  const showToolNotification = (eventType) => (event) => {
2193
1764
  const payload = event.payload;
@@ -2356,12 +1927,12 @@ function AomiRuntimeProvider({
2356
1927
  children,
2357
1928
  backendUrl = "http://localhost:8080"
2358
1929
  }) {
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 }) }) }) });
1930
+ const aomiClient = useMemo3(() => new AomiClient({ baseUrl: backendUrl }), [backendUrl]);
1931
+ return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, { aomiClient, children }) }) }) });
2361
1932
  }
2362
1933
  function AomiRuntimeInner({
2363
1934
  children,
2364
- backendApi
1935
+ aomiClient
2365
1936
  }) {
2366
1937
  var _a;
2367
1938
  const threadContext = useThreadContext();
@@ -2369,7 +1940,7 @@ function AomiRuntimeInner({
2369
1940
  return /* @__PURE__ */ jsx7(
2370
1941
  ControlContextProvider,
2371
1942
  {
2372
- backendApi,
1943
+ aomiClient,
2373
1944
  sessionId: threadContext.currentThreadId,
2374
1945
  publicKey: (_a = user.address) != null ? _a : void 0,
2375
1946
  getThreadMetadata: threadContext.getThreadMetadata,
@@ -2377,9 +1948,9 @@ function AomiRuntimeInner({
2377
1948
  children: /* @__PURE__ */ jsx7(
2378
1949
  EventContextProvider,
2379
1950
  {
2380
- backendApi,
1951
+ aomiClient,
2381
1952
  sessionId: threadContext.currentThreadId,
2382
- children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { backendApi, children })
1953
+ children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { aomiClient, children })
2383
1954
  }
2384
1955
  )
2385
1956
  }
@@ -2428,8 +1999,8 @@ function useNotificationHandler({
2428
1999
  };
2429
2000
  }
2430
2001
  export {
2002
+ AomiClient2 as AomiClient,
2431
2003
  AomiRuntimeProvider,
2432
- BackendApi,
2433
2004
  ControlContextProvider,
2434
2005
  EventContextProvider,
2435
2006
  NotificationContextProvider,
@@ -2441,6 +2012,7 @@ export {
2441
2012
  getChainInfo,
2442
2013
  getNetworkName,
2443
2014
  initThreadControl,
2015
+ toViemSignTypedDataArgs,
2444
2016
  useAomiRuntime,
2445
2017
  useControl,
2446
2018
  useCurrentThreadMessages,