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