@aomi-labs/react 0.3.5 → 0.3.7
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.cjs +426 -619
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -57
- package/dist/index.d.ts +58 -57
- package/dist/index.js +443 -646
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,19 @@ var __spreadValues = (a, b) => {
|
|
|
20
20
|
return a;
|
|
21
21
|
};
|
|
22
22
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __restKey = (key) => typeof key === "symbol" ? key : key + "";
|
|
24
|
+
var __objRest = (source, exclude) => {
|
|
25
|
+
var target = {};
|
|
26
|
+
for (var prop in source)
|
|
27
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
if (source != null && __getOwnPropSymbols)
|
|
30
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
+
target[prop] = source[prop];
|
|
33
|
+
}
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
23
36
|
var __export = (target, all) => {
|
|
24
37
|
for (var name in all)
|
|
25
38
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -37,7 +50,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
37
50
|
// packages/react/src/index.ts
|
|
38
51
|
var index_exports = {};
|
|
39
52
|
__export(index_exports, {
|
|
40
|
-
AomiClient: () =>
|
|
53
|
+
AomiClient: () => import_client3.AomiClient,
|
|
41
54
|
AomiRuntimeProvider: () => AomiRuntimeProvider,
|
|
42
55
|
ControlContextProvider: () => ControlContextProvider,
|
|
43
56
|
EventContextProvider: () => EventContextProvider,
|
|
@@ -50,7 +63,7 @@ __export(index_exports, {
|
|
|
50
63
|
getChainInfo: () => getChainInfo,
|
|
51
64
|
getNetworkName: () => getNetworkName,
|
|
52
65
|
initThreadControl: () => initThreadControl,
|
|
53
|
-
toViemSignTypedDataArgs: () =>
|
|
66
|
+
toViemSignTypedDataArgs: () => import_client4.toViemSignTypedDataArgs,
|
|
54
67
|
useAomiRuntime: () => useAomiRuntime,
|
|
55
68
|
useControl: () => useControl,
|
|
56
69
|
useCurrentThreadMessages: () => useCurrentThreadMessages,
|
|
@@ -63,12 +76,12 @@ __export(index_exports, {
|
|
|
63
76
|
useWalletHandler: () => useWalletHandler
|
|
64
77
|
});
|
|
65
78
|
module.exports = __toCommonJS(index_exports);
|
|
79
|
+
var import_client3 = require("@aomi-labs/client");
|
|
66
80
|
var import_client4 = require("@aomi-labs/client");
|
|
67
|
-
var import_client5 = require("@aomi-labs/client");
|
|
68
81
|
|
|
69
82
|
// packages/react/src/runtime/aomi-runtime.tsx
|
|
70
83
|
var import_react11 = require("react");
|
|
71
|
-
var
|
|
84
|
+
var import_client2 = require("@aomi-labs/client");
|
|
72
85
|
|
|
73
86
|
// packages/react/src/contexts/control-context.tsx
|
|
74
87
|
var import_react = require("react");
|
|
@@ -247,6 +260,25 @@ var ThreadStore = class {
|
|
|
247
260
|
// packages/react/src/contexts/control-context.tsx
|
|
248
261
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
249
262
|
var API_KEY_STORAGE_KEY = "aomi_api_key";
|
|
263
|
+
var CLIENT_ID_STORAGE_KEY = "aomi_client_id";
|
|
264
|
+
var PROVIDER_KEYS_STORAGE_KEY = "aomi_provider_keys";
|
|
265
|
+
var PROVIDER_KEY_SECRET_PREFIX = "PROVIDER_KEY:";
|
|
266
|
+
function getOrCreateClientId() {
|
|
267
|
+
var _a, _b, _c, _d, _e;
|
|
268
|
+
try {
|
|
269
|
+
const storedClientId = (_a = globalThis.localStorage) == null ? void 0 : _a.getItem(CLIENT_ID_STORAGE_KEY);
|
|
270
|
+
if (storedClientId && storedClientId.trim().length > 0) {
|
|
271
|
+
return storedClientId;
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
}
|
|
275
|
+
const clientId = (_d = (_c = (_b = globalThis.crypto) == null ? void 0 : _b.randomUUID) == null ? void 0 : _c.call(_b)) != null ? _d : `client-${Date.now()}`;
|
|
276
|
+
try {
|
|
277
|
+
(_e = globalThis.localStorage) == null ? void 0 : _e.setItem(CLIENT_ID_STORAGE_KEY, clientId);
|
|
278
|
+
} catch (e) {
|
|
279
|
+
}
|
|
280
|
+
return clientId;
|
|
281
|
+
}
|
|
250
282
|
function getDefaultApp(apps) {
|
|
251
283
|
var _a;
|
|
252
284
|
return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
|
|
@@ -276,11 +308,12 @@ function ControlContextProvider({
|
|
|
276
308
|
var _a, _b;
|
|
277
309
|
const [state, setStateInternal] = (0, import_react.useState)(() => ({
|
|
278
310
|
apiKey: null,
|
|
279
|
-
clientId:
|
|
311
|
+
clientId: getOrCreateClientId(),
|
|
280
312
|
availableModels: [],
|
|
281
313
|
authorizedApps: [],
|
|
282
314
|
defaultModel: null,
|
|
283
|
-
defaultApp: null
|
|
315
|
+
defaultApp: null,
|
|
316
|
+
providerKeys: {}
|
|
284
317
|
}));
|
|
285
318
|
const stateRef = (0, import_react.useRef)(state);
|
|
286
319
|
stateRef.current = state;
|
|
@@ -298,10 +331,14 @@ function ControlContextProvider({
|
|
|
298
331
|
const currentThreadMetadata = getThreadMetadata(sessionId);
|
|
299
332
|
const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
|
|
300
333
|
(0, import_react.useEffect)(() => {
|
|
301
|
-
var _a2
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
334
|
+
var _a2;
|
|
335
|
+
try {
|
|
336
|
+
if (state.clientId) {
|
|
337
|
+
(_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(CLIENT_ID_STORAGE_KEY, state.clientId);
|
|
338
|
+
}
|
|
339
|
+
} catch (e) {
|
|
340
|
+
}
|
|
341
|
+
}, [state.clientId]);
|
|
305
342
|
(0, import_react.useEffect)(() => {
|
|
306
343
|
var _a2, _b2;
|
|
307
344
|
try {
|
|
@@ -312,6 +349,17 @@ function ControlContextProvider({
|
|
|
312
349
|
} catch (e) {
|
|
313
350
|
}
|
|
314
351
|
}, []);
|
|
352
|
+
(0, import_react.useEffect)(() => {
|
|
353
|
+
var _a2;
|
|
354
|
+
try {
|
|
355
|
+
const raw = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(PROVIDER_KEYS_STORAGE_KEY);
|
|
356
|
+
if (raw) {
|
|
357
|
+
const parsed = JSON.parse(raw);
|
|
358
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { providerKeys: parsed }));
|
|
359
|
+
}
|
|
360
|
+
} catch (e) {
|
|
361
|
+
}
|
|
362
|
+
}, []);
|
|
315
363
|
(0, import_react.useEffect)(() => {
|
|
316
364
|
var _a2, _b2;
|
|
317
365
|
try {
|
|
@@ -323,6 +371,33 @@ function ControlContextProvider({
|
|
|
323
371
|
} catch (e) {
|
|
324
372
|
}
|
|
325
373
|
}, [state.apiKey]);
|
|
374
|
+
(0, import_react.useEffect)(() => {
|
|
375
|
+
var _a2, _b2;
|
|
376
|
+
try {
|
|
377
|
+
const keys = state.providerKeys;
|
|
378
|
+
if (Object.keys(keys).length > 0) {
|
|
379
|
+
(_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(
|
|
380
|
+
PROVIDER_KEYS_STORAGE_KEY,
|
|
381
|
+
JSON.stringify(keys)
|
|
382
|
+
);
|
|
383
|
+
} else {
|
|
384
|
+
(_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(PROVIDER_KEYS_STORAGE_KEY);
|
|
385
|
+
}
|
|
386
|
+
} catch (e) {
|
|
387
|
+
}
|
|
388
|
+
}, [state.providerKeys]);
|
|
389
|
+
(0, import_react.useEffect)(() => {
|
|
390
|
+
if (!state.clientId) return;
|
|
391
|
+
const keys = stateRef.current.providerKeys;
|
|
392
|
+
if (Object.keys(keys).length === 0) return;
|
|
393
|
+
const secrets = {};
|
|
394
|
+
for (const [provider, entry] of Object.entries(keys)) {
|
|
395
|
+
secrets[`${PROVIDER_KEY_SECRET_PREFIX}${provider}`] = entry.apiKey;
|
|
396
|
+
}
|
|
397
|
+
void aomiClientRef.current.ingestSecrets(state.clientId, secrets).catch((err) => {
|
|
398
|
+
console.error("Failed to auto-ingest provider keys:", err);
|
|
399
|
+
});
|
|
400
|
+
}, [state.clientId, state.providerKeys]);
|
|
326
401
|
(0, import_react.useEffect)(() => {
|
|
327
402
|
const fetchApps = async () => {
|
|
328
403
|
var _a2;
|
|
@@ -393,6 +468,65 @@ function ControlContextProvider({
|
|
|
393
468
|
if (!clientId) return;
|
|
394
469
|
await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(_a2, clientId));
|
|
395
470
|
}, []);
|
|
471
|
+
const setProviderKey = (0, import_react.useCallback)(
|
|
472
|
+
async (provider, apiKey, label) => {
|
|
473
|
+
const trimmed = apiKey.trim();
|
|
474
|
+
if (!trimmed) return;
|
|
475
|
+
const entry = {
|
|
476
|
+
apiKey: trimmed,
|
|
477
|
+
keyPrefix: trimmed.slice(0, 7),
|
|
478
|
+
label
|
|
479
|
+
};
|
|
480
|
+
setStateInternal((prev) => {
|
|
481
|
+
const next = __spreadProps(__spreadValues({}, prev), {
|
|
482
|
+
providerKeys: __spreadProps(__spreadValues({}, prev.providerKeys), { [provider]: entry })
|
|
483
|
+
});
|
|
484
|
+
callbacks.current.forEach((cb) => cb(next));
|
|
485
|
+
return next;
|
|
486
|
+
});
|
|
487
|
+
const clientId = stateRef.current.clientId;
|
|
488
|
+
if (clientId) {
|
|
489
|
+
try {
|
|
490
|
+
await aomiClientRef.current.ingestSecrets(clientId, {
|
|
491
|
+
[`${PROVIDER_KEY_SECRET_PREFIX}${provider}`]: trimmed
|
|
492
|
+
});
|
|
493
|
+
} catch (err) {
|
|
494
|
+
console.error("Failed to ingest provider key:", err);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
[]
|
|
499
|
+
);
|
|
500
|
+
const removeProviderKey = (0, import_react.useCallback)(
|
|
501
|
+
async (provider) => {
|
|
502
|
+
const clientId = stateRef.current.clientId;
|
|
503
|
+
if (clientId) {
|
|
504
|
+
await aomiClientRef.current.deleteSecret(
|
|
505
|
+
clientId,
|
|
506
|
+
`${PROVIDER_KEY_SECRET_PREFIX}${provider}`
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
setStateInternal((prev) => {
|
|
510
|
+
const _a2 = prev.providerKeys, { [provider]: _ } = _a2, rest = __objRest(_a2, [__restKey(provider)]);
|
|
511
|
+
const next = __spreadProps(__spreadValues({}, prev), { providerKeys: rest });
|
|
512
|
+
callbacks.current.forEach((cb) => cb(next));
|
|
513
|
+
return next;
|
|
514
|
+
});
|
|
515
|
+
},
|
|
516
|
+
[]
|
|
517
|
+
);
|
|
518
|
+
const getProviderKeys = (0, import_react.useCallback)(
|
|
519
|
+
() => stateRef.current.providerKeys,
|
|
520
|
+
[]
|
|
521
|
+
);
|
|
522
|
+
const hasProviderKey = (0, import_react.useCallback)(
|
|
523
|
+
(provider) => {
|
|
524
|
+
const keys = stateRef.current.providerKeys;
|
|
525
|
+
if (provider) return provider in keys;
|
|
526
|
+
return Object.keys(keys).length > 0;
|
|
527
|
+
},
|
|
528
|
+
[]
|
|
529
|
+
);
|
|
396
530
|
const getAvailableModels = (0, import_react.useCallback)(async () => {
|
|
397
531
|
try {
|
|
398
532
|
const models = await aomiClientRef.current.getModels(
|
|
@@ -451,7 +585,7 @@ function ControlContextProvider({
|
|
|
451
585
|
)) != null ? _c : "default";
|
|
452
586
|
}, []);
|
|
453
587
|
const onModelSelect = (0, import_react.useCallback)(async (model) => {
|
|
454
|
-
var _a2, _b2, _c, _d;
|
|
588
|
+
var _a2, _b2, _c, _d, _e;
|
|
455
589
|
const threadId = sessionIdRef.current;
|
|
456
590
|
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
457
591
|
const isProcessing2 = currentControl.isProcessing;
|
|
@@ -492,7 +626,11 @@ function ControlContextProvider({
|
|
|
492
626
|
const result = await aomiClientRef.current.setModel(
|
|
493
627
|
threadId,
|
|
494
628
|
model,
|
|
495
|
-
{
|
|
629
|
+
{
|
|
630
|
+
app,
|
|
631
|
+
apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0,
|
|
632
|
+
clientId: (_e = stateRef.current.clientId) != null ? _e : void 0
|
|
633
|
+
}
|
|
496
634
|
);
|
|
497
635
|
console.log("[control-context] onModelSelect backend result", result);
|
|
498
636
|
} catch (err) {
|
|
@@ -575,6 +713,10 @@ function ControlContextProvider({
|
|
|
575
713
|
setApiKey,
|
|
576
714
|
ingestSecrets,
|
|
577
715
|
clearSecrets,
|
|
716
|
+
setProviderKey,
|
|
717
|
+
removeProviderKey,
|
|
718
|
+
getProviderKeys,
|
|
719
|
+
hasProviderKey,
|
|
578
720
|
getAvailableModels,
|
|
579
721
|
getAuthorizedApps,
|
|
580
722
|
getCurrentThreadControl,
|
|
@@ -594,53 +736,6 @@ function ControlContextProvider({
|
|
|
594
736
|
|
|
595
737
|
// packages/react/src/contexts/event-context.tsx
|
|
596
738
|
var import_react2 = require("react");
|
|
597
|
-
var import_client = require("@aomi-labs/client");
|
|
598
|
-
|
|
599
|
-
// packages/react/src/state/event-buffer.ts
|
|
600
|
-
function createEventBuffer() {
|
|
601
|
-
return {
|
|
602
|
-
inboundQueue: [],
|
|
603
|
-
outboundQueue: [],
|
|
604
|
-
sseStatus: "disconnected",
|
|
605
|
-
lastEventId: null,
|
|
606
|
-
subscribers: /* @__PURE__ */ new Map()
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
function enqueueInbound(state, event) {
|
|
610
|
-
state.inboundQueue.push(__spreadProps(__spreadValues({}, event), {
|
|
611
|
-
status: "pending",
|
|
612
|
-
timestamp: Date.now()
|
|
613
|
-
}));
|
|
614
|
-
}
|
|
615
|
-
function subscribe(state, type, callback) {
|
|
616
|
-
if (!state.subscribers.has(type)) {
|
|
617
|
-
state.subscribers.set(type, /* @__PURE__ */ new Set());
|
|
618
|
-
}
|
|
619
|
-
state.subscribers.get(type).add(callback);
|
|
620
|
-
return () => {
|
|
621
|
-
var _a;
|
|
622
|
-
(_a = state.subscribers.get(type)) == null ? void 0 : _a.delete(callback);
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
function dispatch(state, event) {
|
|
626
|
-
const typeSubscribers = state.subscribers.get(event.type);
|
|
627
|
-
if (typeSubscribers) {
|
|
628
|
-
for (const callback of typeSubscribers) {
|
|
629
|
-
callback(event);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
const allSubscribers = state.subscribers.get("*");
|
|
633
|
-
if (allSubscribers) {
|
|
634
|
-
for (const callback of allSubscribers) {
|
|
635
|
-
callback(event);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
function setSSEStatus(state, status) {
|
|
640
|
-
state.sseStatus = status;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// packages/react/src/contexts/event-context.tsx
|
|
644
739
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
645
740
|
var EventContextState = (0, import_react2.createContext)(null);
|
|
646
741
|
function useEventContext() {
|
|
@@ -657,52 +752,32 @@ function EventContextProvider({
|
|
|
657
752
|
aomiClient,
|
|
658
753
|
sessionId
|
|
659
754
|
}) {
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
bufferRef.current = createEventBuffer();
|
|
663
|
-
}
|
|
664
|
-
const buffer = bufferRef.current;
|
|
665
|
-
const [sseStatus, setSseStatus] = (0, import_react2.useState)("disconnected");
|
|
666
|
-
(0, import_react2.useEffect)(() => {
|
|
667
|
-
setSSEStatus(buffer, "connecting");
|
|
668
|
-
setSseStatus("connecting");
|
|
669
|
-
const unsubscribe = aomiClient.subscribeSSE(
|
|
670
|
-
sessionId,
|
|
671
|
-
(event) => {
|
|
672
|
-
enqueueInbound(buffer, {
|
|
673
|
-
type: event.type,
|
|
674
|
-
sessionId: event.session_id,
|
|
675
|
-
payload: event
|
|
676
|
-
});
|
|
677
|
-
const inboundEvent = {
|
|
678
|
-
type: event.type,
|
|
679
|
-
sessionId: event.session_id,
|
|
680
|
-
payload: event,
|
|
681
|
-
status: "fetched",
|
|
682
|
-
timestamp: Date.now()
|
|
683
|
-
};
|
|
684
|
-
dispatch(buffer, inboundEvent);
|
|
685
|
-
},
|
|
686
|
-
(error) => {
|
|
687
|
-
console.error("SSE error:", error);
|
|
688
|
-
setSSEStatus(buffer, "disconnected");
|
|
689
|
-
setSseStatus("disconnected");
|
|
690
|
-
}
|
|
691
|
-
);
|
|
692
|
-
setSSEStatus(buffer, "connected");
|
|
693
|
-
setSseStatus("connected");
|
|
694
|
-
return () => {
|
|
695
|
-
unsubscribe();
|
|
696
|
-
setSSEStatus(buffer, "disconnected");
|
|
697
|
-
setSseStatus("disconnected");
|
|
698
|
-
};
|
|
699
|
-
}, [aomiClient, sessionId, buffer]);
|
|
700
|
-
const subscribeCallback = (0, import_react2.useCallback)(
|
|
755
|
+
const subscribersRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
756
|
+
const subscribe = (0, import_react2.useCallback)(
|
|
701
757
|
(type, callback) => {
|
|
702
|
-
|
|
758
|
+
const subs = subscribersRef.current;
|
|
759
|
+
if (!subs.has(type)) {
|
|
760
|
+
subs.set(type, /* @__PURE__ */ new Set());
|
|
761
|
+
}
|
|
762
|
+
subs.get(type).add(callback);
|
|
763
|
+
return () => {
|
|
764
|
+
var _a;
|
|
765
|
+
(_a = subs.get(type)) == null ? void 0 : _a.delete(callback);
|
|
766
|
+
};
|
|
703
767
|
},
|
|
704
|
-
[
|
|
768
|
+
[]
|
|
705
769
|
);
|
|
770
|
+
const dispatchEvent = (0, import_react2.useCallback)((event) => {
|
|
771
|
+
const subs = subscribersRef.current;
|
|
772
|
+
const typeSubs = subs.get(event.type);
|
|
773
|
+
if (typeSubs) {
|
|
774
|
+
for (const cb of typeSubs) cb(event);
|
|
775
|
+
}
|
|
776
|
+
const wildcardSubs = subs.get("*");
|
|
777
|
+
if (wildcardSubs) {
|
|
778
|
+
for (const cb of wildcardSubs) cb(event);
|
|
779
|
+
}
|
|
780
|
+
}, []);
|
|
706
781
|
const sendOutbound = (0, import_react2.useCallback)(
|
|
707
782
|
async (event) => {
|
|
708
783
|
try {
|
|
@@ -717,50 +792,14 @@ function EventContextProvider({
|
|
|
717
792
|
},
|
|
718
793
|
[aomiClient]
|
|
719
794
|
);
|
|
720
|
-
const dispatchSystemEvents = (0, import_react2.useCallback)(
|
|
721
|
-
(sessionId2, events) => {
|
|
722
|
-
var _a;
|
|
723
|
-
for (const event of events) {
|
|
724
|
-
let eventType;
|
|
725
|
-
let payload;
|
|
726
|
-
if ((0, import_client.isInlineCall)(event)) {
|
|
727
|
-
eventType = event.InlineCall.type;
|
|
728
|
-
payload = (_a = event.InlineCall.payload) != null ? _a : event.InlineCall;
|
|
729
|
-
} else if ((0, import_client.isSystemNotice)(event)) {
|
|
730
|
-
eventType = "system_notice";
|
|
731
|
-
payload = { message: event.SystemNotice };
|
|
732
|
-
} else if ((0, import_client.isSystemError)(event)) {
|
|
733
|
-
eventType = "system_error";
|
|
734
|
-
payload = { message: event.SystemError };
|
|
735
|
-
} else if ((0, import_client.isAsyncCallback)(event)) {
|
|
736
|
-
eventType = "async_callback";
|
|
737
|
-
payload = event.AsyncCallback;
|
|
738
|
-
} else {
|
|
739
|
-
console.warn("Unknown system event type:", event);
|
|
740
|
-
continue;
|
|
741
|
-
}
|
|
742
|
-
const inboundEvent = {
|
|
743
|
-
type: eventType,
|
|
744
|
-
sessionId: sessionId2,
|
|
745
|
-
payload,
|
|
746
|
-
status: "fetched",
|
|
747
|
-
timestamp: Date.now()
|
|
748
|
-
};
|
|
749
|
-
enqueueInbound(buffer, {
|
|
750
|
-
type: eventType,
|
|
751
|
-
sessionId: sessionId2,
|
|
752
|
-
payload
|
|
753
|
-
});
|
|
754
|
-
dispatch(buffer, inboundEvent);
|
|
755
|
-
}
|
|
756
|
-
},
|
|
757
|
-
[buffer]
|
|
758
|
-
);
|
|
759
795
|
const contextValue = {
|
|
760
|
-
subscribe
|
|
796
|
+
subscribe,
|
|
797
|
+
dispatch: dispatchEvent,
|
|
761
798
|
sendOutboundSystem: sendOutbound,
|
|
762
|
-
|
|
763
|
-
|
|
799
|
+
// SSE is managed by ClientSession now — status is always "connected"
|
|
800
|
+
// when sessions are active. Individual session status can be queried
|
|
801
|
+
// from the session manager if needed.
|
|
802
|
+
sseStatus: "connected"
|
|
764
803
|
};
|
|
765
804
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EventContextState.Provider, { value: contextValue, children });
|
|
766
805
|
}
|
|
@@ -957,6 +996,40 @@ var import_react10 = require("@assistant-ui/react");
|
|
|
957
996
|
// packages/react/src/runtime/orchestrator.ts
|
|
958
997
|
var import_react6 = require("react");
|
|
959
998
|
|
|
999
|
+
// packages/react/src/runtime/session-manager.ts
|
|
1000
|
+
var import_client = require("@aomi-labs/client");
|
|
1001
|
+
var SessionManager = class {
|
|
1002
|
+
constructor(clientFactory) {
|
|
1003
|
+
this.clientFactory = clientFactory;
|
|
1004
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
1005
|
+
}
|
|
1006
|
+
getOrCreate(threadId, opts) {
|
|
1007
|
+
let session = this.sessions.get(threadId);
|
|
1008
|
+
if (session) return session;
|
|
1009
|
+
session = new import_client.Session(this.clientFactory(), __spreadProps(__spreadValues({}, opts), {
|
|
1010
|
+
sessionId: threadId
|
|
1011
|
+
}));
|
|
1012
|
+
this.sessions.set(threadId, session);
|
|
1013
|
+
return session;
|
|
1014
|
+
}
|
|
1015
|
+
get(threadId) {
|
|
1016
|
+
return this.sessions.get(threadId);
|
|
1017
|
+
}
|
|
1018
|
+
close(threadId) {
|
|
1019
|
+
const session = this.sessions.get(threadId);
|
|
1020
|
+
if (session) {
|
|
1021
|
+
session.close();
|
|
1022
|
+
this.sessions.delete(threadId);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
closeAll() {
|
|
1026
|
+
for (const [threadId, session] of this.sessions) {
|
|
1027
|
+
session.close();
|
|
1028
|
+
}
|
|
1029
|
+
this.sessions.clear();
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
|
|
960
1033
|
// packages/react/src/runtime/utils.ts
|
|
961
1034
|
var import_clsx = require("clsx");
|
|
962
1035
|
var import_tailwind_merge = require("tailwind-merge");
|
|
@@ -1059,194 +1132,6 @@ var SUPPORTED_CHAINS = [
|
|
|
1059
1132
|
];
|
|
1060
1133
|
var getChainInfo = (chainId) => chainId === void 0 ? void 0 : SUPPORTED_CHAINS.find((c) => c.id === chainId);
|
|
1061
1134
|
|
|
1062
|
-
// packages/react/src/state/backend-state.ts
|
|
1063
|
-
function createBackendState() {
|
|
1064
|
-
return {
|
|
1065
|
-
runningThreads: /* @__PURE__ */ new Set()
|
|
1066
|
-
};
|
|
1067
|
-
}
|
|
1068
|
-
function resolveThreadId(_state, threadId) {
|
|
1069
|
-
return threadId;
|
|
1070
|
-
}
|
|
1071
|
-
function setThreadRunning(state, threadId, running) {
|
|
1072
|
-
if (running) {
|
|
1073
|
-
state.runningThreads.add(threadId);
|
|
1074
|
-
} else {
|
|
1075
|
-
state.runningThreads.delete(threadId);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
function isThreadRunning(state, threadId) {
|
|
1079
|
-
return state.runningThreads.has(threadId);
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
// packages/react/src/runtime/message-controller.ts
|
|
1083
|
-
var MessageController = class {
|
|
1084
|
-
constructor(config) {
|
|
1085
|
-
this.config = config;
|
|
1086
|
-
}
|
|
1087
|
-
inbound(threadId, msgs) {
|
|
1088
|
-
if (!msgs) return;
|
|
1089
|
-
const threadMessages = [];
|
|
1090
|
-
for (const msg of msgs) {
|
|
1091
|
-
const threadMessage = toInboundMessage(msg);
|
|
1092
|
-
if (threadMessage) {
|
|
1093
|
-
threadMessages.push(threadMessage);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
this.getThreadContextApi().setThreadMessages(threadId, threadMessages);
|
|
1097
|
-
}
|
|
1098
|
-
async outbound(message, threadId) {
|
|
1099
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1100
|
-
const backendState = this.config.backendStateRef.current;
|
|
1101
|
-
const text = message.content.filter(
|
|
1102
|
-
(part) => part.type === "text"
|
|
1103
|
-
).map(
|
|
1104
|
-
(part) => part.text
|
|
1105
|
-
).join("\n");
|
|
1106
|
-
if (!text) return;
|
|
1107
|
-
const threadState = this.getThreadContextApi();
|
|
1108
|
-
const existingMessages = threadState.getThreadMessages(threadId);
|
|
1109
|
-
const userMessage = {
|
|
1110
|
-
role: "user",
|
|
1111
|
-
content: [{ type: "text", text }],
|
|
1112
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
1113
|
-
};
|
|
1114
|
-
threadState.setThreadMessages(threadId, [...existingMessages, userMessage]);
|
|
1115
|
-
threadState.updateThreadMetadata(threadId, {
|
|
1116
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1117
|
-
});
|
|
1118
|
-
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1119
|
-
const app = this.config.getApp();
|
|
1120
|
-
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1121
|
-
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1122
|
-
const clientId = (_g = (_f = this.config).getClientId) == null ? void 0 : _g.call(_f);
|
|
1123
|
-
const userState = (_i = (_h = this.config).getUserState) == null ? void 0 : _i.call(_h);
|
|
1124
|
-
try {
|
|
1125
|
-
this.markRunning(threadId, true);
|
|
1126
|
-
const response = await this.config.aomiClientRef.current.sendMessage(
|
|
1127
|
-
backendThreadId,
|
|
1128
|
-
text,
|
|
1129
|
-
{ app, publicKey, apiKey, userState, clientId }
|
|
1130
|
-
);
|
|
1131
|
-
if (response == null ? void 0 : response.messages) {
|
|
1132
|
-
this.inbound(threadId, response.messages);
|
|
1133
|
-
}
|
|
1134
|
-
if (((_j = response == null ? void 0 : response.system_events) == null ? void 0 : _j.length) && this.config.onSyncEvents) {
|
|
1135
|
-
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1136
|
-
}
|
|
1137
|
-
if (response == null ? void 0 : response.is_processing) {
|
|
1138
|
-
this.config.polling.start(threadId);
|
|
1139
|
-
} else if (!this.config.polling.isPolling(threadId)) {
|
|
1140
|
-
this.markRunning(threadId, false);
|
|
1141
|
-
}
|
|
1142
|
-
} catch (error) {
|
|
1143
|
-
console.error("Failed to send message:", error);
|
|
1144
|
-
this.markRunning(threadId, false);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
async cancel(threadId) {
|
|
1148
|
-
var _a;
|
|
1149
|
-
this.config.polling.stop(threadId);
|
|
1150
|
-
const backendState = this.config.backendStateRef.current;
|
|
1151
|
-
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1152
|
-
try {
|
|
1153
|
-
const response = await this.config.aomiClientRef.current.interrupt(backendThreadId);
|
|
1154
|
-
if (response == null ? void 0 : response.messages) {
|
|
1155
|
-
this.inbound(threadId, response.messages);
|
|
1156
|
-
}
|
|
1157
|
-
if (((_a = response == null ? void 0 : response.system_events) == null ? void 0 : _a.length) && this.config.onSyncEvents) {
|
|
1158
|
-
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1159
|
-
}
|
|
1160
|
-
this.markRunning(threadId, false);
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
console.error("Failed to cancel:", error);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
markRunning(threadId, running) {
|
|
1166
|
-
var _a, _b;
|
|
1167
|
-
setThreadRunning(this.config.backendStateRef.current, threadId, running);
|
|
1168
|
-
if (this.config.threadContextRef.current.currentThreadId === threadId) {
|
|
1169
|
-
(_b = (_a = this.config).setGlobalIsRunning) == null ? void 0 : _b.call(_a, running);
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
getThreadContextApi() {
|
|
1173
|
-
const { getThreadMessages, setThreadMessages, updateThreadMetadata } = this.config.threadContextRef.current;
|
|
1174
|
-
return { getThreadMessages, setThreadMessages, updateThreadMetadata };
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
1177
|
-
|
|
1178
|
-
// packages/react/src/runtime/polling-controller.ts
|
|
1179
|
-
var PollingController = class {
|
|
1180
|
-
constructor(config) {
|
|
1181
|
-
this.config = config;
|
|
1182
|
-
this.intervals = /* @__PURE__ */ new Map();
|
|
1183
|
-
var _a;
|
|
1184
|
-
this.intervalMs = (_a = config.intervalMs) != null ? _a : 500;
|
|
1185
|
-
}
|
|
1186
|
-
start(threadId) {
|
|
1187
|
-
var _a, _b;
|
|
1188
|
-
const backendState = this.config.backendStateRef.current;
|
|
1189
|
-
if (this.intervals.has(threadId)) return;
|
|
1190
|
-
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1191
|
-
setThreadRunning(backendState, threadId, true);
|
|
1192
|
-
const tick = async () => {
|
|
1193
|
-
var _a2, _b2, _c, _d;
|
|
1194
|
-
if (!this.intervals.has(threadId)) return;
|
|
1195
|
-
try {
|
|
1196
|
-
console.log(
|
|
1197
|
-
"[PollingController] Fetching state for threadId:",
|
|
1198
|
-
threadId
|
|
1199
|
-
);
|
|
1200
|
-
const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
|
|
1201
|
-
const clientId = (_d = (_c = this.config).getClientId) == null ? void 0 : _d.call(_c);
|
|
1202
|
-
const state = await this.config.aomiClientRef.current.fetchState(
|
|
1203
|
-
backendThreadId,
|
|
1204
|
-
userState,
|
|
1205
|
-
clientId
|
|
1206
|
-
);
|
|
1207
|
-
if (!this.intervals.has(threadId)) return;
|
|
1208
|
-
this.handleState(threadId, state);
|
|
1209
|
-
} catch (error) {
|
|
1210
|
-
console.error("Polling error:", error);
|
|
1211
|
-
this.stop(threadId);
|
|
1212
|
-
}
|
|
1213
|
-
};
|
|
1214
|
-
const intervalId = setInterval(tick, this.intervalMs);
|
|
1215
|
-
this.intervals.set(threadId, intervalId);
|
|
1216
|
-
(_b = (_a = this.config).onStart) == null ? void 0 : _b.call(_a, threadId);
|
|
1217
|
-
}
|
|
1218
|
-
stop(threadId) {
|
|
1219
|
-
var _a, _b;
|
|
1220
|
-
const intervalId = this.intervals.get(threadId);
|
|
1221
|
-
if (intervalId) {
|
|
1222
|
-
clearInterval(intervalId);
|
|
1223
|
-
this.intervals.delete(threadId);
|
|
1224
|
-
}
|
|
1225
|
-
setThreadRunning(this.config.backendStateRef.current, threadId, false);
|
|
1226
|
-
(_b = (_a = this.config).onStop) == null ? void 0 : _b.call(_a, threadId);
|
|
1227
|
-
}
|
|
1228
|
-
isPolling(threadId) {
|
|
1229
|
-
return this.intervals.has(threadId);
|
|
1230
|
-
}
|
|
1231
|
-
stopAll() {
|
|
1232
|
-
for (const threadId of this.intervals.keys()) {
|
|
1233
|
-
this.stop(threadId);
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
handleState(threadId, state) {
|
|
1237
|
-
var _a;
|
|
1238
|
-
if (((_a = state.system_events) == null ? void 0 : _a.length) && this.config.onSyncEvents) {
|
|
1239
|
-
const backendState = this.config.backendStateRef.current;
|
|
1240
|
-
const sessionId = resolveThreadId(backendState, threadId);
|
|
1241
|
-
this.config.onSyncEvents(sessionId, state.system_events);
|
|
1242
|
-
}
|
|
1243
|
-
this.config.applyMessages(threadId, state.messages);
|
|
1244
|
-
if (!state.is_processing) {
|
|
1245
|
-
this.stop(threadId);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
1249
|
-
|
|
1250
1135
|
// packages/react/src/runtime/orchestrator.ts
|
|
1251
1136
|
function useRuntimeOrchestrator(aomiClient, options) {
|
|
1252
1137
|
const threadContext = useThreadContext();
|
|
@@ -1254,90 +1139,160 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1254
1139
|
threadContextRef.current = threadContext;
|
|
1255
1140
|
const aomiClientRef = (0, import_react6.useRef)(aomiClient);
|
|
1256
1141
|
aomiClientRef.current = aomiClient;
|
|
1257
|
-
const backendStateRef = (0, import_react6.useRef)(createBackendState());
|
|
1258
1142
|
const [isRunning, setIsRunning] = (0, import_react6.useState)(false);
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1143
|
+
const sessionManagerRef = (0, import_react6.useRef)(null);
|
|
1144
|
+
if (!sessionManagerRef.current) {
|
|
1145
|
+
sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
|
|
1146
|
+
}
|
|
1261
1147
|
const pendingFetches = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1148
|
+
const listenerCleanups = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
1149
|
+
const getSession = (0, import_react6.useCallback)(
|
|
1150
|
+
(threadId) => {
|
|
1151
|
+
var _a, _b, _c, _d, _e;
|
|
1152
|
+
const manager = sessionManagerRef.current;
|
|
1153
|
+
const existing = manager.get(threadId);
|
|
1154
|
+
if (existing) return existing;
|
|
1155
|
+
const session = manager.getOrCreate(threadId, {
|
|
1156
|
+
app: options.getApp(),
|
|
1157
|
+
publicKey: (_a = options.getPublicKey) == null ? void 0 : _a.call(options),
|
|
1158
|
+
apiKey: (_c = (_b = options.getApiKey) == null ? void 0 : _b.call(options)) != null ? _c : void 0,
|
|
1159
|
+
clientId: (_d = options.getClientId) == null ? void 0 : _d.call(options),
|
|
1160
|
+
userState: (_e = options.getUserState) == null ? void 0 : _e.call(options)
|
|
1161
|
+
});
|
|
1162
|
+
const cleanups = [];
|
|
1163
|
+
cleanups.push(
|
|
1164
|
+
session.on("messages", (msgs) => {
|
|
1165
|
+
const threadMessages = [];
|
|
1166
|
+
for (const msg of msgs) {
|
|
1167
|
+
const converted = toInboundMessage(msg);
|
|
1168
|
+
if (converted) threadMessages.push(converted);
|
|
1169
|
+
}
|
|
1170
|
+
threadContextRef.current.setThreadMessages(threadId, threadMessages);
|
|
1171
|
+
})
|
|
1172
|
+
);
|
|
1173
|
+
cleanups.push(
|
|
1174
|
+
session.on("processing_start", () => {
|
|
1175
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1176
|
+
setIsRunning(true);
|
|
1177
|
+
}
|
|
1178
|
+
})
|
|
1179
|
+
);
|
|
1180
|
+
cleanups.push(
|
|
1181
|
+
session.on("processing_end", () => {
|
|
1182
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1183
|
+
setIsRunning(false);
|
|
1184
|
+
}
|
|
1185
|
+
})
|
|
1186
|
+
);
|
|
1187
|
+
cleanups.push(
|
|
1188
|
+
session.on("wallet_tx_request", (req) => {
|
|
1189
|
+
var _a2;
|
|
1190
|
+
return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
|
|
1191
|
+
})
|
|
1192
|
+
);
|
|
1193
|
+
cleanups.push(
|
|
1194
|
+
session.on("wallet_eip712_request", (req) => {
|
|
1195
|
+
var _a2;
|
|
1196
|
+
return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
|
|
1197
|
+
})
|
|
1198
|
+
);
|
|
1199
|
+
cleanups.push(
|
|
1200
|
+
session.on("title_changed", ({ title }) => {
|
|
1201
|
+
threadContextRef.current.updateThreadMetadata(threadId, { title });
|
|
1202
|
+
})
|
|
1203
|
+
);
|
|
1204
|
+
const forwardEvent = (type) => session.on(type, (payload) => {
|
|
1205
|
+
var _a2;
|
|
1206
|
+
(_a2 = options.onEvent) == null ? void 0 : _a2.call(options, { type, payload, sessionId: threadId });
|
|
1207
|
+
});
|
|
1208
|
+
cleanups.push(forwardEvent("tool_update"));
|
|
1209
|
+
cleanups.push(forwardEvent("tool_complete"));
|
|
1210
|
+
cleanups.push(forwardEvent("system_notice"));
|
|
1211
|
+
cleanups.push(forwardEvent("system_error"));
|
|
1212
|
+
cleanups.push(forwardEvent("async_callback"));
|
|
1213
|
+
listenerCleanups.current.set(threadId, () => {
|
|
1214
|
+
for (const cleanup of cleanups) cleanup();
|
|
1215
|
+
});
|
|
1216
|
+
return session;
|
|
1217
|
+
},
|
|
1218
|
+
// Stable deps — option getters are refs
|
|
1219
|
+
[]
|
|
1220
|
+
);
|
|
1221
|
+
const ensureInitialState = (0, import_react6.useCallback)(
|
|
1222
|
+
async (threadId) => {
|
|
1223
|
+
var _a;
|
|
1224
|
+
if (pendingFetches.current.has(threadId)) return;
|
|
1225
|
+
pendingFetches.current.add(threadId);
|
|
1226
|
+
try {
|
|
1227
|
+
const session = getSession(threadId);
|
|
1228
|
+
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1229
|
+
if (userState) session.resolveUserState(userState);
|
|
1230
|
+
await session.fetchCurrentState();
|
|
1274
1231
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1275
|
-
setIsRunning(
|
|
1232
|
+
setIsRunning(session.getIsProcessing());
|
|
1276
1233
|
}
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1234
|
+
} catch (error) {
|
|
1235
|
+
console.error("Failed to fetch initial state:", error);
|
|
1279
1236
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1280
1237
|
setIsRunning(false);
|
|
1281
1238
|
}
|
|
1239
|
+
} finally {
|
|
1240
|
+
pendingFetches.current.delete(threadId);
|
|
1282
1241
|
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
polling: pollingRef.current,
|
|
1291
|
-
setGlobalIsRunning: setIsRunning,
|
|
1292
|
-
getPublicKey: options.getPublicKey,
|
|
1293
|
-
getApp: options.getApp,
|
|
1294
|
-
getApiKey: options.getApiKey,
|
|
1295
|
-
getClientId: options.getClientId,
|
|
1296
|
-
getUserState: options.getUserState,
|
|
1297
|
-
onSyncEvents: options.onSyncEvents
|
|
1298
|
-
});
|
|
1299
|
-
}
|
|
1300
|
-
const ensureInitialState = (0, import_react6.useCallback)(async (threadId) => {
|
|
1301
|
-
var _a, _b, _c, _d, _e;
|
|
1302
|
-
if (pendingFetches.current.has(threadId)) return;
|
|
1303
|
-
const backendThreadId = resolveThreadId(backendStateRef.current, threadId);
|
|
1304
|
-
pendingFetches.current.add(threadId);
|
|
1305
|
-
try {
|
|
1242
|
+
},
|
|
1243
|
+
[getSession]
|
|
1244
|
+
);
|
|
1245
|
+
const sendMessage = (0, import_react6.useCallback)(
|
|
1246
|
+
async (text, threadId) => {
|
|
1247
|
+
var _a;
|
|
1248
|
+
const session = getSession(threadId);
|
|
1306
1249
|
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1307
|
-
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1250
|
+
if (userState) session.resolveUserState(userState);
|
|
1251
|
+
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1252
|
+
const userMessage = {
|
|
1253
|
+
role: "user",
|
|
1254
|
+
content: [{ type: "text", text }],
|
|
1255
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
1256
|
+
};
|
|
1257
|
+
threadContextRef.current.setThreadMessages(threadId, [
|
|
1258
|
+
...existingMessages,
|
|
1259
|
+
userMessage
|
|
1260
|
+
]);
|
|
1261
|
+
threadContextRef.current.updateThreadMetadata(threadId, {
|
|
1262
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1263
|
+
});
|
|
1264
|
+
await session.sendAsync(text);
|
|
1265
|
+
},
|
|
1266
|
+
[getSession]
|
|
1267
|
+
);
|
|
1268
|
+
const cancelGeneration = (0, import_react6.useCallback)(
|
|
1269
|
+
async (threadId) => {
|
|
1270
|
+
var _a;
|
|
1271
|
+
const session = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1272
|
+
if (session) {
|
|
1273
|
+
await session.interrupt();
|
|
1324
1274
|
}
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1275
|
+
},
|
|
1276
|
+
[]
|
|
1277
|
+
);
|
|
1278
|
+
(0, import_react6.useEffect)(() => {
|
|
1279
|
+
return () => {
|
|
1280
|
+
var _a;
|
|
1281
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1282
|
+
for (const cleanup of listenerCleanups.current.values()) {
|
|
1283
|
+
cleanup();
|
|
1329
1284
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1285
|
+
listenerCleanups.current.clear();
|
|
1286
|
+
};
|
|
1333
1287
|
}, []);
|
|
1334
1288
|
return {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
messageController: messageControllerRef.current,
|
|
1289
|
+
sessionManager: sessionManagerRef.current,
|
|
1290
|
+
getSession,
|
|
1338
1291
|
isRunning,
|
|
1339
1292
|
setIsRunning,
|
|
1340
1293
|
ensureInitialState,
|
|
1294
|
+
sendMessage,
|
|
1295
|
+
cancelGeneration,
|
|
1341
1296
|
aomiClientRef
|
|
1342
1297
|
};
|
|
1343
1298
|
}
|
|
@@ -1490,150 +1445,48 @@ function useAomiRuntime() {
|
|
|
1490
1445
|
|
|
1491
1446
|
// packages/react/src/handlers/wallet-handler.ts
|
|
1492
1447
|
var import_react8 = require("react");
|
|
1493
|
-
var import_client2 = require("@aomi-labs/client");
|
|
1494
|
-
|
|
1495
|
-
// packages/react/src/state/wallet-buffer.ts
|
|
1496
|
-
function createWalletBuffer() {
|
|
1497
|
-
return { queue: [], nextId: 1 };
|
|
1498
|
-
}
|
|
1499
|
-
function enqueue(buffer, kind, payload) {
|
|
1500
|
-
const request = {
|
|
1501
|
-
id: `wreq-${buffer.nextId++}`,
|
|
1502
|
-
kind,
|
|
1503
|
-
payload,
|
|
1504
|
-
status: "pending",
|
|
1505
|
-
timestamp: Date.now()
|
|
1506
|
-
};
|
|
1507
|
-
buffer.queue.push(request);
|
|
1508
|
-
return request;
|
|
1509
|
-
}
|
|
1510
|
-
function dequeue(buffer, id) {
|
|
1511
|
-
const index = buffer.queue.findIndex((r) => r.id === id);
|
|
1512
|
-
if (index === -1) return null;
|
|
1513
|
-
return buffer.queue.splice(index, 1)[0];
|
|
1514
|
-
}
|
|
1515
|
-
function markProcessing(buffer, id) {
|
|
1516
|
-
const request = buffer.queue.find((r) => r.id === id);
|
|
1517
|
-
if (!request || request.status !== "pending") return false;
|
|
1518
|
-
request.status = "processing";
|
|
1519
|
-
return true;
|
|
1520
|
-
}
|
|
1521
|
-
function getAll(buffer) {
|
|
1522
|
-
return [...buffer.queue];
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
// packages/react/src/handlers/wallet-handler.ts
|
|
1526
1448
|
function useWalletHandler({
|
|
1527
|
-
|
|
1528
|
-
onRequestComplete
|
|
1449
|
+
getSession
|
|
1529
1450
|
}) {
|
|
1530
|
-
const { subscribe: subscribe2, sendOutboundSystem: sendOutbound } = useEventContext();
|
|
1531
|
-
const bufferRef = (0, import_react8.useRef)(createWalletBuffer());
|
|
1532
1451
|
const [pendingRequests, setPendingRequests] = (0, import_react8.useState)([]);
|
|
1533
|
-
const
|
|
1534
|
-
|
|
1452
|
+
const requestsRef = (0, import_react8.useRef)([]);
|
|
1453
|
+
const enqueueRequest = (0, import_react8.useCallback)((request) => {
|
|
1454
|
+
requestsRef.current = [...requestsRef.current, request];
|
|
1455
|
+
setPendingRequests(requestsRef.current);
|
|
1535
1456
|
}, []);
|
|
1536
|
-
(0, import_react8.useEffect)(() => {
|
|
1537
|
-
const unsubscribe = subscribe2(
|
|
1538
|
-
"wallet_tx_request",
|
|
1539
|
-
(event) => {
|
|
1540
|
-
const payload = (0, import_client2.normalizeTxPayload)(event.payload);
|
|
1541
|
-
if (!payload) {
|
|
1542
|
-
console.warn("[aomi][wallet] Ignoring tx request with invalid payload", event.payload);
|
|
1543
|
-
return;
|
|
1544
|
-
}
|
|
1545
|
-
enqueue(bufferRef.current, "transaction", payload);
|
|
1546
|
-
syncState();
|
|
1547
|
-
}
|
|
1548
|
-
);
|
|
1549
|
-
return unsubscribe;
|
|
1550
|
-
}, [subscribe2, syncState]);
|
|
1551
|
-
(0, import_react8.useEffect)(() => {
|
|
1552
|
-
const unsubscribe = subscribe2(
|
|
1553
|
-
"wallet_eip712_request",
|
|
1554
|
-
(event) => {
|
|
1555
|
-
var _a;
|
|
1556
|
-
const payload = (0, import_client2.normalizeEip712Payload)((_a = event.payload) != null ? _a : {});
|
|
1557
|
-
enqueue(bufferRef.current, "eip712_sign", payload);
|
|
1558
|
-
syncState();
|
|
1559
|
-
}
|
|
1560
|
-
);
|
|
1561
|
-
return unsubscribe;
|
|
1562
|
-
}, [subscribe2, syncState]);
|
|
1563
|
-
const startProcessingCb = (0, import_react8.useCallback)(
|
|
1564
|
-
(id) => {
|
|
1565
|
-
markProcessing(bufferRef.current, id);
|
|
1566
|
-
syncState();
|
|
1567
|
-
},
|
|
1568
|
-
[syncState]
|
|
1569
|
-
);
|
|
1570
1457
|
const resolveRequest = (0, import_react8.useCallback)(
|
|
1571
1458
|
(id, result) => {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
if (removed.kind === "transaction") {
|
|
1577
|
-
outbound = sendOutbound({
|
|
1578
|
-
type: "wallet:tx_complete",
|
|
1579
|
-
sessionId,
|
|
1580
|
-
payload: {
|
|
1581
|
-
txHash: (_a = result.txHash) != null ? _a : "",
|
|
1582
|
-
status: "success",
|
|
1583
|
-
amount: result.amount
|
|
1584
|
-
}
|
|
1585
|
-
});
|
|
1586
|
-
} else {
|
|
1587
|
-
const eip712Payload = removed.payload;
|
|
1588
|
-
outbound = sendOutbound({
|
|
1589
|
-
type: "wallet_eip712_response",
|
|
1590
|
-
sessionId,
|
|
1591
|
-
payload: {
|
|
1592
|
-
status: "success",
|
|
1593
|
-
signature: result.signature,
|
|
1594
|
-
description: eip712Payload.description
|
|
1595
|
-
}
|
|
1596
|
-
});
|
|
1459
|
+
const session = getSession();
|
|
1460
|
+
if (!session) {
|
|
1461
|
+
console.error("[wallet-handler] No session available to resolve request");
|
|
1462
|
+
return;
|
|
1597
1463
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1464
|
+
requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
|
|
1465
|
+
setPendingRequests(requestsRef.current);
|
|
1466
|
+
void session.resolve(id, result).catch((err) => {
|
|
1467
|
+
console.error("[wallet-handler] Failed to resolve request:", err);
|
|
1468
|
+
});
|
|
1600
1469
|
},
|
|
1601
|
-
[
|
|
1470
|
+
[getSession]
|
|
1602
1471
|
);
|
|
1603
1472
|
const rejectRequest = (0, import_react8.useCallback)(
|
|
1604
1473
|
(id, error) => {
|
|
1605
|
-
const
|
|
1606
|
-
if (!
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
outbound = sendOutbound({
|
|
1610
|
-
type: "wallet:tx_complete",
|
|
1611
|
-
sessionId,
|
|
1612
|
-
payload: {
|
|
1613
|
-
txHash: "",
|
|
1614
|
-
status: "failed"
|
|
1615
|
-
}
|
|
1616
|
-
});
|
|
1617
|
-
} else {
|
|
1618
|
-
const eip712Payload = removed.payload;
|
|
1619
|
-
outbound = sendOutbound({
|
|
1620
|
-
type: "wallet_eip712_response",
|
|
1621
|
-
sessionId,
|
|
1622
|
-
payload: {
|
|
1623
|
-
status: "failed",
|
|
1624
|
-
error: error != null ? error : "EIP-712 signing failed",
|
|
1625
|
-
description: eip712Payload.description
|
|
1626
|
-
}
|
|
1627
|
-
});
|
|
1474
|
+
const session = getSession();
|
|
1475
|
+
if (!session) {
|
|
1476
|
+
console.error("[wallet-handler] No session available to reject request");
|
|
1477
|
+
return;
|
|
1628
1478
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1479
|
+
requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
|
|
1480
|
+
setPendingRequests(requestsRef.current);
|
|
1481
|
+
void session.reject(id, error).catch((err) => {
|
|
1482
|
+
console.error("[wallet-handler] Failed to reject request:", err);
|
|
1483
|
+
});
|
|
1631
1484
|
},
|
|
1632
|
-
[
|
|
1485
|
+
[getSession]
|
|
1633
1486
|
);
|
|
1634
1487
|
return {
|
|
1635
1488
|
pendingRequests,
|
|
1636
|
-
|
|
1489
|
+
enqueueRequest,
|
|
1637
1490
|
resolveRequest,
|
|
1638
1491
|
rejectRequest
|
|
1639
1492
|
};
|
|
@@ -1648,19 +1501,25 @@ function AomiRuntimeCore({
|
|
|
1648
1501
|
const threadContext = useThreadContext();
|
|
1649
1502
|
const eventContext = useEventContext();
|
|
1650
1503
|
const notificationContext = useNotification();
|
|
1651
|
-
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1652
1504
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1653
1505
|
const { getControlState, getCurrentThreadApp, clearSecrets } = useControl();
|
|
1506
|
+
const sessionManagerRef = (0, import_react9.useRef)(null);
|
|
1507
|
+
const walletHandler = useWalletHandler({
|
|
1508
|
+
getSession: () => {
|
|
1509
|
+
var _a;
|
|
1510
|
+
return (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadContext.currentThreadId);
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1654
1513
|
const {
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
messageController,
|
|
1514
|
+
sessionManager,
|
|
1515
|
+
getSession,
|
|
1658
1516
|
isRunning,
|
|
1659
1517
|
setIsRunning,
|
|
1660
1518
|
ensureInitialState,
|
|
1519
|
+
sendMessage: orchestratorSendMessage,
|
|
1520
|
+
cancelGeneration: orchestratorCancel,
|
|
1661
1521
|
aomiClientRef
|
|
1662
1522
|
} = useRuntimeOrchestrator(aomiClient, {
|
|
1663
|
-
onSyncEvents: dispatchSystemEvents,
|
|
1664
1523
|
getPublicKey: () => getUserState().address,
|
|
1665
1524
|
getUserState,
|
|
1666
1525
|
getApp: getCurrentThreadApp,
|
|
@@ -1668,8 +1527,11 @@ function AomiRuntimeCore({
|
|
|
1668
1527
|
getClientId: () => {
|
|
1669
1528
|
var _a;
|
|
1670
1529
|
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1671
|
-
}
|
|
1530
|
+
},
|
|
1531
|
+
onWalletRequest: (request) => walletHandler.enqueueRequest(request),
|
|
1532
|
+
onEvent: (event) => eventContext.dispatch(event)
|
|
1672
1533
|
});
|
|
1534
|
+
sessionManagerRef.current = sessionManager;
|
|
1673
1535
|
const walletSnapshot = (0, import_react9.useCallback)(
|
|
1674
1536
|
(nextUser) => ({
|
|
1675
1537
|
address: nextUser.address,
|
|
@@ -1710,13 +1572,6 @@ function AomiRuntimeCore({
|
|
|
1710
1572
|
(0, import_react9.useEffect)(() => {
|
|
1711
1573
|
currentThreadIdRef.current = threadContext.currentThreadId;
|
|
1712
1574
|
}, [threadContext.currentThreadId]);
|
|
1713
|
-
const onWalletRequestComplete = (0, import_react9.useCallback)(() => {
|
|
1714
|
-
polling.start(currentThreadIdRef.current);
|
|
1715
|
-
}, [polling]);
|
|
1716
|
-
const walletHandler = useWalletHandler({
|
|
1717
|
-
sessionId: threadContext.currentThreadId,
|
|
1718
|
-
onRequestComplete: onWalletRequestComplete
|
|
1719
|
-
});
|
|
1720
1575
|
(0, import_react9.useEffect)(() => {
|
|
1721
1576
|
const unsubscribe = eventContext.subscribe(
|
|
1722
1577
|
"user_state_request",
|
|
@@ -1733,10 +1588,6 @@ function AomiRuntimeCore({
|
|
|
1733
1588
|
(0, import_react9.useEffect)(() => {
|
|
1734
1589
|
void ensureInitialState(threadContext.currentThreadId);
|
|
1735
1590
|
}, [ensureInitialState, threadContext.currentThreadId]);
|
|
1736
|
-
(0, import_react9.useEffect)(() => {
|
|
1737
|
-
const threadId = threadContext.currentThreadId;
|
|
1738
|
-
setIsRunning(isThreadRunning(backendStateRef.current, threadId));
|
|
1739
|
-
}, [backendStateRef, setIsRunning, threadContext.currentThreadId]);
|
|
1740
1591
|
(0, import_react9.useEffect)(() => {
|
|
1741
1592
|
const threadId = threadContext.currentThreadId;
|
|
1742
1593
|
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
@@ -1792,65 +1643,18 @@ function AomiRuntimeCore({
|
|
|
1792
1643
|
}, [user.address, aomiClientRef]);
|
|
1793
1644
|
const threadListAdapter = (0, import_react9.useMemo)(
|
|
1794
1645
|
() => buildThreadListAdapter({
|
|
1795
|
-
backendStateRef,
|
|
1796
1646
|
aomiClientRef,
|
|
1797
1647
|
threadContext,
|
|
1798
|
-
|
|
1799
|
-
polling,
|
|
1800
|
-
userAddress: user.address,
|
|
1801
|
-
setIsRunning,
|
|
1802
|
-
getApp: getCurrentThreadApp,
|
|
1803
|
-
getApiKey: () => getControlState().apiKey,
|
|
1804
|
-
getUserState
|
|
1648
|
+
setIsRunning
|
|
1805
1649
|
}),
|
|
1806
1650
|
[
|
|
1807
1651
|
aomiClientRef,
|
|
1808
|
-
polling,
|
|
1809
|
-
user.address,
|
|
1810
|
-
backendStateRef,
|
|
1811
1652
|
setIsRunning,
|
|
1812
1653
|
threadContext,
|
|
1813
1654
|
threadContext.currentThreadId,
|
|
1814
|
-
threadContext.allThreadsMetadata
|
|
1815
|
-
getControlState,
|
|
1816
|
-
getCurrentThreadApp,
|
|
1817
|
-
getUserState
|
|
1655
|
+
threadContext.allThreadsMetadata
|
|
1818
1656
|
]
|
|
1819
1657
|
);
|
|
1820
|
-
(0, import_react9.useEffect)(() => {
|
|
1821
|
-
const backendState = backendStateRef.current;
|
|
1822
|
-
const unsubscribe = eventContext.subscribe("title_changed", (event) => {
|
|
1823
|
-
const sessionId = event.sessionId;
|
|
1824
|
-
const payload = event.payload;
|
|
1825
|
-
const newTitle = payload == null ? void 0 : payload.new_title;
|
|
1826
|
-
if (typeof newTitle !== "string") return;
|
|
1827
|
-
const targetThreadId = resolveThreadId(backendState, sessionId);
|
|
1828
|
-
const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
|
|
1829
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1830
|
-
console.debug("[aomi][sse] title_changed", {
|
|
1831
|
-
sessionId,
|
|
1832
|
-
newTitle,
|
|
1833
|
-
normalizedTitle,
|
|
1834
|
-
currentThreadId: threadContextRef.current.currentThreadId,
|
|
1835
|
-
targetThreadId
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
threadContextRef.current.setThreadMetadata((prev) => {
|
|
1839
|
-
var _a, _b;
|
|
1840
|
-
const next = new Map(prev);
|
|
1841
|
-
const existing = next.get(targetThreadId);
|
|
1842
|
-
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1843
|
-
next.set(targetThreadId, {
|
|
1844
|
-
title: normalizedTitle,
|
|
1845
|
-
status: nextStatus,
|
|
1846
|
-
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1847
|
-
control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
|
|
1848
|
-
});
|
|
1849
|
-
return next;
|
|
1850
|
-
});
|
|
1851
|
-
});
|
|
1852
|
-
return unsubscribe;
|
|
1853
|
-
}, [eventContext, backendStateRef]);
|
|
1854
1658
|
(0, import_react9.useEffect)(() => {
|
|
1855
1659
|
const showToolNotification = (eventType) => (event) => {
|
|
1856
1660
|
const payload = event.payload;
|
|
@@ -1877,9 +1681,7 @@ function AomiRuntimeCore({
|
|
|
1877
1681
|
};
|
|
1878
1682
|
}, [eventContext, notificationContext]);
|
|
1879
1683
|
(0, import_react9.useEffect)(() => {
|
|
1880
|
-
const unsubscribe = eventContext.subscribe("system_notice", (
|
|
1881
|
-
const payload = event.payload;
|
|
1882
|
-
const message = payload == null ? void 0 : payload.message;
|
|
1684
|
+
const unsubscribe = eventContext.subscribe("system_notice", (_event) => {
|
|
1883
1685
|
});
|
|
1884
1686
|
return unsubscribe;
|
|
1885
1687
|
}, [eventContext, notificationContext]);
|
|
@@ -1887,34 +1689,36 @@ function AomiRuntimeCore({
|
|
|
1887
1689
|
messages: currentMessages,
|
|
1888
1690
|
setMessages: (msgs) => threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),
|
|
1889
1691
|
isRunning,
|
|
1890
|
-
onNew: (message) =>
|
|
1891
|
-
|
|
1692
|
+
onNew: async (message) => {
|
|
1693
|
+
const text = message.content.filter(
|
|
1694
|
+
(part) => part.type === "text"
|
|
1695
|
+
).map((part) => part.text).join("\n");
|
|
1696
|
+
if (text) {
|
|
1697
|
+
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1698
|
+
}
|
|
1699
|
+
},
|
|
1700
|
+
onCancel: async () => {
|
|
1701
|
+
await orchestratorCancel(threadContext.currentThreadId);
|
|
1702
|
+
},
|
|
1892
1703
|
convertMessage: (msg) => msg,
|
|
1893
1704
|
adapters: { threadList: threadListAdapter }
|
|
1894
1705
|
});
|
|
1895
1706
|
(0, import_react9.useEffect)(() => {
|
|
1896
1707
|
return () => {
|
|
1897
|
-
|
|
1708
|
+
sessionManager.closeAll();
|
|
1898
1709
|
void clearSecrets();
|
|
1899
1710
|
};
|
|
1900
|
-
}, [
|
|
1711
|
+
}, [sessionManager, clearSecrets]);
|
|
1901
1712
|
const userContext = useUser();
|
|
1902
1713
|
const sendMessage = (0, import_react9.useCallback)(
|
|
1903
1714
|
async (text) => {
|
|
1904
|
-
|
|
1905
|
-
role: "user",
|
|
1906
|
-
content: [{ type: "text", text }]
|
|
1907
|
-
};
|
|
1908
|
-
await messageController.outbound(
|
|
1909
|
-
appendMessage,
|
|
1910
|
-
threadContext.currentThreadId
|
|
1911
|
-
);
|
|
1715
|
+
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1912
1716
|
},
|
|
1913
|
-
[
|
|
1717
|
+
[orchestratorSendMessage, threadContext.currentThreadId]
|
|
1914
1718
|
);
|
|
1915
1719
|
const cancelGeneration = (0, import_react9.useCallback)(() => {
|
|
1916
|
-
|
|
1917
|
-
}, [
|
|
1720
|
+
void orchestratorCancel(threadContext.currentThreadId);
|
|
1721
|
+
}, [orchestratorCancel, threadContext.currentThreadId]);
|
|
1918
1722
|
const getMessages = (0, import_react9.useCallback)(
|
|
1919
1723
|
(threadId) => {
|
|
1920
1724
|
const id = threadId != null ? threadId : threadContext.currentThreadId;
|
|
@@ -1928,9 +1732,10 @@ function AomiRuntimeCore({
|
|
|
1928
1732
|
}, [threadListAdapter]);
|
|
1929
1733
|
const deleteThread = (0, import_react9.useCallback)(
|
|
1930
1734
|
async (threadId) => {
|
|
1735
|
+
sessionManager.close(threadId);
|
|
1931
1736
|
await threadListAdapter.onDelete(threadId);
|
|
1932
1737
|
},
|
|
1933
|
-
[threadListAdapter]
|
|
1738
|
+
[threadListAdapter, sessionManager]
|
|
1934
1739
|
);
|
|
1935
1740
|
const renameThread = (0, import_react9.useCallback)(
|
|
1936
1741
|
async (threadId, title) => {
|
|
@@ -1985,7 +1790,9 @@ function AomiRuntimeCore({
|
|
|
1985
1790
|
clearAllNotifications: notificationContext.clearAll,
|
|
1986
1791
|
// Wallet API
|
|
1987
1792
|
pendingWalletRequests: walletHandler.pendingRequests,
|
|
1988
|
-
startWalletRequest:
|
|
1793
|
+
startWalletRequest: () => {
|
|
1794
|
+
},
|
|
1795
|
+
// No-op: ClientSession manages processing state
|
|
1989
1796
|
resolveWalletRequest: walletHandler.resolveRequest,
|
|
1990
1797
|
rejectWalletRequest: walletHandler.rejectRequest,
|
|
1991
1798
|
// Event API
|
|
@@ -2022,7 +1829,7 @@ function AomiRuntimeProvider({
|
|
|
2022
1829
|
children,
|
|
2023
1830
|
backendUrl = "http://localhost:8080"
|
|
2024
1831
|
}) {
|
|
2025
|
-
const aomiClient = (0, import_react11.useMemo)(() => new
|
|
1832
|
+
const aomiClient = (0, import_react11.useMemo)(() => new import_client2.AomiClient({ baseUrl: backendUrl }), [backendUrl]);
|
|
2026
1833
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThreadContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NotificationContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AomiRuntimeInner, { aomiClient, children }) }) }) });
|
|
2027
1834
|
}
|
|
2028
1835
|
function AomiRuntimeInner({
|
|
@@ -2061,10 +1868,10 @@ function generateNotificationId() {
|
|
|
2061
1868
|
function useNotificationHandler({
|
|
2062
1869
|
onNotification
|
|
2063
1870
|
} = {}) {
|
|
2064
|
-
const { subscribe
|
|
1871
|
+
const { subscribe } = useEventContext();
|
|
2065
1872
|
const [notifications, setNotifications] = (0, import_react12.useState)([]);
|
|
2066
1873
|
(0, import_react12.useEffect)(() => {
|
|
2067
|
-
const unsubscribe =
|
|
1874
|
+
const unsubscribe = subscribe("notification", (event) => {
|
|
2068
1875
|
var _a, _b;
|
|
2069
1876
|
const payload = event.payload;
|
|
2070
1877
|
const notification = {
|
|
@@ -2073,14 +1880,14 @@ function useNotificationHandler({
|
|
|
2073
1880
|
title: (_b = payload.title) != null ? _b : "Notification",
|
|
2074
1881
|
body: payload.body,
|
|
2075
1882
|
handled: false,
|
|
2076
|
-
timestamp:
|
|
1883
|
+
timestamp: Date.now(),
|
|
2077
1884
|
sessionId: event.sessionId
|
|
2078
1885
|
};
|
|
2079
1886
|
setNotifications((prev) => [notification, ...prev]);
|
|
2080
1887
|
onNotification == null ? void 0 : onNotification(notification);
|
|
2081
1888
|
});
|
|
2082
1889
|
return unsubscribe;
|
|
2083
|
-
}, [
|
|
1890
|
+
}, [subscribe, onNotification]);
|
|
2084
1891
|
const unhandledCount = notifications.filter((n) => !n.handled).length;
|
|
2085
1892
|
const markHandled = (0, import_react12.useCallback)((id) => {
|
|
2086
1893
|
setNotifications(
|