@aomi-labs/react 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -0
- package/dist/index.cjs +179 -616
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -171
- package/dist/index.d.ts +28 -171
- package/dist/index.js +182 -610
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -18,438 +18,13 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
20
|
|
|
21
|
-
// packages/react/src/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!dataLines.length) return null;
|
|
25
|
-
return dataLines.join("\n");
|
|
26
|
-
}
|
|
27
|
-
async function readSseStream(stream, signal, onMessage) {
|
|
28
|
-
const reader = stream.getReader();
|
|
29
|
-
const decoder = new TextDecoder();
|
|
30
|
-
let buffer = "";
|
|
31
|
-
try {
|
|
32
|
-
while (!signal.aborted) {
|
|
33
|
-
const { value, done } = await reader.read();
|
|
34
|
-
if (done) break;
|
|
35
|
-
buffer += decoder.decode(value, { stream: true });
|
|
36
|
-
buffer = buffer.replace(/\r/g, "");
|
|
37
|
-
let separatorIndex = buffer.indexOf("\n\n");
|
|
38
|
-
while (separatorIndex >= 0) {
|
|
39
|
-
const rawEvent = buffer.slice(0, separatorIndex);
|
|
40
|
-
buffer = buffer.slice(separatorIndex + 2);
|
|
41
|
-
const data = extractSseData(rawEvent);
|
|
42
|
-
if (data) {
|
|
43
|
-
onMessage(data);
|
|
44
|
-
}
|
|
45
|
-
separatorIndex = buffer.indexOf("\n\n");
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
} finally {
|
|
49
|
-
reader.releaseLock();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function createSseSubscriber({
|
|
53
|
-
backendUrl,
|
|
54
|
-
getHeaders,
|
|
55
|
-
shouldLog = process.env.NODE_ENV !== "production"
|
|
56
|
-
}) {
|
|
57
|
-
const subscriptions = /* @__PURE__ */ new Map();
|
|
58
|
-
const subscribe2 = (sessionId, onUpdate, onError) => {
|
|
59
|
-
const existing = subscriptions.get(sessionId);
|
|
60
|
-
const listener = { onUpdate, onError };
|
|
61
|
-
if (existing) {
|
|
62
|
-
existing.listeners.add(listener);
|
|
63
|
-
if (shouldLog) {
|
|
64
|
-
console.debug("[aomi][sse] listener added", {
|
|
65
|
-
sessionId,
|
|
66
|
-
listeners: existing.listeners.size
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
return () => {
|
|
70
|
-
existing.listeners.delete(listener);
|
|
71
|
-
if (shouldLog) {
|
|
72
|
-
console.debug("[aomi][sse] listener removed", {
|
|
73
|
-
sessionId,
|
|
74
|
-
listeners: existing.listeners.size
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
if (existing.listeners.size === 0) {
|
|
78
|
-
existing.stop("unsubscribe");
|
|
79
|
-
if (subscriptions.get(sessionId) === existing) {
|
|
80
|
-
subscriptions.delete(sessionId);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
const subscription = {
|
|
86
|
-
abortController: null,
|
|
87
|
-
retries: 0,
|
|
88
|
-
retryTimer: null,
|
|
89
|
-
stopped: false,
|
|
90
|
-
listeners: /* @__PURE__ */ new Set([listener]),
|
|
91
|
-
stop: (reason) => {
|
|
92
|
-
var _a;
|
|
93
|
-
subscription.stopped = true;
|
|
94
|
-
if (subscription.retryTimer) {
|
|
95
|
-
clearTimeout(subscription.retryTimer);
|
|
96
|
-
subscription.retryTimer = null;
|
|
97
|
-
}
|
|
98
|
-
(_a = subscription.abortController) == null ? void 0 : _a.abort();
|
|
99
|
-
subscription.abortController = null;
|
|
100
|
-
if (shouldLog) {
|
|
101
|
-
console.debug("[aomi][sse] stop", {
|
|
102
|
-
sessionId,
|
|
103
|
-
reason,
|
|
104
|
-
retries: subscription.retries
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const scheduleRetry = () => {
|
|
110
|
-
if (subscription.stopped) return;
|
|
111
|
-
subscription.retries += 1;
|
|
112
|
-
const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 1e4);
|
|
113
|
-
if (shouldLog) {
|
|
114
|
-
console.debug("[aomi][sse] retry scheduled", {
|
|
115
|
-
sessionId,
|
|
116
|
-
delayMs,
|
|
117
|
-
retries: subscription.retries
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
subscription.retryTimer = setTimeout(() => {
|
|
121
|
-
void open();
|
|
122
|
-
}, delayMs);
|
|
123
|
-
};
|
|
124
|
-
const open = async () => {
|
|
125
|
-
var _a;
|
|
126
|
-
if (subscription.stopped) return;
|
|
127
|
-
if (subscription.retryTimer) {
|
|
128
|
-
clearTimeout(subscription.retryTimer);
|
|
129
|
-
subscription.retryTimer = null;
|
|
130
|
-
}
|
|
131
|
-
const controller = new AbortController();
|
|
132
|
-
subscription.abortController = controller;
|
|
133
|
-
const openedAt = Date.now();
|
|
134
|
-
try {
|
|
135
|
-
const response = await fetch(`${backendUrl}/api/updates`, {
|
|
136
|
-
headers: getHeaders(sessionId),
|
|
137
|
-
signal: controller.signal
|
|
138
|
-
});
|
|
139
|
-
if (!response.ok) {
|
|
140
|
-
throw new Error(
|
|
141
|
-
`SSE HTTP ${response.status}: ${response.statusText}`
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
if (!response.body) {
|
|
145
|
-
throw new Error("SSE response missing body");
|
|
146
|
-
}
|
|
147
|
-
subscription.retries = 0;
|
|
148
|
-
await readSseStream(response.body, controller.signal, (data) => {
|
|
149
|
-
var _a2, _b;
|
|
150
|
-
let parsed;
|
|
151
|
-
try {
|
|
152
|
-
parsed = JSON.parse(data);
|
|
153
|
-
} catch (error) {
|
|
154
|
-
for (const item of subscription.listeners) {
|
|
155
|
-
(_a2 = item.onError) == null ? void 0 : _a2.call(item, error);
|
|
156
|
-
}
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
for (const item of subscription.listeners) {
|
|
160
|
-
try {
|
|
161
|
-
item.onUpdate(parsed);
|
|
162
|
-
} catch (error) {
|
|
163
|
-
(_b = item.onError) == null ? void 0 : _b.call(item, error);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
if (shouldLog) {
|
|
168
|
-
console.debug("[aomi][sse] stream ended", {
|
|
169
|
-
sessionId,
|
|
170
|
-
aborted: controller.signal.aborted,
|
|
171
|
-
stopped: subscription.stopped,
|
|
172
|
-
durationMs: Date.now() - openedAt
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
} catch (error) {
|
|
176
|
-
if (!controller.signal.aborted && !subscription.stopped) {
|
|
177
|
-
for (const item of subscription.listeners) {
|
|
178
|
-
(_a = item.onError) == null ? void 0 : _a.call(item, error);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (!subscription.stopped) {
|
|
183
|
-
scheduleRetry();
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
subscriptions.set(sessionId, subscription);
|
|
187
|
-
void open();
|
|
188
|
-
return () => {
|
|
189
|
-
subscription.listeners.delete(listener);
|
|
190
|
-
if (shouldLog) {
|
|
191
|
-
console.debug("[aomi][sse] listener removed", {
|
|
192
|
-
sessionId,
|
|
193
|
-
listeners: subscription.listeners.size
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
if (subscription.listeners.size === 0) {
|
|
197
|
-
subscription.stop("unsubscribe");
|
|
198
|
-
if (subscriptions.get(sessionId) === subscription) {
|
|
199
|
-
subscriptions.delete(sessionId);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
return { subscribe: subscribe2 };
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// packages/react/src/backend/client.ts
|
|
208
|
-
var SESSION_ID_HEADER = "X-Session-Id";
|
|
209
|
-
var API_KEY_HEADER = "X-API-Key";
|
|
210
|
-
function toQueryString(payload) {
|
|
211
|
-
const params = new URLSearchParams();
|
|
212
|
-
for (const [key, value] of Object.entries(payload)) {
|
|
213
|
-
if (value === void 0 || value === null) continue;
|
|
214
|
-
params.set(key, String(value));
|
|
215
|
-
}
|
|
216
|
-
const qs = params.toString();
|
|
217
|
-
return qs ? `?${qs}` : "";
|
|
218
|
-
}
|
|
219
|
-
function withSessionHeader(sessionId, init) {
|
|
220
|
-
const headers = new Headers(init);
|
|
221
|
-
headers.set(SESSION_ID_HEADER, sessionId);
|
|
222
|
-
return headers;
|
|
223
|
-
}
|
|
224
|
-
async function postState(backendUrl, path, payload, sessionId, apiKey) {
|
|
225
|
-
const query = toQueryString(payload);
|
|
226
|
-
const url = `${backendUrl}${path}${query}`;
|
|
227
|
-
const headers = new Headers(withSessionHeader(sessionId));
|
|
228
|
-
if (apiKey) {
|
|
229
|
-
headers.set(API_KEY_HEADER, apiKey);
|
|
230
|
-
}
|
|
231
|
-
const response = await fetch(url, {
|
|
232
|
-
method: "POST",
|
|
233
|
-
headers
|
|
234
|
-
});
|
|
235
|
-
if (!response.ok) {
|
|
236
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
237
|
-
}
|
|
238
|
-
return await response.json();
|
|
239
|
-
}
|
|
240
|
-
var BackendApi = class {
|
|
241
|
-
constructor(backendUrl) {
|
|
242
|
-
this.backendUrl = backendUrl;
|
|
243
|
-
this.sseSubscriber = createSseSubscriber({
|
|
244
|
-
backendUrl,
|
|
245
|
-
getHeaders: (sessionId) => withSessionHeader(sessionId, { Accept: "text/event-stream" })
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
async fetchState(sessionId, userState) {
|
|
249
|
-
const url = new URL("/api/state", this.backendUrl);
|
|
250
|
-
if (userState) {
|
|
251
|
-
url.searchParams.set("user_state", JSON.stringify(userState));
|
|
252
|
-
}
|
|
253
|
-
const response = await fetch(url.toString(), {
|
|
254
|
-
headers: withSessionHeader(sessionId)
|
|
255
|
-
});
|
|
256
|
-
if (!response.ok) {
|
|
257
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
258
|
-
}
|
|
259
|
-
return await response.json();
|
|
260
|
-
}
|
|
261
|
-
async postChatMessage(sessionId, message, namespace, publicKey, apiKey, userState) {
|
|
262
|
-
const payload = { message, namespace };
|
|
263
|
-
if (publicKey) {
|
|
264
|
-
payload.public_key = publicKey;
|
|
265
|
-
}
|
|
266
|
-
if (userState) {
|
|
267
|
-
payload.user_state = JSON.stringify(userState);
|
|
268
|
-
}
|
|
269
|
-
return postState(
|
|
270
|
-
this.backendUrl,
|
|
271
|
-
"/api/chat",
|
|
272
|
-
payload,
|
|
273
|
-
sessionId,
|
|
274
|
-
apiKey
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
async postSystemMessage(sessionId, message) {
|
|
278
|
-
return postState(
|
|
279
|
-
this.backendUrl,
|
|
280
|
-
"/api/system",
|
|
281
|
-
{
|
|
282
|
-
message
|
|
283
|
-
},
|
|
284
|
-
sessionId
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
async postInterrupt(sessionId) {
|
|
288
|
-
return postState(
|
|
289
|
-
this.backendUrl,
|
|
290
|
-
"/api/interrupt",
|
|
291
|
-
{},
|
|
292
|
-
sessionId
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Subscribe to SSE updates for a session.
|
|
297
|
-
* Uses fetch streaming and reconnects on disconnects.
|
|
298
|
-
* Returns an unsubscribe function.
|
|
299
|
-
*/
|
|
300
|
-
subscribeSSE(sessionId, onUpdate, onError) {
|
|
301
|
-
return this.sseSubscriber.subscribe(sessionId, onUpdate, onError);
|
|
302
|
-
}
|
|
303
|
-
async fetchThreads(publicKey) {
|
|
304
|
-
const url = `${this.backendUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
|
|
305
|
-
const response = await fetch(url);
|
|
306
|
-
if (!response.ok) {
|
|
307
|
-
throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
|
|
308
|
-
}
|
|
309
|
-
return await response.json();
|
|
310
|
-
}
|
|
311
|
-
async fetchThread(sessionId) {
|
|
312
|
-
const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
|
|
313
|
-
const response = await fetch(url, {
|
|
314
|
-
headers: withSessionHeader(sessionId)
|
|
315
|
-
});
|
|
316
|
-
if (!response.ok) {
|
|
317
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
318
|
-
}
|
|
319
|
-
return await response.json();
|
|
320
|
-
}
|
|
321
|
-
async createThread(threadId, publicKey) {
|
|
322
|
-
const body = {};
|
|
323
|
-
if (publicKey) body.public_key = publicKey;
|
|
324
|
-
const url = `${this.backendUrl}/api/sessions`;
|
|
325
|
-
const response = await fetch(url, {
|
|
326
|
-
method: "POST",
|
|
327
|
-
headers: withSessionHeader(threadId, {
|
|
328
|
-
"Content-Type": "application/json"
|
|
329
|
-
}),
|
|
330
|
-
body: JSON.stringify(body)
|
|
331
|
-
});
|
|
332
|
-
if (!response.ok) {
|
|
333
|
-
throw new Error(`Failed to create thread: HTTP ${response.status}`);
|
|
334
|
-
}
|
|
335
|
-
return await response.json();
|
|
336
|
-
}
|
|
337
|
-
async archiveThread(sessionId) {
|
|
338
|
-
const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
|
|
339
|
-
const response = await fetch(url, {
|
|
340
|
-
method: "POST",
|
|
341
|
-
headers: withSessionHeader(sessionId)
|
|
342
|
-
});
|
|
343
|
-
if (!response.ok) {
|
|
344
|
-
throw new Error(`Failed to archive thread: HTTP ${response.status}`);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
async unarchiveThread(sessionId) {
|
|
348
|
-
const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
|
|
349
|
-
const response = await fetch(url, {
|
|
350
|
-
method: "POST",
|
|
351
|
-
headers: withSessionHeader(sessionId)
|
|
352
|
-
});
|
|
353
|
-
if (!response.ok) {
|
|
354
|
-
throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
async deleteThread(sessionId) {
|
|
358
|
-
const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
|
|
359
|
-
const response = await fetch(url, {
|
|
360
|
-
method: "DELETE",
|
|
361
|
-
headers: withSessionHeader(sessionId)
|
|
362
|
-
});
|
|
363
|
-
if (!response.ok) {
|
|
364
|
-
throw new Error(`Failed to delete thread: HTTP ${response.status}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
async renameThread(sessionId, newTitle) {
|
|
368
|
-
const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
|
|
369
|
-
const response = await fetch(url, {
|
|
370
|
-
method: "PATCH",
|
|
371
|
-
headers: withSessionHeader(sessionId, {
|
|
372
|
-
"Content-Type": "application/json"
|
|
373
|
-
}),
|
|
374
|
-
body: JSON.stringify({ title: newTitle })
|
|
375
|
-
});
|
|
376
|
-
if (!response.ok) {
|
|
377
|
-
throw new Error(`Failed to rename thread: HTTP ${response.status}`);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
async getSystemEvents(sessionId, count) {
|
|
381
|
-
const url = new URL("/api/events", this.backendUrl);
|
|
382
|
-
if (count !== void 0) {
|
|
383
|
-
url.searchParams.set("count", String(count));
|
|
384
|
-
}
|
|
385
|
-
const response = await fetch(url.toString(), {
|
|
386
|
-
headers: withSessionHeader(sessionId)
|
|
387
|
-
});
|
|
388
|
-
if (!response.ok) {
|
|
389
|
-
if (response.status === 404) return [];
|
|
390
|
-
throw new Error(`Failed to get system events: HTTP ${response.status}`);
|
|
391
|
-
}
|
|
392
|
-
return await response.json();
|
|
393
|
-
}
|
|
394
|
-
// ===========================================================================
|
|
395
|
-
// Control API
|
|
396
|
-
// ===========================================================================
|
|
397
|
-
/**
|
|
398
|
-
* Get allowed namespaces for the current request context.
|
|
399
|
-
*/
|
|
400
|
-
async getNamespaces(sessionId, publicKey, apiKey) {
|
|
401
|
-
const url = new URL("/api/control/namespaces", this.backendUrl);
|
|
402
|
-
if (publicKey) {
|
|
403
|
-
url.searchParams.set("public_key", publicKey);
|
|
404
|
-
}
|
|
405
|
-
console.log("[BackendApi.getNamespaces]", {
|
|
406
|
-
backendUrl: this.backendUrl,
|
|
407
|
-
fullUrl: url.toString(),
|
|
408
|
-
sessionId,
|
|
409
|
-
publicKey
|
|
410
|
-
});
|
|
411
|
-
const headers = new Headers(withSessionHeader(sessionId));
|
|
412
|
-
if (apiKey) {
|
|
413
|
-
headers.set(API_KEY_HEADER, apiKey);
|
|
414
|
-
}
|
|
415
|
-
const response = await fetch(url.toString(), { headers });
|
|
416
|
-
if (!response.ok) {
|
|
417
|
-
throw new Error(`Failed to get namespaces: HTTP ${response.status}`);
|
|
418
|
-
}
|
|
419
|
-
return await response.json();
|
|
420
|
-
}
|
|
421
|
-
/**
|
|
422
|
-
* Get available models.
|
|
423
|
-
*/
|
|
424
|
-
async getModels(sessionId) {
|
|
425
|
-
const url = new URL("/api/control/models", this.backendUrl);
|
|
426
|
-
console.log("[BackendApi.getModels]", {
|
|
427
|
-
backendUrl: this.backendUrl,
|
|
428
|
-
fullUrl: url.toString(),
|
|
429
|
-
sessionId
|
|
430
|
-
});
|
|
431
|
-
const response = await fetch(url.toString(), {
|
|
432
|
-
headers: withSessionHeader(sessionId)
|
|
433
|
-
});
|
|
434
|
-
if (!response.ok) {
|
|
435
|
-
throw new Error(`Failed to get models: HTTP ${response.status}`);
|
|
436
|
-
}
|
|
437
|
-
return await response.json();
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Set the model selection for a session.
|
|
441
|
-
*/
|
|
442
|
-
async setModel(sessionId, rig, namespace, apiKey) {
|
|
443
|
-
const payload = { rig };
|
|
444
|
-
if (namespace) {
|
|
445
|
-
payload.namespace = namespace;
|
|
446
|
-
}
|
|
447
|
-
return postState(this.backendUrl, "/api/control/model", payload, sessionId, apiKey);
|
|
448
|
-
}
|
|
449
|
-
};
|
|
21
|
+
// packages/react/src/index.ts
|
|
22
|
+
import { AomiClient as AomiClient2 } from "@aomi-labs/client";
|
|
23
|
+
import { toViemSignTypedDataArgs } from "@aomi-labs/client";
|
|
450
24
|
|
|
451
25
|
// packages/react/src/runtime/aomi-runtime.tsx
|
|
452
26
|
import { useMemo as useMemo3 } from "react";
|
|
27
|
+
import { AomiClient } from "@aomi-labs/client";
|
|
453
28
|
|
|
454
29
|
// packages/react/src/contexts/control-context.tsx
|
|
455
30
|
import {
|
|
@@ -489,7 +64,7 @@ var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
|
489
64
|
function initThreadControl() {
|
|
490
65
|
return {
|
|
491
66
|
model: null,
|
|
492
|
-
|
|
67
|
+
app: null,
|
|
493
68
|
controlDirty: false,
|
|
494
69
|
isProcessing: false
|
|
495
70
|
};
|
|
@@ -635,6 +210,16 @@ var ThreadStore = class {
|
|
|
635
210
|
// packages/react/src/contexts/control-context.tsx
|
|
636
211
|
import { jsx } from "react/jsx-runtime";
|
|
637
212
|
var API_KEY_STORAGE_KEY = "aomi_api_key";
|
|
213
|
+
function getDefaultApp(apps) {
|
|
214
|
+
var _a;
|
|
215
|
+
return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
|
|
216
|
+
}
|
|
217
|
+
function resolveAuthorizedApp(app, authorizedApps, defaultApp) {
|
|
218
|
+
if (app && authorizedApps.includes(app)) {
|
|
219
|
+
return app;
|
|
220
|
+
}
|
|
221
|
+
return defaultApp;
|
|
222
|
+
}
|
|
638
223
|
var ControlContext = createContext(null);
|
|
639
224
|
function useControl() {
|
|
640
225
|
const ctx = useContext(ControlContext);
|
|
@@ -645,7 +230,7 @@ function useControl() {
|
|
|
645
230
|
}
|
|
646
231
|
function ControlContextProvider({
|
|
647
232
|
children,
|
|
648
|
-
|
|
233
|
+
aomiClient,
|
|
649
234
|
sessionId,
|
|
650
235
|
publicKey,
|
|
651
236
|
getThreadMetadata,
|
|
@@ -655,14 +240,14 @@ function ControlContextProvider({
|
|
|
655
240
|
const [state, setStateInternal] = useState(() => ({
|
|
656
241
|
apiKey: null,
|
|
657
242
|
availableModels: [],
|
|
658
|
-
|
|
243
|
+
authorizedApps: [],
|
|
659
244
|
defaultModel: null,
|
|
660
|
-
|
|
245
|
+
defaultApp: null
|
|
661
246
|
}));
|
|
662
247
|
const stateRef = useRef(state);
|
|
663
248
|
stateRef.current = state;
|
|
664
|
-
const
|
|
665
|
-
|
|
249
|
+
const aomiClientRef = useRef(aomiClient);
|
|
250
|
+
aomiClientRef.current = aomiClient;
|
|
666
251
|
const sessionIdRef = useRef(sessionId);
|
|
667
252
|
sessionIdRef.current = sessionId;
|
|
668
253
|
const publicKeyRef = useRef(publicKey);
|
|
@@ -696,33 +281,35 @@ function ControlContextProvider({
|
|
|
696
281
|
}
|
|
697
282
|
}, [state.apiKey]);
|
|
698
283
|
useEffect(() => {
|
|
699
|
-
const
|
|
700
|
-
var _a2
|
|
284
|
+
const fetchApps = async () => {
|
|
285
|
+
var _a2;
|
|
701
286
|
try {
|
|
702
|
-
const
|
|
287
|
+
const apps = await aomiClientRef.current.getApps(
|
|
703
288
|
sessionIdRef.current,
|
|
704
|
-
|
|
705
|
-
|
|
289
|
+
{
|
|
290
|
+
publicKey: publicKeyRef.current,
|
|
291
|
+
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
292
|
+
}
|
|
706
293
|
);
|
|
707
|
-
const
|
|
294
|
+
const defaultApp = getDefaultApp(apps);
|
|
708
295
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
709
|
-
|
|
710
|
-
|
|
296
|
+
authorizedApps: apps,
|
|
297
|
+
defaultApp
|
|
711
298
|
}));
|
|
712
299
|
} catch (error) {
|
|
713
|
-
console.error("Failed to fetch
|
|
300
|
+
console.error("Failed to fetch apps:", error);
|
|
714
301
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
715
|
-
|
|
716
|
-
|
|
302
|
+
authorizedApps: ["default"],
|
|
303
|
+
defaultApp: "default"
|
|
717
304
|
}));
|
|
718
305
|
}
|
|
719
306
|
};
|
|
720
|
-
void
|
|
721
|
-
}, [state.apiKey]);
|
|
307
|
+
void fetchApps();
|
|
308
|
+
}, [state.apiKey, publicKey, sessionId]);
|
|
722
309
|
useEffect(() => {
|
|
723
310
|
const fetchModels = async () => {
|
|
724
311
|
try {
|
|
725
|
-
const models = await
|
|
312
|
+
const models = await aomiClientRef.current.getModels(
|
|
726
313
|
sessionIdRef.current
|
|
727
314
|
);
|
|
728
315
|
setStateInternal((prev) => {
|
|
@@ -747,7 +334,7 @@ function ControlContextProvider({
|
|
|
747
334
|
}, []);
|
|
748
335
|
const getAvailableModels = useCallback(async () => {
|
|
749
336
|
try {
|
|
750
|
-
const models = await
|
|
337
|
+
const models = await aomiClientRef.current.getModels(
|
|
751
338
|
sessionIdRef.current
|
|
752
339
|
);
|
|
753
340
|
setStateInternal((prev) => {
|
|
@@ -763,25 +350,27 @@ function ControlContextProvider({
|
|
|
763
350
|
return [];
|
|
764
351
|
}
|
|
765
352
|
}, []);
|
|
766
|
-
const
|
|
767
|
-
var _a2
|
|
353
|
+
const getAuthorizedApps = useCallback(async () => {
|
|
354
|
+
var _a2;
|
|
768
355
|
try {
|
|
769
|
-
const
|
|
356
|
+
const apps = await aomiClientRef.current.getApps(
|
|
770
357
|
sessionIdRef.current,
|
|
771
|
-
|
|
772
|
-
|
|
358
|
+
{
|
|
359
|
+
publicKey: publicKeyRef.current,
|
|
360
|
+
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
361
|
+
}
|
|
773
362
|
);
|
|
774
|
-
const
|
|
363
|
+
const defaultApp = getDefaultApp(apps);
|
|
775
364
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
776
|
-
|
|
777
|
-
|
|
365
|
+
authorizedApps: apps,
|
|
366
|
+
defaultApp
|
|
778
367
|
}));
|
|
779
|
-
return
|
|
368
|
+
return apps;
|
|
780
369
|
} catch (error) {
|
|
781
|
-
console.error("Failed to fetch
|
|
370
|
+
console.error("Failed to fetch apps:", error);
|
|
782
371
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
783
|
-
|
|
784
|
-
|
|
372
|
+
authorizedApps: ["default"],
|
|
373
|
+
defaultApp: "default"
|
|
785
374
|
}));
|
|
786
375
|
return ["default"];
|
|
787
376
|
}
|
|
@@ -791,8 +380,17 @@ function ControlContextProvider({
|
|
|
791
380
|
const metadata = getThreadMetadataRef.current(sessionIdRef.current);
|
|
792
381
|
return (_a2 = metadata == null ? void 0 : metadata.control) != null ? _a2 : initThreadControl();
|
|
793
382
|
}, []);
|
|
383
|
+
const getCurrentThreadApp = useCallback(() => {
|
|
384
|
+
var _a2, _b2, _c;
|
|
385
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(sessionIdRef.current)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
386
|
+
return (_c = resolveAuthorizedApp(
|
|
387
|
+
currentControl.app,
|
|
388
|
+
stateRef.current.authorizedApps,
|
|
389
|
+
stateRef.current.defaultApp
|
|
390
|
+
)) != null ? _c : "default";
|
|
391
|
+
}, []);
|
|
794
392
|
const onModelSelect = useCallback(async (model) => {
|
|
795
|
-
var _a2, _b2, _c, _d
|
|
393
|
+
var _a2, _b2, _c, _d;
|
|
796
394
|
const threadId = sessionIdRef.current;
|
|
797
395
|
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
798
396
|
const isProcessing2 = currentControl.isProcessing;
|
|
@@ -805,32 +403,35 @@ function ControlContextProvider({
|
|
|
805
403
|
console.warn("[control-context] Cannot switch model while processing");
|
|
806
404
|
return;
|
|
807
405
|
}
|
|
808
|
-
const
|
|
406
|
+
const app = (_c = resolveAuthorizedApp(
|
|
407
|
+
currentControl.app,
|
|
408
|
+
stateRef.current.authorizedApps,
|
|
409
|
+
stateRef.current.defaultApp
|
|
410
|
+
)) != null ? _c : "default";
|
|
809
411
|
console.log("[control-context] onModelSelect updating metadata", {
|
|
810
412
|
threadId,
|
|
811
413
|
model,
|
|
812
|
-
|
|
414
|
+
app,
|
|
813
415
|
currentControl
|
|
814
416
|
});
|
|
815
417
|
updateThreadMetadataRef.current(threadId, {
|
|
816
418
|
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
817
419
|
model,
|
|
818
|
-
|
|
420
|
+
app,
|
|
819
421
|
controlDirty: true
|
|
820
422
|
})
|
|
821
423
|
});
|
|
822
424
|
console.log("[control-context] onModelSelect calling backend setModel", {
|
|
823
425
|
threadId,
|
|
824
426
|
model,
|
|
825
|
-
|
|
826
|
-
backendUrl:
|
|
427
|
+
app,
|
|
428
|
+
backendUrl: aomiClientRef.current
|
|
827
429
|
});
|
|
828
430
|
try {
|
|
829
|
-
const result = await
|
|
431
|
+
const result = await aomiClientRef.current.setModel(
|
|
830
432
|
threadId,
|
|
831
433
|
model,
|
|
832
|
-
|
|
833
|
-
(_e = stateRef.current.apiKey) != null ? _e : void 0
|
|
434
|
+
{ app, apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0 }
|
|
834
435
|
);
|
|
835
436
|
console.log("[control-context] onModelSelect backend result", result);
|
|
836
437
|
} catch (err) {
|
|
@@ -838,34 +439,38 @@ function ControlContextProvider({
|
|
|
838
439
|
throw err;
|
|
839
440
|
}
|
|
840
441
|
}, []);
|
|
841
|
-
const
|
|
442
|
+
const onAppSelect = useCallback((app) => {
|
|
842
443
|
var _a2, _b2;
|
|
843
444
|
const threadId = sessionIdRef.current;
|
|
844
445
|
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
845
446
|
const isProcessing2 = currentControl.isProcessing;
|
|
846
|
-
console.log("[control-context]
|
|
847
|
-
|
|
447
|
+
console.log("[control-context] onAppSelect called", {
|
|
448
|
+
app,
|
|
848
449
|
isProcessing: isProcessing2,
|
|
849
450
|
threadId
|
|
850
451
|
});
|
|
851
452
|
if (isProcessing2) {
|
|
852
453
|
console.warn(
|
|
853
|
-
"[control-context] Cannot switch
|
|
454
|
+
"[control-context] Cannot switch app while processing"
|
|
854
455
|
);
|
|
855
456
|
return;
|
|
856
457
|
}
|
|
857
|
-
|
|
458
|
+
if (stateRef.current.authorizedApps.length > 0 && !stateRef.current.authorizedApps.includes(app)) {
|
|
459
|
+
console.warn("[control-context] Cannot select unauthorized app", { app });
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
console.log("[control-context] onAppSelect updating metadata", {
|
|
858
463
|
threadId,
|
|
859
|
-
|
|
464
|
+
app,
|
|
860
465
|
currentControl
|
|
861
466
|
});
|
|
862
467
|
updateThreadMetadataRef.current(threadId, {
|
|
863
468
|
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
864
|
-
|
|
469
|
+
app,
|
|
865
470
|
controlDirty: true
|
|
866
471
|
})
|
|
867
472
|
});
|
|
868
|
-
console.log("[control-context]
|
|
473
|
+
console.log("[control-context] onAppSelect metadata updated");
|
|
869
474
|
}, []);
|
|
870
475
|
const markControlSynced = useCallback(() => {
|
|
871
476
|
var _a2, _b2;
|
|
@@ -895,11 +500,11 @@ function ControlContextProvider({
|
|
|
895
500
|
if ("apiKey" in updates) {
|
|
896
501
|
setApiKey((_a2 = updates.apiKey) != null ? _a2 : null);
|
|
897
502
|
}
|
|
898
|
-
if ("
|
|
899
|
-
|
|
503
|
+
if ("app" in updates && updates.app !== void 0 && updates.app !== null) {
|
|
504
|
+
onAppSelect(updates.app);
|
|
900
505
|
}
|
|
901
506
|
},
|
|
902
|
-
[setApiKey,
|
|
507
|
+
[setApiKey, onAppSelect]
|
|
903
508
|
);
|
|
904
509
|
return /* @__PURE__ */ jsx(
|
|
905
510
|
ControlContext.Provider,
|
|
@@ -908,10 +513,11 @@ function ControlContextProvider({
|
|
|
908
513
|
state,
|
|
909
514
|
setApiKey,
|
|
910
515
|
getAvailableModels,
|
|
911
|
-
|
|
516
|
+
getAuthorizedApps,
|
|
912
517
|
getCurrentThreadControl,
|
|
518
|
+
getCurrentThreadApp,
|
|
913
519
|
onModelSelect,
|
|
914
|
-
|
|
520
|
+
onAppSelect,
|
|
915
521
|
isProcessing,
|
|
916
522
|
markControlSynced,
|
|
917
523
|
getControlState,
|
|
@@ -932,20 +538,12 @@ import {
|
|
|
932
538
|
useRef as useRef2,
|
|
933
539
|
useState as useState2
|
|
934
540
|
} from "react";
|
|
935
|
-
|
|
936
|
-
|
|
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
|
-
}
|
|
541
|
+
import {
|
|
542
|
+
isInlineCall,
|
|
543
|
+
isSystemNotice,
|
|
544
|
+
isSystemError,
|
|
545
|
+
isAsyncCallback
|
|
546
|
+
} from "@aomi-labs/client";
|
|
949
547
|
|
|
950
548
|
// packages/react/src/state/event-buffer.ts
|
|
951
549
|
function createEventBuffer() {
|
|
@@ -1005,7 +603,7 @@ function useEventContext() {
|
|
|
1005
603
|
}
|
|
1006
604
|
function EventContextProvider({
|
|
1007
605
|
children,
|
|
1008
|
-
|
|
606
|
+
aomiClient,
|
|
1009
607
|
sessionId
|
|
1010
608
|
}) {
|
|
1011
609
|
const bufferRef = useRef2(null);
|
|
@@ -1017,7 +615,7 @@ function EventContextProvider({
|
|
|
1017
615
|
useEffect2(() => {
|
|
1018
616
|
setSSEStatus(buffer, "connecting");
|
|
1019
617
|
setSseStatus("connecting");
|
|
1020
|
-
const unsubscribe =
|
|
618
|
+
const unsubscribe = aomiClient.subscribeSSE(
|
|
1021
619
|
sessionId,
|
|
1022
620
|
(event) => {
|
|
1023
621
|
enqueueInbound(buffer, {
|
|
@@ -1047,7 +645,7 @@ function EventContextProvider({
|
|
|
1047
645
|
setSSEStatus(buffer, "disconnected");
|
|
1048
646
|
setSseStatus("disconnected");
|
|
1049
647
|
};
|
|
1050
|
-
}, [
|
|
648
|
+
}, [aomiClient, sessionId, buffer]);
|
|
1051
649
|
const subscribeCallback = useCallback2(
|
|
1052
650
|
(type, callback) => {
|
|
1053
651
|
return subscribe(buffer, type, callback);
|
|
@@ -1061,12 +659,12 @@ function EventContextProvider({
|
|
|
1061
659
|
type: event.type,
|
|
1062
660
|
payload: event.payload
|
|
1063
661
|
});
|
|
1064
|
-
await
|
|
662
|
+
await aomiClient.sendSystemMessage(event.sessionId, message);
|
|
1065
663
|
} catch (error) {
|
|
1066
664
|
console.error("Failed to send outbound event:", error);
|
|
1067
665
|
}
|
|
1068
666
|
},
|
|
1069
|
-
[
|
|
667
|
+
[aomiClient]
|
|
1070
668
|
);
|
|
1071
669
|
const dispatchSystemEvents = useCallback2(
|
|
1072
670
|
(sessionId2, events) => {
|
|
@@ -1452,19 +1050,16 @@ var MessageController = class {
|
|
|
1452
1050
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1453
1051
|
});
|
|
1454
1052
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1455
|
-
const
|
|
1053
|
+
const app = this.config.getApp();
|
|
1456
1054
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1457
1055
|
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1458
1056
|
const userState = (_g = (_f = this.config).getUserState) == null ? void 0 : _g.call(_f);
|
|
1459
1057
|
try {
|
|
1460
1058
|
this.markRunning(threadId, true);
|
|
1461
|
-
const response = await this.config.
|
|
1059
|
+
const response = await this.config.aomiClientRef.current.sendMessage(
|
|
1462
1060
|
backendThreadId,
|
|
1463
1061
|
text,
|
|
1464
|
-
|
|
1465
|
-
publicKey,
|
|
1466
|
-
apiKey,
|
|
1467
|
-
userState
|
|
1062
|
+
{ app, publicKey, apiKey, userState }
|
|
1468
1063
|
);
|
|
1469
1064
|
if (response == null ? void 0 : response.messages) {
|
|
1470
1065
|
this.inbound(threadId, response.messages);
|
|
@@ -1488,7 +1083,7 @@ var MessageController = class {
|
|
|
1488
1083
|
const backendState = this.config.backendStateRef.current;
|
|
1489
1084
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1490
1085
|
try {
|
|
1491
|
-
const response = await this.config.
|
|
1086
|
+
const response = await this.config.aomiClientRef.current.interrupt(backendThreadId);
|
|
1492
1087
|
if (response == null ? void 0 : response.messages) {
|
|
1493
1088
|
this.inbound(threadId, response.messages);
|
|
1494
1089
|
}
|
|
@@ -1536,7 +1131,7 @@ var PollingController = class {
|
|
|
1536
1131
|
threadId
|
|
1537
1132
|
);
|
|
1538
1133
|
const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
|
|
1539
|
-
const state = await this.config.
|
|
1134
|
+
const state = await this.config.aomiClientRef.current.fetchState(
|
|
1540
1135
|
backendThreadId,
|
|
1541
1136
|
userState
|
|
1542
1137
|
);
|
|
@@ -1584,12 +1179,12 @@ var PollingController = class {
|
|
|
1584
1179
|
};
|
|
1585
1180
|
|
|
1586
1181
|
// packages/react/src/runtime/orchestrator.ts
|
|
1587
|
-
function useRuntimeOrchestrator(
|
|
1182
|
+
function useRuntimeOrchestrator(aomiClient, options) {
|
|
1588
1183
|
const threadContext = useThreadContext();
|
|
1589
1184
|
const threadContextRef = useRef5(threadContext);
|
|
1590
1185
|
threadContextRef.current = threadContext;
|
|
1591
|
-
const
|
|
1592
|
-
|
|
1186
|
+
const aomiClientRef = useRef5(aomiClient);
|
|
1187
|
+
aomiClientRef.current = aomiClient;
|
|
1593
1188
|
const backendStateRef = useRef5(createBackendState());
|
|
1594
1189
|
const [isRunning, setIsRunning] = useState5(false);
|
|
1595
1190
|
const messageControllerRef = useRef5(null);
|
|
@@ -1597,7 +1192,7 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1597
1192
|
const pendingFetches = useRef5(/* @__PURE__ */ new Set());
|
|
1598
1193
|
if (!pollingRef.current) {
|
|
1599
1194
|
pollingRef.current = new PollingController({
|
|
1600
|
-
|
|
1195
|
+
aomiClientRef,
|
|
1601
1196
|
backendStateRef,
|
|
1602
1197
|
applyMessages: (threadId, msgs) => {
|
|
1603
1198
|
var _a;
|
|
@@ -1619,13 +1214,13 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1619
1214
|
}
|
|
1620
1215
|
if (!messageControllerRef.current) {
|
|
1621
1216
|
messageControllerRef.current = new MessageController({
|
|
1622
|
-
|
|
1217
|
+
aomiClientRef,
|
|
1623
1218
|
backendStateRef,
|
|
1624
1219
|
threadContextRef,
|
|
1625
1220
|
polling: pollingRef.current,
|
|
1626
1221
|
setGlobalIsRunning: setIsRunning,
|
|
1627
1222
|
getPublicKey: options.getPublicKey,
|
|
1628
|
-
|
|
1223
|
+
getApp: options.getApp,
|
|
1629
1224
|
getApiKey: options.getApiKey,
|
|
1630
1225
|
getUserState: options.getUserState,
|
|
1631
1226
|
onSyncEvents: options.onSyncEvents
|
|
@@ -1638,7 +1233,7 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1638
1233
|
pendingFetches.current.add(threadId);
|
|
1639
1234
|
try {
|
|
1640
1235
|
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1641
|
-
const state = await
|
|
1236
|
+
const state = await aomiClientRef.current.fetchState(
|
|
1642
1237
|
backendThreadId,
|
|
1643
1238
|
userState
|
|
1644
1239
|
);
|
|
@@ -1670,7 +1265,7 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1670
1265
|
isRunning,
|
|
1671
1266
|
setIsRunning,
|
|
1672
1267
|
ensureInitialState,
|
|
1673
|
-
|
|
1268
|
+
aomiClientRef
|
|
1674
1269
|
};
|
|
1675
1270
|
}
|
|
1676
1271
|
|
|
@@ -1701,7 +1296,7 @@ function buildThreadLists(threadMetadata) {
|
|
|
1701
1296
|
return { regularThreads, archivedThreads };
|
|
1702
1297
|
}
|
|
1703
1298
|
function buildThreadListAdapter({
|
|
1704
|
-
|
|
1299
|
+
aomiClientRef,
|
|
1705
1300
|
threadContext,
|
|
1706
1301
|
setIsRunning
|
|
1707
1302
|
}) {
|
|
@@ -1729,6 +1324,7 @@ function buildThreadListAdapter({
|
|
|
1729
1324
|
},
|
|
1730
1325
|
onSwitchToThread: (threadId) => {
|
|
1731
1326
|
threadContext.setCurrentThreadId(threadId);
|
|
1327
|
+
threadContext.bumpThreadViewKey();
|
|
1732
1328
|
},
|
|
1733
1329
|
onRename: async (threadId, newTitle) => {
|
|
1734
1330
|
var _a, _b;
|
|
@@ -1738,7 +1334,7 @@ function buildThreadListAdapter({
|
|
|
1738
1334
|
title: normalizedTitle
|
|
1739
1335
|
});
|
|
1740
1336
|
try {
|
|
1741
|
-
await
|
|
1337
|
+
await aomiClientRef.current.renameThread(threadId, newTitle);
|
|
1742
1338
|
} catch (error) {
|
|
1743
1339
|
console.error("Failed to rename thread:", error);
|
|
1744
1340
|
threadContext.updateThreadMetadata(threadId, {
|
|
@@ -1749,7 +1345,7 @@ function buildThreadListAdapter({
|
|
|
1749
1345
|
onArchive: async (threadId) => {
|
|
1750
1346
|
threadContext.updateThreadMetadata(threadId, { status: "archived" });
|
|
1751
1347
|
try {
|
|
1752
|
-
await
|
|
1348
|
+
await aomiClientRef.current.archiveThread(threadId);
|
|
1753
1349
|
} catch (error) {
|
|
1754
1350
|
console.error("Failed to archive thread:", error);
|
|
1755
1351
|
threadContext.updateThreadMetadata(threadId, { status: "regular" });
|
|
@@ -1758,7 +1354,7 @@ function buildThreadListAdapter({
|
|
|
1758
1354
|
onUnarchive: async (threadId) => {
|
|
1759
1355
|
threadContext.updateThreadMetadata(threadId, { status: "regular" });
|
|
1760
1356
|
try {
|
|
1761
|
-
await
|
|
1357
|
+
await aomiClientRef.current.unarchiveThread(threadId);
|
|
1762
1358
|
} catch (error) {
|
|
1763
1359
|
console.error("Failed to unarchive thread:", error);
|
|
1764
1360
|
threadContext.updateThreadMetadata(threadId, { status: "archived" });
|
|
@@ -1766,7 +1362,7 @@ function buildThreadListAdapter({
|
|
|
1766
1362
|
},
|
|
1767
1363
|
onDelete: async (threadId) => {
|
|
1768
1364
|
try {
|
|
1769
|
-
await
|
|
1365
|
+
await aomiClientRef.current.deleteThread(threadId);
|
|
1770
1366
|
threadContext.setThreadMetadata((prev) => {
|
|
1771
1367
|
const next = new Map(prev);
|
|
1772
1368
|
next.delete(threadId);
|
|
@@ -1821,6 +1417,10 @@ function useAomiRuntime() {
|
|
|
1821
1417
|
|
|
1822
1418
|
// packages/react/src/handlers/wallet-handler.ts
|
|
1823
1419
|
import { useCallback as useCallback6, useEffect as useEffect3, useRef as useRef6, useState as useState6 } from "react";
|
|
1420
|
+
import {
|
|
1421
|
+
normalizeEip712Payload,
|
|
1422
|
+
normalizeTxPayload
|
|
1423
|
+
} from "@aomi-labs/client";
|
|
1824
1424
|
|
|
1825
1425
|
// packages/react/src/state/wallet-buffer.ts
|
|
1826
1426
|
function createWalletBuffer() {
|
|
@@ -1867,7 +1467,11 @@ function useWalletHandler({
|
|
|
1867
1467
|
const unsubscribe = subscribe2(
|
|
1868
1468
|
"wallet_tx_request",
|
|
1869
1469
|
(event) => {
|
|
1870
|
-
const payload = event.payload;
|
|
1470
|
+
const payload = normalizeTxPayload(event.payload);
|
|
1471
|
+
if (!payload) {
|
|
1472
|
+
console.warn("[aomi][wallet] Ignoring tx request with invalid payload", event.payload);
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1871
1475
|
enqueue(bufferRef.current, "transaction", payload);
|
|
1872
1476
|
syncState();
|
|
1873
1477
|
}
|
|
@@ -1879,7 +1483,7 @@ function useWalletHandler({
|
|
|
1879
1483
|
"wallet_eip712_request",
|
|
1880
1484
|
(event) => {
|
|
1881
1485
|
var _a;
|
|
1882
|
-
const payload = (_a = event.payload) != null ? _a : {};
|
|
1486
|
+
const payload = normalizeEip712Payload((_a = event.payload) != null ? _a : {});
|
|
1883
1487
|
enqueue(bufferRef.current, "eip712_sign", payload);
|
|
1884
1488
|
syncState();
|
|
1885
1489
|
}
|
|
@@ -1969,14 +1573,14 @@ function useWalletHandler({
|
|
|
1969
1573
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1970
1574
|
function AomiRuntimeCore({
|
|
1971
1575
|
children,
|
|
1972
|
-
|
|
1576
|
+
aomiClient
|
|
1973
1577
|
}) {
|
|
1974
1578
|
const threadContext = useThreadContext();
|
|
1975
1579
|
const eventContext = useEventContext();
|
|
1976
1580
|
const notificationContext = useNotification();
|
|
1977
1581
|
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1978
1582
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1979
|
-
const { getControlState,
|
|
1583
|
+
const { getControlState, getCurrentThreadApp } = useControl();
|
|
1980
1584
|
const {
|
|
1981
1585
|
backendStateRef,
|
|
1982
1586
|
polling,
|
|
@@ -1984,15 +1588,12 @@ function AomiRuntimeCore({
|
|
|
1984
1588
|
isRunning,
|
|
1985
1589
|
setIsRunning,
|
|
1986
1590
|
ensureInitialState,
|
|
1987
|
-
|
|
1988
|
-
} = useRuntimeOrchestrator(
|
|
1591
|
+
aomiClientRef
|
|
1592
|
+
} = useRuntimeOrchestrator(aomiClient, {
|
|
1989
1593
|
onSyncEvents: dispatchSystemEvents,
|
|
1990
1594
|
getPublicKey: () => getUserState().address,
|
|
1991
1595
|
getUserState,
|
|
1992
|
-
|
|
1993
|
-
var _a, _b;
|
|
1994
|
-
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
1995
|
-
},
|
|
1596
|
+
getApp: getCurrentThreadApp,
|
|
1996
1597
|
getApiKey: () => getControlState().apiKey
|
|
1997
1598
|
});
|
|
1998
1599
|
useEffect4(() => {
|
|
@@ -2007,10 +1608,10 @@ function AomiRuntimeCore({
|
|
|
2007
1608
|
ensName: newUser.ensName
|
|
2008
1609
|
}
|
|
2009
1610
|
});
|
|
2010
|
-
await
|
|
1611
|
+
await aomiClientRef.current.sendSystemMessage(sessionId, message);
|
|
2011
1612
|
});
|
|
2012
1613
|
return unsubscribe;
|
|
2013
|
-
}, [onUserStateChange,
|
|
1614
|
+
}, [onUserStateChange, aomiClientRef, threadContext.currentThreadId]);
|
|
2014
1615
|
const threadContextRef = useRef7(threadContext);
|
|
2015
1616
|
threadContextRef.current = threadContext;
|
|
2016
1617
|
const currentThreadIdRef = useRef7(threadContext.currentThreadId);
|
|
@@ -2058,21 +1659,13 @@ function AomiRuntimeCore({
|
|
|
2058
1659
|
const currentMessages = threadContext.getThreadMessages(
|
|
2059
1660
|
threadContext.currentThreadId
|
|
2060
1661
|
);
|
|
2061
|
-
const resolvedSessionId = useMemo2(
|
|
2062
|
-
() => resolveThreadId(backendStateRef.current, threadContext.currentThreadId),
|
|
2063
|
-
[
|
|
2064
|
-
backendStateRef,
|
|
2065
|
-
threadContext.currentThreadId,
|
|
2066
|
-
threadContext.allThreadsMetadata
|
|
2067
|
-
]
|
|
2068
|
-
);
|
|
2069
1662
|
useEffect4(() => {
|
|
2070
1663
|
const userAddress = user.address;
|
|
2071
1664
|
if (!userAddress) return;
|
|
2072
1665
|
const fetchThreadList = async () => {
|
|
2073
1666
|
var _a, _b, _c;
|
|
2074
1667
|
try {
|
|
2075
|
-
const threadList = await
|
|
1668
|
+
const threadList = await aomiClientRef.current.listThreads(userAddress);
|
|
2076
1669
|
const currentContext = threadContextRef.current;
|
|
2077
1670
|
const newMetadata = new Map(currentContext.allThreadsMetadata);
|
|
2078
1671
|
let maxChatNum = currentContext.threadCnt;
|
|
@@ -2104,25 +1697,22 @@ function AomiRuntimeCore({
|
|
|
2104
1697
|
}
|
|
2105
1698
|
};
|
|
2106
1699
|
void fetchThreadList();
|
|
2107
|
-
}, [user.address,
|
|
1700
|
+
}, [user.address, aomiClientRef]);
|
|
2108
1701
|
const threadListAdapter = useMemo2(
|
|
2109
1702
|
() => buildThreadListAdapter({
|
|
2110
1703
|
backendStateRef,
|
|
2111
|
-
|
|
1704
|
+
aomiClientRef,
|
|
2112
1705
|
threadContext,
|
|
2113
1706
|
currentThreadIdRef,
|
|
2114
1707
|
polling,
|
|
2115
1708
|
userAddress: user.address,
|
|
2116
1709
|
setIsRunning,
|
|
2117
|
-
|
|
2118
|
-
var _a, _b;
|
|
2119
|
-
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
2120
|
-
},
|
|
1710
|
+
getApp: getCurrentThreadApp,
|
|
2121
1711
|
getApiKey: () => getControlState().apiKey,
|
|
2122
1712
|
getUserState
|
|
2123
1713
|
}),
|
|
2124
1714
|
[
|
|
2125
|
-
|
|
1715
|
+
aomiClientRef,
|
|
2126
1716
|
polling,
|
|
2127
1717
|
user.address,
|
|
2128
1718
|
backendStateRef,
|
|
@@ -2131,63 +1721,44 @@ function AomiRuntimeCore({
|
|
|
2131
1721
|
threadContext.currentThreadId,
|
|
2132
1722
|
threadContext.allThreadsMetadata,
|
|
2133
1723
|
getControlState,
|
|
1724
|
+
getCurrentThreadApp,
|
|
2134
1725
|
getUserState
|
|
2135
1726
|
]
|
|
2136
1727
|
);
|
|
2137
1728
|
useEffect4(() => {
|
|
2138
1729
|
const backendState = backendStateRef.current;
|
|
2139
|
-
const
|
|
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
|
-
}
|
|
1730
|
+
const unsubscribe = eventContext.subscribe("title_changed", (event) => {
|
|
1731
|
+
const sessionId = event.sessionId;
|
|
1732
|
+
const payload = event.payload;
|
|
1733
|
+
const newTitle = payload == null ? void 0 : payload.new_title;
|
|
1734
|
+
if (typeof newTitle !== "string") return;
|
|
1735
|
+
const targetThreadId = resolveThreadId(backendState, sessionId);
|
|
1736
|
+
const normalizedTitle = isPlaceholderTitle(newTitle) ? "" : newTitle;
|
|
1737
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1738
|
+
console.debug("[aomi][sse] title_changed", {
|
|
1739
|
+
sessionId,
|
|
1740
|
+
newTitle,
|
|
1741
|
+
normalizedTitle,
|
|
1742
|
+
currentThreadId: threadContextRef.current.currentThreadId,
|
|
1743
|
+
targetThreadId
|
|
1744
|
+
});
|
|
2180
1745
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
1746
|
+
threadContextRef.current.setThreadMetadata((prev) => {
|
|
1747
|
+
var _a, _b;
|
|
1748
|
+
const next = new Map(prev);
|
|
1749
|
+
const existing = next.get(targetThreadId);
|
|
1750
|
+
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1751
|
+
next.set(targetThreadId, {
|
|
1752
|
+
title: normalizedTitle,
|
|
1753
|
+
status: nextStatus,
|
|
1754
|
+
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1755
|
+
control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
|
|
1756
|
+
});
|
|
1757
|
+
return next;
|
|
1758
|
+
});
|
|
1759
|
+
});
|
|
1760
|
+
return unsubscribe;
|
|
1761
|
+
}, [eventContext, backendStateRef]);
|
|
2191
1762
|
useEffect4(() => {
|
|
2192
1763
|
const showToolNotification = (eventType) => (event) => {
|
|
2193
1764
|
const payload = event.payload;
|
|
@@ -2356,12 +1927,12 @@ function AomiRuntimeProvider({
|
|
|
2356
1927
|
children,
|
|
2357
1928
|
backendUrl = "http://localhost:8080"
|
|
2358
1929
|
}) {
|
|
2359
|
-
const
|
|
2360
|
-
return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, {
|
|
1930
|
+
const aomiClient = useMemo3(() => new AomiClient({ baseUrl: backendUrl }), [backendUrl]);
|
|
1931
|
+
return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, { aomiClient, children }) }) }) });
|
|
2361
1932
|
}
|
|
2362
1933
|
function AomiRuntimeInner({
|
|
2363
1934
|
children,
|
|
2364
|
-
|
|
1935
|
+
aomiClient
|
|
2365
1936
|
}) {
|
|
2366
1937
|
var _a;
|
|
2367
1938
|
const threadContext = useThreadContext();
|
|
@@ -2369,7 +1940,7 @@ function AomiRuntimeInner({
|
|
|
2369
1940
|
return /* @__PURE__ */ jsx7(
|
|
2370
1941
|
ControlContextProvider,
|
|
2371
1942
|
{
|
|
2372
|
-
|
|
1943
|
+
aomiClient,
|
|
2373
1944
|
sessionId: threadContext.currentThreadId,
|
|
2374
1945
|
publicKey: (_a = user.address) != null ? _a : void 0,
|
|
2375
1946
|
getThreadMetadata: threadContext.getThreadMetadata,
|
|
@@ -2377,9 +1948,9 @@ function AomiRuntimeInner({
|
|
|
2377
1948
|
children: /* @__PURE__ */ jsx7(
|
|
2378
1949
|
EventContextProvider,
|
|
2379
1950
|
{
|
|
2380
|
-
|
|
1951
|
+
aomiClient,
|
|
2381
1952
|
sessionId: threadContext.currentThreadId,
|
|
2382
|
-
children: /* @__PURE__ */ jsx7(AomiRuntimeCore, {
|
|
1953
|
+
children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { aomiClient, children })
|
|
2383
1954
|
}
|
|
2384
1955
|
)
|
|
2385
1956
|
}
|
|
@@ -2428,8 +1999,8 @@ function useNotificationHandler({
|
|
|
2428
1999
|
};
|
|
2429
2000
|
}
|
|
2430
2001
|
export {
|
|
2002
|
+
AomiClient2 as AomiClient,
|
|
2431
2003
|
AomiRuntimeProvider,
|
|
2432
|
-
BackendApi,
|
|
2433
2004
|
ControlContextProvider,
|
|
2434
2005
|
EventContextProvider,
|
|
2435
2006
|
NotificationContextProvider,
|
|
@@ -2441,6 +2012,7 @@ export {
|
|
|
2441
2012
|
getChainInfo,
|
|
2442
2013
|
getNetworkName,
|
|
2443
2014
|
initThreadControl,
|
|
2015
|
+
toViemSignTypedDataArgs,
|
|
2444
2016
|
useAomiRuntime,
|
|
2445
2017
|
useControl,
|
|
2446
2018
|
useCurrentThreadMessages,
|