@aomi-labs/react 0.3.5 → 0.3.6
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 +276 -611
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -56
- package/dist/index.d.ts +41 -56
- package/dist/index.js +293 -638
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -37,7 +37,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
37
37
|
// packages/react/src/index.ts
|
|
38
38
|
var index_exports = {};
|
|
39
39
|
__export(index_exports, {
|
|
40
|
-
AomiClient: () =>
|
|
40
|
+
AomiClient: () => import_client3.AomiClient,
|
|
41
41
|
AomiRuntimeProvider: () => AomiRuntimeProvider,
|
|
42
42
|
ControlContextProvider: () => ControlContextProvider,
|
|
43
43
|
EventContextProvider: () => EventContextProvider,
|
|
@@ -50,7 +50,7 @@ __export(index_exports, {
|
|
|
50
50
|
getChainInfo: () => getChainInfo,
|
|
51
51
|
getNetworkName: () => getNetworkName,
|
|
52
52
|
initThreadControl: () => initThreadControl,
|
|
53
|
-
toViemSignTypedDataArgs: () =>
|
|
53
|
+
toViemSignTypedDataArgs: () => import_client4.toViemSignTypedDataArgs,
|
|
54
54
|
useAomiRuntime: () => useAomiRuntime,
|
|
55
55
|
useControl: () => useControl,
|
|
56
56
|
useCurrentThreadMessages: () => useCurrentThreadMessages,
|
|
@@ -63,12 +63,12 @@ __export(index_exports, {
|
|
|
63
63
|
useWalletHandler: () => useWalletHandler
|
|
64
64
|
});
|
|
65
65
|
module.exports = __toCommonJS(index_exports);
|
|
66
|
+
var import_client3 = require("@aomi-labs/client");
|
|
66
67
|
var import_client4 = require("@aomi-labs/client");
|
|
67
|
-
var import_client5 = require("@aomi-labs/client");
|
|
68
68
|
|
|
69
69
|
// packages/react/src/runtime/aomi-runtime.tsx
|
|
70
70
|
var import_react11 = require("react");
|
|
71
|
-
var
|
|
71
|
+
var import_client2 = require("@aomi-labs/client");
|
|
72
72
|
|
|
73
73
|
// packages/react/src/contexts/control-context.tsx
|
|
74
74
|
var import_react = require("react");
|
|
@@ -594,53 +594,6 @@ function ControlContextProvider({
|
|
|
594
594
|
|
|
595
595
|
// packages/react/src/contexts/event-context.tsx
|
|
596
596
|
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
597
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
645
598
|
var EventContextState = (0, import_react2.createContext)(null);
|
|
646
599
|
function useEventContext() {
|
|
@@ -657,52 +610,32 @@ function EventContextProvider({
|
|
|
657
610
|
aomiClient,
|
|
658
611
|
sessionId
|
|
659
612
|
}) {
|
|
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)(
|
|
613
|
+
const subscribersRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
614
|
+
const subscribe = (0, import_react2.useCallback)(
|
|
701
615
|
(type, callback) => {
|
|
702
|
-
|
|
616
|
+
const subs = subscribersRef.current;
|
|
617
|
+
if (!subs.has(type)) {
|
|
618
|
+
subs.set(type, /* @__PURE__ */ new Set());
|
|
619
|
+
}
|
|
620
|
+
subs.get(type).add(callback);
|
|
621
|
+
return () => {
|
|
622
|
+
var _a;
|
|
623
|
+
(_a = subs.get(type)) == null ? void 0 : _a.delete(callback);
|
|
624
|
+
};
|
|
703
625
|
},
|
|
704
|
-
[
|
|
626
|
+
[]
|
|
705
627
|
);
|
|
628
|
+
const dispatchEvent = (0, import_react2.useCallback)((event) => {
|
|
629
|
+
const subs = subscribersRef.current;
|
|
630
|
+
const typeSubs = subs.get(event.type);
|
|
631
|
+
if (typeSubs) {
|
|
632
|
+
for (const cb of typeSubs) cb(event);
|
|
633
|
+
}
|
|
634
|
+
const wildcardSubs = subs.get("*");
|
|
635
|
+
if (wildcardSubs) {
|
|
636
|
+
for (const cb of wildcardSubs) cb(event);
|
|
637
|
+
}
|
|
638
|
+
}, []);
|
|
706
639
|
const sendOutbound = (0, import_react2.useCallback)(
|
|
707
640
|
async (event) => {
|
|
708
641
|
try {
|
|
@@ -717,50 +650,14 @@ function EventContextProvider({
|
|
|
717
650
|
},
|
|
718
651
|
[aomiClient]
|
|
719
652
|
);
|
|
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
653
|
const contextValue = {
|
|
760
|
-
subscribe
|
|
654
|
+
subscribe,
|
|
655
|
+
dispatch: dispatchEvent,
|
|
761
656
|
sendOutboundSystem: sendOutbound,
|
|
762
|
-
|
|
763
|
-
|
|
657
|
+
// SSE is managed by ClientSession now — status is always "connected"
|
|
658
|
+
// when sessions are active. Individual session status can be queried
|
|
659
|
+
// from the session manager if needed.
|
|
660
|
+
sseStatus: "connected"
|
|
764
661
|
};
|
|
765
662
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EventContextState.Provider, { value: contextValue, children });
|
|
766
663
|
}
|
|
@@ -957,6 +854,40 @@ var import_react10 = require("@assistant-ui/react");
|
|
|
957
854
|
// packages/react/src/runtime/orchestrator.ts
|
|
958
855
|
var import_react6 = require("react");
|
|
959
856
|
|
|
857
|
+
// packages/react/src/runtime/session-manager.ts
|
|
858
|
+
var import_client = require("@aomi-labs/client");
|
|
859
|
+
var SessionManager = class {
|
|
860
|
+
constructor(clientFactory) {
|
|
861
|
+
this.clientFactory = clientFactory;
|
|
862
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
863
|
+
}
|
|
864
|
+
getOrCreate(threadId, opts) {
|
|
865
|
+
let session = this.sessions.get(threadId);
|
|
866
|
+
if (session) return session;
|
|
867
|
+
session = new import_client.Session(this.clientFactory(), __spreadProps(__spreadValues({}, opts), {
|
|
868
|
+
sessionId: threadId
|
|
869
|
+
}));
|
|
870
|
+
this.sessions.set(threadId, session);
|
|
871
|
+
return session;
|
|
872
|
+
}
|
|
873
|
+
get(threadId) {
|
|
874
|
+
return this.sessions.get(threadId);
|
|
875
|
+
}
|
|
876
|
+
close(threadId) {
|
|
877
|
+
const session = this.sessions.get(threadId);
|
|
878
|
+
if (session) {
|
|
879
|
+
session.close();
|
|
880
|
+
this.sessions.delete(threadId);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
closeAll() {
|
|
884
|
+
for (const [threadId, session] of this.sessions) {
|
|
885
|
+
session.close();
|
|
886
|
+
}
|
|
887
|
+
this.sessions.clear();
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
|
|
960
891
|
// packages/react/src/runtime/utils.ts
|
|
961
892
|
var import_clsx = require("clsx");
|
|
962
893
|
var import_tailwind_merge = require("tailwind-merge");
|
|
@@ -1059,194 +990,6 @@ var SUPPORTED_CHAINS = [
|
|
|
1059
990
|
];
|
|
1060
991
|
var getChainInfo = (chainId) => chainId === void 0 ? void 0 : SUPPORTED_CHAINS.find((c) => c.id === chainId);
|
|
1061
992
|
|
|
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
993
|
// packages/react/src/runtime/orchestrator.ts
|
|
1251
994
|
function useRuntimeOrchestrator(aomiClient, options) {
|
|
1252
995
|
const threadContext = useThreadContext();
|
|
@@ -1254,90 +997,160 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1254
997
|
threadContextRef.current = threadContext;
|
|
1255
998
|
const aomiClientRef = (0, import_react6.useRef)(aomiClient);
|
|
1256
999
|
aomiClientRef.current = aomiClient;
|
|
1257
|
-
const backendStateRef = (0, import_react6.useRef)(createBackendState());
|
|
1258
1000
|
const [isRunning, setIsRunning] = (0, import_react6.useState)(false);
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1001
|
+
const sessionManagerRef = (0, import_react6.useRef)(null);
|
|
1002
|
+
if (!sessionManagerRef.current) {
|
|
1003
|
+
sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
|
|
1004
|
+
}
|
|
1261
1005
|
const pendingFetches = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1006
|
+
const listenerCleanups = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
1007
|
+
const getSession = (0, import_react6.useCallback)(
|
|
1008
|
+
(threadId) => {
|
|
1009
|
+
var _a, _b, _c, _d, _e;
|
|
1010
|
+
const manager = sessionManagerRef.current;
|
|
1011
|
+
const existing = manager.get(threadId);
|
|
1012
|
+
if (existing) return existing;
|
|
1013
|
+
const session = manager.getOrCreate(threadId, {
|
|
1014
|
+
app: options.getApp(),
|
|
1015
|
+
publicKey: (_a = options.getPublicKey) == null ? void 0 : _a.call(options),
|
|
1016
|
+
apiKey: (_c = (_b = options.getApiKey) == null ? void 0 : _b.call(options)) != null ? _c : void 0,
|
|
1017
|
+
clientId: (_d = options.getClientId) == null ? void 0 : _d.call(options),
|
|
1018
|
+
userState: (_e = options.getUserState) == null ? void 0 : _e.call(options)
|
|
1019
|
+
});
|
|
1020
|
+
const cleanups = [];
|
|
1021
|
+
cleanups.push(
|
|
1022
|
+
session.on("messages", (msgs) => {
|
|
1023
|
+
const threadMessages = [];
|
|
1024
|
+
for (const msg of msgs) {
|
|
1025
|
+
const converted = toInboundMessage(msg);
|
|
1026
|
+
if (converted) threadMessages.push(converted);
|
|
1027
|
+
}
|
|
1028
|
+
threadContextRef.current.setThreadMessages(threadId, threadMessages);
|
|
1029
|
+
})
|
|
1030
|
+
);
|
|
1031
|
+
cleanups.push(
|
|
1032
|
+
session.on("processing_start", () => {
|
|
1033
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1034
|
+
setIsRunning(true);
|
|
1035
|
+
}
|
|
1036
|
+
})
|
|
1037
|
+
);
|
|
1038
|
+
cleanups.push(
|
|
1039
|
+
session.on("processing_end", () => {
|
|
1040
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1041
|
+
setIsRunning(false);
|
|
1042
|
+
}
|
|
1043
|
+
})
|
|
1044
|
+
);
|
|
1045
|
+
cleanups.push(
|
|
1046
|
+
session.on("wallet_tx_request", (req) => {
|
|
1047
|
+
var _a2;
|
|
1048
|
+
return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
|
|
1049
|
+
})
|
|
1050
|
+
);
|
|
1051
|
+
cleanups.push(
|
|
1052
|
+
session.on("wallet_eip712_request", (req) => {
|
|
1053
|
+
var _a2;
|
|
1054
|
+
return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
|
|
1055
|
+
})
|
|
1056
|
+
);
|
|
1057
|
+
cleanups.push(
|
|
1058
|
+
session.on("title_changed", ({ title }) => {
|
|
1059
|
+
threadContextRef.current.updateThreadMetadata(threadId, { title });
|
|
1060
|
+
})
|
|
1061
|
+
);
|
|
1062
|
+
const forwardEvent = (type) => session.on(type, (payload) => {
|
|
1063
|
+
var _a2;
|
|
1064
|
+
(_a2 = options.onEvent) == null ? void 0 : _a2.call(options, { type, payload, sessionId: threadId });
|
|
1065
|
+
});
|
|
1066
|
+
cleanups.push(forwardEvent("tool_update"));
|
|
1067
|
+
cleanups.push(forwardEvent("tool_complete"));
|
|
1068
|
+
cleanups.push(forwardEvent("system_notice"));
|
|
1069
|
+
cleanups.push(forwardEvent("system_error"));
|
|
1070
|
+
cleanups.push(forwardEvent("async_callback"));
|
|
1071
|
+
listenerCleanups.current.set(threadId, () => {
|
|
1072
|
+
for (const cleanup of cleanups) cleanup();
|
|
1073
|
+
});
|
|
1074
|
+
return session;
|
|
1075
|
+
},
|
|
1076
|
+
// Stable deps — option getters are refs
|
|
1077
|
+
[]
|
|
1078
|
+
);
|
|
1079
|
+
const ensureInitialState = (0, import_react6.useCallback)(
|
|
1080
|
+
async (threadId) => {
|
|
1081
|
+
var _a;
|
|
1082
|
+
if (pendingFetches.current.has(threadId)) return;
|
|
1083
|
+
pendingFetches.current.add(threadId);
|
|
1084
|
+
try {
|
|
1085
|
+
const session = getSession(threadId);
|
|
1086
|
+
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1087
|
+
if (userState) session.resolveUserState(userState);
|
|
1088
|
+
await session.fetchCurrentState();
|
|
1274
1089
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1275
|
-
setIsRunning(
|
|
1090
|
+
setIsRunning(session.getIsProcessing());
|
|
1276
1091
|
}
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1092
|
+
} catch (error) {
|
|
1093
|
+
console.error("Failed to fetch initial state:", error);
|
|
1279
1094
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1280
1095
|
setIsRunning(false);
|
|
1281
1096
|
}
|
|
1097
|
+
} finally {
|
|
1098
|
+
pendingFetches.current.delete(threadId);
|
|
1282
1099
|
}
|
|
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 {
|
|
1100
|
+
},
|
|
1101
|
+
[getSession]
|
|
1102
|
+
);
|
|
1103
|
+
const sendMessage = (0, import_react6.useCallback)(
|
|
1104
|
+
async (text, threadId) => {
|
|
1105
|
+
var _a;
|
|
1106
|
+
const session = getSession(threadId);
|
|
1306
1107
|
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
|
-
|
|
1108
|
+
if (userState) session.resolveUserState(userState);
|
|
1109
|
+
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1110
|
+
const userMessage = {
|
|
1111
|
+
role: "user",
|
|
1112
|
+
content: [{ type: "text", text }],
|
|
1113
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
1114
|
+
};
|
|
1115
|
+
threadContextRef.current.setThreadMessages(threadId, [
|
|
1116
|
+
...existingMessages,
|
|
1117
|
+
userMessage
|
|
1118
|
+
]);
|
|
1119
|
+
threadContextRef.current.updateThreadMetadata(threadId, {
|
|
1120
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1121
|
+
});
|
|
1122
|
+
await session.sendAsync(text);
|
|
1123
|
+
},
|
|
1124
|
+
[getSession]
|
|
1125
|
+
);
|
|
1126
|
+
const cancelGeneration = (0, import_react6.useCallback)(
|
|
1127
|
+
async (threadId) => {
|
|
1128
|
+
var _a;
|
|
1129
|
+
const session = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1130
|
+
if (session) {
|
|
1131
|
+
await session.interrupt();
|
|
1324
1132
|
}
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1133
|
+
},
|
|
1134
|
+
[]
|
|
1135
|
+
);
|
|
1136
|
+
(0, import_react6.useEffect)(() => {
|
|
1137
|
+
return () => {
|
|
1138
|
+
var _a;
|
|
1139
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1140
|
+
for (const cleanup of listenerCleanups.current.values()) {
|
|
1141
|
+
cleanup();
|
|
1329
1142
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1143
|
+
listenerCleanups.current.clear();
|
|
1144
|
+
};
|
|
1333
1145
|
}, []);
|
|
1334
1146
|
return {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
messageController: messageControllerRef.current,
|
|
1147
|
+
sessionManager: sessionManagerRef.current,
|
|
1148
|
+
getSession,
|
|
1338
1149
|
isRunning,
|
|
1339
1150
|
setIsRunning,
|
|
1340
1151
|
ensureInitialState,
|
|
1152
|
+
sendMessage,
|
|
1153
|
+
cancelGeneration,
|
|
1341
1154
|
aomiClientRef
|
|
1342
1155
|
};
|
|
1343
1156
|
}
|
|
@@ -1490,150 +1303,48 @@ function useAomiRuntime() {
|
|
|
1490
1303
|
|
|
1491
1304
|
// packages/react/src/handlers/wallet-handler.ts
|
|
1492
1305
|
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
1306
|
function useWalletHandler({
|
|
1527
|
-
|
|
1528
|
-
onRequestComplete
|
|
1307
|
+
getSession
|
|
1529
1308
|
}) {
|
|
1530
|
-
const { subscribe: subscribe2, sendOutboundSystem: sendOutbound } = useEventContext();
|
|
1531
|
-
const bufferRef = (0, import_react8.useRef)(createWalletBuffer());
|
|
1532
1309
|
const [pendingRequests, setPendingRequests] = (0, import_react8.useState)([]);
|
|
1533
|
-
const
|
|
1534
|
-
|
|
1310
|
+
const requestsRef = (0, import_react8.useRef)([]);
|
|
1311
|
+
const enqueueRequest = (0, import_react8.useCallback)((request) => {
|
|
1312
|
+
requestsRef.current = [...requestsRef.current, request];
|
|
1313
|
+
setPendingRequests(requestsRef.current);
|
|
1535
1314
|
}, []);
|
|
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
1315
|
const resolveRequest = (0, import_react8.useCallback)(
|
|
1571
1316
|
(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
|
-
});
|
|
1317
|
+
const session = getSession();
|
|
1318
|
+
if (!session) {
|
|
1319
|
+
console.error("[wallet-handler] No session available to resolve request");
|
|
1320
|
+
return;
|
|
1597
1321
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1322
|
+
requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
|
|
1323
|
+
setPendingRequests(requestsRef.current);
|
|
1324
|
+
void session.resolve(id, result).catch((err) => {
|
|
1325
|
+
console.error("[wallet-handler] Failed to resolve request:", err);
|
|
1326
|
+
});
|
|
1600
1327
|
},
|
|
1601
|
-
[
|
|
1328
|
+
[getSession]
|
|
1602
1329
|
);
|
|
1603
1330
|
const rejectRequest = (0, import_react8.useCallback)(
|
|
1604
1331
|
(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
|
-
});
|
|
1332
|
+
const session = getSession();
|
|
1333
|
+
if (!session) {
|
|
1334
|
+
console.error("[wallet-handler] No session available to reject request");
|
|
1335
|
+
return;
|
|
1628
1336
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1337
|
+
requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
|
|
1338
|
+
setPendingRequests(requestsRef.current);
|
|
1339
|
+
void session.reject(id, error).catch((err) => {
|
|
1340
|
+
console.error("[wallet-handler] Failed to reject request:", err);
|
|
1341
|
+
});
|
|
1631
1342
|
},
|
|
1632
|
-
[
|
|
1343
|
+
[getSession]
|
|
1633
1344
|
);
|
|
1634
1345
|
return {
|
|
1635
1346
|
pendingRequests,
|
|
1636
|
-
|
|
1347
|
+
enqueueRequest,
|
|
1637
1348
|
resolveRequest,
|
|
1638
1349
|
rejectRequest
|
|
1639
1350
|
};
|
|
@@ -1648,19 +1359,25 @@ function AomiRuntimeCore({
|
|
|
1648
1359
|
const threadContext = useThreadContext();
|
|
1649
1360
|
const eventContext = useEventContext();
|
|
1650
1361
|
const notificationContext = useNotification();
|
|
1651
|
-
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1652
1362
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1653
1363
|
const { getControlState, getCurrentThreadApp, clearSecrets } = useControl();
|
|
1364
|
+
const sessionManagerRef = (0, import_react9.useRef)(null);
|
|
1365
|
+
const walletHandler = useWalletHandler({
|
|
1366
|
+
getSession: () => {
|
|
1367
|
+
var _a;
|
|
1368
|
+
return (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadContext.currentThreadId);
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1654
1371
|
const {
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
messageController,
|
|
1372
|
+
sessionManager,
|
|
1373
|
+
getSession,
|
|
1658
1374
|
isRunning,
|
|
1659
1375
|
setIsRunning,
|
|
1660
1376
|
ensureInitialState,
|
|
1377
|
+
sendMessage: orchestratorSendMessage,
|
|
1378
|
+
cancelGeneration: orchestratorCancel,
|
|
1661
1379
|
aomiClientRef
|
|
1662
1380
|
} = useRuntimeOrchestrator(aomiClient, {
|
|
1663
|
-
onSyncEvents: dispatchSystemEvents,
|
|
1664
1381
|
getPublicKey: () => getUserState().address,
|
|
1665
1382
|
getUserState,
|
|
1666
1383
|
getApp: getCurrentThreadApp,
|
|
@@ -1668,8 +1385,11 @@ function AomiRuntimeCore({
|
|
|
1668
1385
|
getClientId: () => {
|
|
1669
1386
|
var _a;
|
|
1670
1387
|
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1671
|
-
}
|
|
1388
|
+
},
|
|
1389
|
+
onWalletRequest: (request) => walletHandler.enqueueRequest(request),
|
|
1390
|
+
onEvent: (event) => eventContext.dispatch(event)
|
|
1672
1391
|
});
|
|
1392
|
+
sessionManagerRef.current = sessionManager;
|
|
1673
1393
|
const walletSnapshot = (0, import_react9.useCallback)(
|
|
1674
1394
|
(nextUser) => ({
|
|
1675
1395
|
address: nextUser.address,
|
|
@@ -1710,13 +1430,6 @@ function AomiRuntimeCore({
|
|
|
1710
1430
|
(0, import_react9.useEffect)(() => {
|
|
1711
1431
|
currentThreadIdRef.current = threadContext.currentThreadId;
|
|
1712
1432
|
}, [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
1433
|
(0, import_react9.useEffect)(() => {
|
|
1721
1434
|
const unsubscribe = eventContext.subscribe(
|
|
1722
1435
|
"user_state_request",
|
|
@@ -1733,10 +1446,6 @@ function AomiRuntimeCore({
|
|
|
1733
1446
|
(0, import_react9.useEffect)(() => {
|
|
1734
1447
|
void ensureInitialState(threadContext.currentThreadId);
|
|
1735
1448
|
}, [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
1449
|
(0, import_react9.useEffect)(() => {
|
|
1741
1450
|
const threadId = threadContext.currentThreadId;
|
|
1742
1451
|
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
@@ -1792,65 +1501,18 @@ function AomiRuntimeCore({
|
|
|
1792
1501
|
}, [user.address, aomiClientRef]);
|
|
1793
1502
|
const threadListAdapter = (0, import_react9.useMemo)(
|
|
1794
1503
|
() => buildThreadListAdapter({
|
|
1795
|
-
backendStateRef,
|
|
1796
1504
|
aomiClientRef,
|
|
1797
1505
|
threadContext,
|
|
1798
|
-
|
|
1799
|
-
polling,
|
|
1800
|
-
userAddress: user.address,
|
|
1801
|
-
setIsRunning,
|
|
1802
|
-
getApp: getCurrentThreadApp,
|
|
1803
|
-
getApiKey: () => getControlState().apiKey,
|
|
1804
|
-
getUserState
|
|
1506
|
+
setIsRunning
|
|
1805
1507
|
}),
|
|
1806
1508
|
[
|
|
1807
1509
|
aomiClientRef,
|
|
1808
|
-
polling,
|
|
1809
|
-
user.address,
|
|
1810
|
-
backendStateRef,
|
|
1811
1510
|
setIsRunning,
|
|
1812
1511
|
threadContext,
|
|
1813
1512
|
threadContext.currentThreadId,
|
|
1814
|
-
threadContext.allThreadsMetadata
|
|
1815
|
-
getControlState,
|
|
1816
|
-
getCurrentThreadApp,
|
|
1817
|
-
getUserState
|
|
1513
|
+
threadContext.allThreadsMetadata
|
|
1818
1514
|
]
|
|
1819
1515
|
);
|
|
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
1516
|
(0, import_react9.useEffect)(() => {
|
|
1855
1517
|
const showToolNotification = (eventType) => (event) => {
|
|
1856
1518
|
const payload = event.payload;
|
|
@@ -1877,9 +1539,7 @@ function AomiRuntimeCore({
|
|
|
1877
1539
|
};
|
|
1878
1540
|
}, [eventContext, notificationContext]);
|
|
1879
1541
|
(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;
|
|
1542
|
+
const unsubscribe = eventContext.subscribe("system_notice", (_event) => {
|
|
1883
1543
|
});
|
|
1884
1544
|
return unsubscribe;
|
|
1885
1545
|
}, [eventContext, notificationContext]);
|
|
@@ -1887,34 +1547,36 @@ function AomiRuntimeCore({
|
|
|
1887
1547
|
messages: currentMessages,
|
|
1888
1548
|
setMessages: (msgs) => threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),
|
|
1889
1549
|
isRunning,
|
|
1890
|
-
onNew: (message) =>
|
|
1891
|
-
|
|
1550
|
+
onNew: async (message) => {
|
|
1551
|
+
const text = message.content.filter(
|
|
1552
|
+
(part) => part.type === "text"
|
|
1553
|
+
).map((part) => part.text).join("\n");
|
|
1554
|
+
if (text) {
|
|
1555
|
+
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1556
|
+
}
|
|
1557
|
+
},
|
|
1558
|
+
onCancel: async () => {
|
|
1559
|
+
await orchestratorCancel(threadContext.currentThreadId);
|
|
1560
|
+
},
|
|
1892
1561
|
convertMessage: (msg) => msg,
|
|
1893
1562
|
adapters: { threadList: threadListAdapter }
|
|
1894
1563
|
});
|
|
1895
1564
|
(0, import_react9.useEffect)(() => {
|
|
1896
1565
|
return () => {
|
|
1897
|
-
|
|
1566
|
+
sessionManager.closeAll();
|
|
1898
1567
|
void clearSecrets();
|
|
1899
1568
|
};
|
|
1900
|
-
}, [
|
|
1569
|
+
}, [sessionManager, clearSecrets]);
|
|
1901
1570
|
const userContext = useUser();
|
|
1902
1571
|
const sendMessage = (0, import_react9.useCallback)(
|
|
1903
1572
|
async (text) => {
|
|
1904
|
-
|
|
1905
|
-
role: "user",
|
|
1906
|
-
content: [{ type: "text", text }]
|
|
1907
|
-
};
|
|
1908
|
-
await messageController.outbound(
|
|
1909
|
-
appendMessage,
|
|
1910
|
-
threadContext.currentThreadId
|
|
1911
|
-
);
|
|
1573
|
+
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1912
1574
|
},
|
|
1913
|
-
[
|
|
1575
|
+
[orchestratorSendMessage, threadContext.currentThreadId]
|
|
1914
1576
|
);
|
|
1915
1577
|
const cancelGeneration = (0, import_react9.useCallback)(() => {
|
|
1916
|
-
|
|
1917
|
-
}, [
|
|
1578
|
+
void orchestratorCancel(threadContext.currentThreadId);
|
|
1579
|
+
}, [orchestratorCancel, threadContext.currentThreadId]);
|
|
1918
1580
|
const getMessages = (0, import_react9.useCallback)(
|
|
1919
1581
|
(threadId) => {
|
|
1920
1582
|
const id = threadId != null ? threadId : threadContext.currentThreadId;
|
|
@@ -1928,9 +1590,10 @@ function AomiRuntimeCore({
|
|
|
1928
1590
|
}, [threadListAdapter]);
|
|
1929
1591
|
const deleteThread = (0, import_react9.useCallback)(
|
|
1930
1592
|
async (threadId) => {
|
|
1593
|
+
sessionManager.close(threadId);
|
|
1931
1594
|
await threadListAdapter.onDelete(threadId);
|
|
1932
1595
|
},
|
|
1933
|
-
[threadListAdapter]
|
|
1596
|
+
[threadListAdapter, sessionManager]
|
|
1934
1597
|
);
|
|
1935
1598
|
const renameThread = (0, import_react9.useCallback)(
|
|
1936
1599
|
async (threadId, title) => {
|
|
@@ -1985,7 +1648,9 @@ function AomiRuntimeCore({
|
|
|
1985
1648
|
clearAllNotifications: notificationContext.clearAll,
|
|
1986
1649
|
// Wallet API
|
|
1987
1650
|
pendingWalletRequests: walletHandler.pendingRequests,
|
|
1988
|
-
startWalletRequest:
|
|
1651
|
+
startWalletRequest: () => {
|
|
1652
|
+
},
|
|
1653
|
+
// No-op: ClientSession manages processing state
|
|
1989
1654
|
resolveWalletRequest: walletHandler.resolveRequest,
|
|
1990
1655
|
rejectWalletRequest: walletHandler.rejectRequest,
|
|
1991
1656
|
// Event API
|
|
@@ -2022,7 +1687,7 @@ function AomiRuntimeProvider({
|
|
|
2022
1687
|
children,
|
|
2023
1688
|
backendUrl = "http://localhost:8080"
|
|
2024
1689
|
}) {
|
|
2025
|
-
const aomiClient = (0, import_react11.useMemo)(() => new
|
|
1690
|
+
const aomiClient = (0, import_react11.useMemo)(() => new import_client2.AomiClient({ baseUrl: backendUrl }), [backendUrl]);
|
|
2026
1691
|
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
1692
|
}
|
|
2028
1693
|
function AomiRuntimeInner({
|
|
@@ -2061,10 +1726,10 @@ function generateNotificationId() {
|
|
|
2061
1726
|
function useNotificationHandler({
|
|
2062
1727
|
onNotification
|
|
2063
1728
|
} = {}) {
|
|
2064
|
-
const { subscribe
|
|
1729
|
+
const { subscribe } = useEventContext();
|
|
2065
1730
|
const [notifications, setNotifications] = (0, import_react12.useState)([]);
|
|
2066
1731
|
(0, import_react12.useEffect)(() => {
|
|
2067
|
-
const unsubscribe =
|
|
1732
|
+
const unsubscribe = subscribe("notification", (event) => {
|
|
2068
1733
|
var _a, _b;
|
|
2069
1734
|
const payload = event.payload;
|
|
2070
1735
|
const notification = {
|
|
@@ -2073,14 +1738,14 @@ function useNotificationHandler({
|
|
|
2073
1738
|
title: (_b = payload.title) != null ? _b : "Notification",
|
|
2074
1739
|
body: payload.body,
|
|
2075
1740
|
handled: false,
|
|
2076
|
-
timestamp:
|
|
1741
|
+
timestamp: Date.now(),
|
|
2077
1742
|
sessionId: event.sessionId
|
|
2078
1743
|
};
|
|
2079
1744
|
setNotifications((prev) => [notification, ...prev]);
|
|
2080
1745
|
onNotification == null ? void 0 : onNotification(notification);
|
|
2081
1746
|
});
|
|
2082
1747
|
return unsubscribe;
|
|
2083
|
-
}, [
|
|
1748
|
+
}, [subscribe, onNotification]);
|
|
2084
1749
|
const unhandledCount = notifications.filter((n) => !n.handled).length;
|
|
2085
1750
|
const markHandled = (0, import_react12.useCallback)((id) => {
|
|
2086
1751
|
setNotifications(
|