@aomi-labs/react 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +755 -330
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -2
- package/dist/index.d.ts +88 -2
- package/dist/index.js +768 -339
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
package/dist/index.cjs
CHANGED
|
@@ -34,11 +34,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
34
34
|
};
|
|
35
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
36
|
|
|
37
|
-
// src/index.ts
|
|
37
|
+
// packages/react/src/index.ts
|
|
38
38
|
var index_exports = {};
|
|
39
39
|
__export(index_exports, {
|
|
40
40
|
AomiRuntimeProvider: () => AomiRuntimeProvider,
|
|
41
41
|
BackendApi: () => BackendApi,
|
|
42
|
+
ControlContextProvider: () => ControlContextProvider,
|
|
42
43
|
EventContextProvider: () => EventContextProvider,
|
|
43
44
|
NotificationContextProvider: () => NotificationContextProvider,
|
|
44
45
|
ThreadContextProvider: () => ThreadContextProvider,
|
|
@@ -46,7 +47,9 @@ __export(index_exports, {
|
|
|
46
47
|
cn: () => cn,
|
|
47
48
|
formatAddress: () => formatAddress,
|
|
48
49
|
getNetworkName: () => getNetworkName,
|
|
50
|
+
initThreadControl: () => initThreadControl,
|
|
49
51
|
useAomiRuntime: () => useAomiRuntime,
|
|
52
|
+
useControl: () => useControl,
|
|
50
53
|
useCurrentThreadMessages: () => useCurrentThreadMessages,
|
|
51
54
|
useCurrentThreadMetadata: () => useCurrentThreadMetadata,
|
|
52
55
|
useEventContext: () => useEventContext,
|
|
@@ -58,7 +61,7 @@ __export(index_exports, {
|
|
|
58
61
|
});
|
|
59
62
|
module.exports = __toCommonJS(index_exports);
|
|
60
63
|
|
|
61
|
-
// src/backend/sse.ts
|
|
64
|
+
// packages/react/src/backend/sse.ts
|
|
62
65
|
function extractSseData(rawEvent) {
|
|
63
66
|
const dataLines = rawEvent.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart());
|
|
64
67
|
if (!dataLines.length) return null;
|
|
@@ -244,8 +247,9 @@ function createSseSubscriber({
|
|
|
244
247
|
return { subscribe: subscribe2 };
|
|
245
248
|
}
|
|
246
249
|
|
|
247
|
-
// src/backend/client.ts
|
|
250
|
+
// packages/react/src/backend/client.ts
|
|
248
251
|
var SESSION_ID_HEADER = "X-Session-Id";
|
|
252
|
+
var API_KEY_HEADER = "X-API-Key";
|
|
249
253
|
function toQueryString(payload) {
|
|
250
254
|
const params = new URLSearchParams();
|
|
251
255
|
for (const [key, value] of Object.entries(payload)) {
|
|
@@ -260,12 +264,16 @@ function withSessionHeader(sessionId, init) {
|
|
|
260
264
|
headers.set(SESSION_ID_HEADER, sessionId);
|
|
261
265
|
return headers;
|
|
262
266
|
}
|
|
263
|
-
async function postState(backendUrl, path, payload, sessionId) {
|
|
267
|
+
async function postState(backendUrl, path, payload, sessionId, apiKey) {
|
|
264
268
|
const query = toQueryString(payload);
|
|
265
269
|
const url = `${backendUrl}${path}${query}`;
|
|
270
|
+
const headers = new Headers(withSessionHeader(sessionId));
|
|
271
|
+
if (apiKey) {
|
|
272
|
+
headers.set(API_KEY_HEADER, apiKey);
|
|
273
|
+
}
|
|
266
274
|
const response = await fetch(url, {
|
|
267
275
|
method: "POST",
|
|
268
|
-
headers
|
|
276
|
+
headers
|
|
269
277
|
});
|
|
270
278
|
if (!response.ok) {
|
|
271
279
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -293,15 +301,17 @@ var BackendApi = class {
|
|
|
293
301
|
}
|
|
294
302
|
return await response.json();
|
|
295
303
|
}
|
|
296
|
-
async postChatMessage(sessionId, message, publicKey) {
|
|
304
|
+
async postChatMessage(sessionId, message, namespace, publicKey, apiKey) {
|
|
305
|
+
const payload = { message, namespace };
|
|
306
|
+
if (publicKey) {
|
|
307
|
+
payload.public_key = publicKey;
|
|
308
|
+
}
|
|
297
309
|
return postState(
|
|
298
310
|
this.backendUrl,
|
|
299
311
|
"/api/chat",
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
},
|
|
304
|
-
sessionId
|
|
312
|
+
payload,
|
|
313
|
+
sessionId,
|
|
314
|
+
apiKey
|
|
305
315
|
);
|
|
306
316
|
}
|
|
307
317
|
async postSystemMessage(sessionId, message) {
|
|
@@ -421,16 +431,535 @@ var BackendApi = class {
|
|
|
421
431
|
}
|
|
422
432
|
return await response.json();
|
|
423
433
|
}
|
|
424
|
-
//
|
|
434
|
+
// ===========================================================================
|
|
435
|
+
// Control API
|
|
436
|
+
// ===========================================================================
|
|
437
|
+
/**
|
|
438
|
+
* Get allowed namespaces for the current request context.
|
|
439
|
+
*/
|
|
440
|
+
async getNamespaces(sessionId, publicKey, apiKey) {
|
|
441
|
+
const url = new URL("/api/control/namespaces", this.backendUrl);
|
|
442
|
+
if (publicKey) {
|
|
443
|
+
url.searchParams.set("public_key", publicKey);
|
|
444
|
+
}
|
|
445
|
+
console.log("[BackendApi.getNamespaces]", {
|
|
446
|
+
backendUrl: this.backendUrl,
|
|
447
|
+
fullUrl: url.toString(),
|
|
448
|
+
sessionId,
|
|
449
|
+
publicKey
|
|
450
|
+
});
|
|
451
|
+
const headers = new Headers(withSessionHeader(sessionId));
|
|
452
|
+
if (apiKey) {
|
|
453
|
+
headers.set(API_KEY_HEADER, apiKey);
|
|
454
|
+
}
|
|
455
|
+
const response = await fetch(url.toString(), { headers });
|
|
456
|
+
if (!response.ok) {
|
|
457
|
+
throw new Error(`Failed to get namespaces: HTTP ${response.status}`);
|
|
458
|
+
}
|
|
459
|
+
return await response.json();
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Get available models.
|
|
463
|
+
*/
|
|
464
|
+
async getModels(sessionId) {
|
|
465
|
+
const url = new URL("/api/control/models", this.backendUrl);
|
|
466
|
+
console.log("[BackendApi.getModels]", {
|
|
467
|
+
backendUrl: this.backendUrl,
|
|
468
|
+
fullUrl: url.toString(),
|
|
469
|
+
sessionId
|
|
470
|
+
});
|
|
471
|
+
const response = await fetch(url.toString(), {
|
|
472
|
+
headers: withSessionHeader(sessionId)
|
|
473
|
+
});
|
|
474
|
+
if (!response.ok) {
|
|
475
|
+
throw new Error(`Failed to get models: HTTP ${response.status}`);
|
|
476
|
+
}
|
|
477
|
+
return await response.json();
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Set the model selection for a session.
|
|
481
|
+
*/
|
|
482
|
+
async setModel(sessionId, rig, namespace, apiKey) {
|
|
483
|
+
const payload = { rig };
|
|
484
|
+
if (namespace) {
|
|
485
|
+
payload.namespace = namespace;
|
|
486
|
+
}
|
|
487
|
+
return postState(this.backendUrl, "/api/control/model", payload, sessionId, apiKey);
|
|
488
|
+
}
|
|
425
489
|
};
|
|
426
490
|
|
|
427
|
-
// src/runtime/aomi-runtime.tsx
|
|
428
|
-
var
|
|
491
|
+
// packages/react/src/runtime/aomi-runtime.tsx
|
|
492
|
+
var import_react10 = require("react");
|
|
429
493
|
|
|
430
|
-
// src/contexts/
|
|
494
|
+
// packages/react/src/contexts/control-context.tsx
|
|
431
495
|
var import_react = require("react");
|
|
432
496
|
|
|
433
|
-
// src/
|
|
497
|
+
// packages/react/src/utils/uuid.ts
|
|
498
|
+
function generateUUID() {
|
|
499
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
500
|
+
return crypto.randomUUID();
|
|
501
|
+
}
|
|
502
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
503
|
+
const r = Math.random() * 16 | 0;
|
|
504
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
505
|
+
return v.toString(16);
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// packages/react/src/state/thread-store.ts
|
|
510
|
+
var shouldLogThreadUpdates = process.env.NODE_ENV !== "production";
|
|
511
|
+
var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
512
|
+
if (!shouldLogThreadUpdates) return;
|
|
513
|
+
if (!prev && !next) return;
|
|
514
|
+
if (!prev || !next) {
|
|
515
|
+
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (prev.title !== next.title || prev.status !== next.status || prev.lastActiveAt !== next.lastActiveAt) {
|
|
519
|
+
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
function initThreadControl() {
|
|
523
|
+
return {
|
|
524
|
+
model: null,
|
|
525
|
+
namespace: null,
|
|
526
|
+
controlDirty: false,
|
|
527
|
+
isProcessing: false
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
var ThreadStore = class {
|
|
531
|
+
constructor(options) {
|
|
532
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
533
|
+
this.subscribe = (listener) => {
|
|
534
|
+
this.listeners.add(listener);
|
|
535
|
+
return () => {
|
|
536
|
+
this.listeners.delete(listener);
|
|
537
|
+
};
|
|
538
|
+
};
|
|
539
|
+
this.getSnapshot = () => this.snapshot;
|
|
540
|
+
this.setCurrentThreadId = (threadId) => {
|
|
541
|
+
this.ensureThreadExists(threadId);
|
|
542
|
+
this.updateState({ currentThreadId: threadId });
|
|
543
|
+
};
|
|
544
|
+
this.bumpThreadViewKey = () => {
|
|
545
|
+
this.updateState({ threadViewKey: this.state.threadViewKey + 1 });
|
|
546
|
+
};
|
|
547
|
+
this.setThreadCnt = (updater) => {
|
|
548
|
+
const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);
|
|
549
|
+
this.updateState({ threadCnt: nextCnt });
|
|
550
|
+
};
|
|
551
|
+
this.setThreads = (updater) => {
|
|
552
|
+
const nextThreads = this.resolveStateAction(updater, this.state.threads);
|
|
553
|
+
this.updateState({ threads: new Map(nextThreads) });
|
|
554
|
+
};
|
|
555
|
+
this.setThreadMetadata = (updater) => {
|
|
556
|
+
const prevMetadata = this.state.threadMetadata;
|
|
557
|
+
const nextMetadata = this.resolveStateAction(updater, prevMetadata);
|
|
558
|
+
for (const [threadId, next] of nextMetadata.entries()) {
|
|
559
|
+
logThreadMetadataChange(
|
|
560
|
+
"setThreadMetadata",
|
|
561
|
+
threadId,
|
|
562
|
+
prevMetadata.get(threadId),
|
|
563
|
+
next
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
for (const [threadId, prev] of prevMetadata.entries()) {
|
|
567
|
+
if (!nextMetadata.has(threadId)) {
|
|
568
|
+
logThreadMetadataChange("setThreadMetadata", threadId, prev, void 0);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
this.updateState({ threadMetadata: new Map(nextMetadata) });
|
|
572
|
+
};
|
|
573
|
+
this.setThreadMessages = (threadId, messages) => {
|
|
574
|
+
this.ensureThreadExists(threadId);
|
|
575
|
+
const nextThreads = new Map(this.state.threads);
|
|
576
|
+
nextThreads.set(threadId, messages);
|
|
577
|
+
this.updateState({ threads: nextThreads });
|
|
578
|
+
};
|
|
579
|
+
this.getThreadMessages = (threadId) => {
|
|
580
|
+
var _a;
|
|
581
|
+
return (_a = this.state.threads.get(threadId)) != null ? _a : [];
|
|
582
|
+
};
|
|
583
|
+
this.getThreadMetadata = (threadId) => {
|
|
584
|
+
return this.state.threadMetadata.get(threadId);
|
|
585
|
+
};
|
|
586
|
+
this.updateThreadMetadata = (threadId, updates) => {
|
|
587
|
+
const existing = this.state.threadMetadata.get(threadId);
|
|
588
|
+
if (!existing) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const next = __spreadValues(__spreadValues({}, existing), updates);
|
|
592
|
+
const nextMetadata = new Map(this.state.threadMetadata);
|
|
593
|
+
nextMetadata.set(threadId, next);
|
|
594
|
+
logThreadMetadataChange("updateThreadMetadata", threadId, existing, next);
|
|
595
|
+
this.updateState({ threadMetadata: nextMetadata });
|
|
596
|
+
};
|
|
597
|
+
var _a;
|
|
598
|
+
const initialThreadId = (_a = options == null ? void 0 : options.initialThreadId) != null ? _a : generateUUID();
|
|
599
|
+
this.state = {
|
|
600
|
+
currentThreadId: initialThreadId,
|
|
601
|
+
threadViewKey: 0,
|
|
602
|
+
threadCnt: 1,
|
|
603
|
+
threads: /* @__PURE__ */ new Map([[initialThreadId, []]]),
|
|
604
|
+
threadMetadata: /* @__PURE__ */ new Map([
|
|
605
|
+
[
|
|
606
|
+
initialThreadId,
|
|
607
|
+
{
|
|
608
|
+
title: "New Chat",
|
|
609
|
+
status: "pending",
|
|
610
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
611
|
+
control: initThreadControl()
|
|
612
|
+
}
|
|
613
|
+
]
|
|
614
|
+
])
|
|
615
|
+
};
|
|
616
|
+
this.snapshot = this.buildSnapshot();
|
|
617
|
+
}
|
|
618
|
+
emit() {
|
|
619
|
+
for (const listener of this.listeners) {
|
|
620
|
+
listener();
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
resolveStateAction(updater, current) {
|
|
624
|
+
return typeof updater === "function" ? updater(current) : updater;
|
|
625
|
+
}
|
|
626
|
+
ensureThreadExists(threadId) {
|
|
627
|
+
if (!this.state.threadMetadata.has(threadId)) {
|
|
628
|
+
const nextMetadata = new Map(this.state.threadMetadata);
|
|
629
|
+
nextMetadata.set(threadId, {
|
|
630
|
+
title: "New Chat",
|
|
631
|
+
status: "regular",
|
|
632
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
633
|
+
control: initThreadControl()
|
|
634
|
+
});
|
|
635
|
+
this.state = __spreadProps(__spreadValues({}, this.state), { threadMetadata: nextMetadata });
|
|
636
|
+
}
|
|
637
|
+
if (!this.state.threads.has(threadId)) {
|
|
638
|
+
const nextThreads = new Map(this.state.threads);
|
|
639
|
+
nextThreads.set(threadId, []);
|
|
640
|
+
this.state = __spreadProps(__spreadValues({}, this.state), { threads: nextThreads });
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
updateState(partial) {
|
|
644
|
+
this.state = __spreadValues(__spreadValues({}, this.state), partial);
|
|
645
|
+
this.snapshot = this.buildSnapshot();
|
|
646
|
+
this.emit();
|
|
647
|
+
}
|
|
648
|
+
buildSnapshot() {
|
|
649
|
+
return {
|
|
650
|
+
currentThreadId: this.state.currentThreadId,
|
|
651
|
+
setCurrentThreadId: this.setCurrentThreadId,
|
|
652
|
+
threadViewKey: this.state.threadViewKey,
|
|
653
|
+
bumpThreadViewKey: this.bumpThreadViewKey,
|
|
654
|
+
allThreads: this.state.threads,
|
|
655
|
+
setThreads: this.setThreads,
|
|
656
|
+
allThreadsMetadata: this.state.threadMetadata,
|
|
657
|
+
setThreadMetadata: this.setThreadMetadata,
|
|
658
|
+
threadCnt: this.state.threadCnt,
|
|
659
|
+
setThreadCnt: this.setThreadCnt,
|
|
660
|
+
getThreadMessages: this.getThreadMessages,
|
|
661
|
+
setThreadMessages: this.setThreadMessages,
|
|
662
|
+
getThreadMetadata: this.getThreadMetadata,
|
|
663
|
+
updateThreadMetadata: this.updateThreadMetadata
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
// packages/react/src/contexts/control-context.tsx
|
|
669
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
670
|
+
var API_KEY_STORAGE_KEY = "aomi_api_key";
|
|
671
|
+
var ControlContext = (0, import_react.createContext)(null);
|
|
672
|
+
function useControl() {
|
|
673
|
+
const ctx = (0, import_react.useContext)(ControlContext);
|
|
674
|
+
if (!ctx) {
|
|
675
|
+
throw new Error("useControl must be used within ControlContextProvider");
|
|
676
|
+
}
|
|
677
|
+
return ctx;
|
|
678
|
+
}
|
|
679
|
+
function ControlContextProvider({
|
|
680
|
+
children,
|
|
681
|
+
backendApi,
|
|
682
|
+
sessionId,
|
|
683
|
+
publicKey,
|
|
684
|
+
getThreadMetadata,
|
|
685
|
+
updateThreadMetadata
|
|
686
|
+
}) {
|
|
687
|
+
var _a, _b;
|
|
688
|
+
const [state, setStateInternal] = (0, import_react.useState)(() => ({
|
|
689
|
+
apiKey: null,
|
|
690
|
+
availableModels: [],
|
|
691
|
+
authorizedNamespaces: [],
|
|
692
|
+
defaultModel: null,
|
|
693
|
+
defaultNamespace: null
|
|
694
|
+
}));
|
|
695
|
+
const stateRef = (0, import_react.useRef)(state);
|
|
696
|
+
stateRef.current = state;
|
|
697
|
+
const backendApiRef = (0, import_react.useRef)(backendApi);
|
|
698
|
+
backendApiRef.current = backendApi;
|
|
699
|
+
const sessionIdRef = (0, import_react.useRef)(sessionId);
|
|
700
|
+
sessionIdRef.current = sessionId;
|
|
701
|
+
const publicKeyRef = (0, import_react.useRef)(publicKey);
|
|
702
|
+
publicKeyRef.current = publicKey;
|
|
703
|
+
const getThreadMetadataRef = (0, import_react.useRef)(getThreadMetadata);
|
|
704
|
+
getThreadMetadataRef.current = getThreadMetadata;
|
|
705
|
+
const updateThreadMetadataRef = (0, import_react.useRef)(updateThreadMetadata);
|
|
706
|
+
updateThreadMetadataRef.current = updateThreadMetadata;
|
|
707
|
+
const callbacks = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
708
|
+
const currentThreadMetadata = getThreadMetadata(sessionId);
|
|
709
|
+
const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
|
|
710
|
+
(0, import_react.useEffect)(() => {
|
|
711
|
+
var _a2, _b2;
|
|
712
|
+
try {
|
|
713
|
+
const storedApiKey = (_b2 = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(API_KEY_STORAGE_KEY)) != null ? _b2 : null;
|
|
714
|
+
if (storedApiKey) {
|
|
715
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { apiKey: storedApiKey }));
|
|
716
|
+
}
|
|
717
|
+
} catch (e) {
|
|
718
|
+
}
|
|
719
|
+
}, []);
|
|
720
|
+
(0, import_react.useEffect)(() => {
|
|
721
|
+
var _a2, _b2;
|
|
722
|
+
try {
|
|
723
|
+
if (state.apiKey) {
|
|
724
|
+
(_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(API_KEY_STORAGE_KEY, state.apiKey);
|
|
725
|
+
} else {
|
|
726
|
+
(_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(API_KEY_STORAGE_KEY);
|
|
727
|
+
}
|
|
728
|
+
} catch (e) {
|
|
729
|
+
}
|
|
730
|
+
}, [state.apiKey]);
|
|
731
|
+
(0, import_react.useEffect)(() => {
|
|
732
|
+
const fetchNamespaces = async () => {
|
|
733
|
+
var _a2, _b2;
|
|
734
|
+
try {
|
|
735
|
+
const namespaces = await backendApiRef.current.getNamespaces(
|
|
736
|
+
sessionIdRef.current,
|
|
737
|
+
publicKeyRef.current,
|
|
738
|
+
(_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
739
|
+
);
|
|
740
|
+
const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
|
|
741
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
742
|
+
authorizedNamespaces: namespaces,
|
|
743
|
+
defaultNamespace: defaultNs
|
|
744
|
+
}));
|
|
745
|
+
} catch (error) {
|
|
746
|
+
console.error("Failed to fetch namespaces:", error);
|
|
747
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
748
|
+
authorizedNamespaces: ["default"],
|
|
749
|
+
defaultNamespace: "default"
|
|
750
|
+
}));
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
void fetchNamespaces();
|
|
754
|
+
}, [state.apiKey]);
|
|
755
|
+
(0, import_react.useEffect)(() => {
|
|
756
|
+
const fetchModels = async () => {
|
|
757
|
+
try {
|
|
758
|
+
const models = await backendApiRef.current.getModels(
|
|
759
|
+
sessionIdRef.current
|
|
760
|
+
);
|
|
761
|
+
setStateInternal((prev) => {
|
|
762
|
+
var _a2;
|
|
763
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
764
|
+
availableModels: models,
|
|
765
|
+
defaultModel: (_a2 = models[0]) != null ? _a2 : null
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
} catch (error) {
|
|
769
|
+
console.error("Failed to fetch models:", error);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
void fetchModels();
|
|
773
|
+
}, []);
|
|
774
|
+
const setApiKey = (0, import_react.useCallback)((apiKey) => {
|
|
775
|
+
setStateInternal((prev) => {
|
|
776
|
+
const next = __spreadProps(__spreadValues({}, prev), { apiKey: apiKey === "" ? null : apiKey });
|
|
777
|
+
callbacks.current.forEach((cb) => cb(next));
|
|
778
|
+
return next;
|
|
779
|
+
});
|
|
780
|
+
}, []);
|
|
781
|
+
const getAvailableModels = (0, import_react.useCallback)(async () => {
|
|
782
|
+
try {
|
|
783
|
+
const models = await backendApiRef.current.getModels(
|
|
784
|
+
sessionIdRef.current
|
|
785
|
+
);
|
|
786
|
+
setStateInternal((prev) => {
|
|
787
|
+
var _a2, _b2;
|
|
788
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
789
|
+
availableModels: models,
|
|
790
|
+
defaultModel: (_b2 = (_a2 = prev.defaultModel) != null ? _a2 : models[0]) != null ? _b2 : null
|
|
791
|
+
});
|
|
792
|
+
});
|
|
793
|
+
return models;
|
|
794
|
+
} catch (error) {
|
|
795
|
+
console.error("Failed to fetch models:", error);
|
|
796
|
+
return [];
|
|
797
|
+
}
|
|
798
|
+
}, []);
|
|
799
|
+
const getAuthorizedNamespaces = (0, import_react.useCallback)(async () => {
|
|
800
|
+
var _a2, _b2;
|
|
801
|
+
try {
|
|
802
|
+
const namespaces = await backendApiRef.current.getNamespaces(
|
|
803
|
+
sessionIdRef.current,
|
|
804
|
+
publicKeyRef.current,
|
|
805
|
+
(_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
806
|
+
);
|
|
807
|
+
const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
|
|
808
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
809
|
+
authorizedNamespaces: namespaces,
|
|
810
|
+
defaultNamespace: defaultNs
|
|
811
|
+
}));
|
|
812
|
+
return namespaces;
|
|
813
|
+
} catch (error) {
|
|
814
|
+
console.error("Failed to fetch namespaces:", error);
|
|
815
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
816
|
+
authorizedNamespaces: ["default"],
|
|
817
|
+
defaultNamespace: "default"
|
|
818
|
+
}));
|
|
819
|
+
return ["default"];
|
|
820
|
+
}
|
|
821
|
+
}, []);
|
|
822
|
+
const getCurrentThreadControl = (0, import_react.useCallback)(() => {
|
|
823
|
+
var _a2;
|
|
824
|
+
const metadata = getThreadMetadataRef.current(sessionIdRef.current);
|
|
825
|
+
return (_a2 = metadata == null ? void 0 : metadata.control) != null ? _a2 : initThreadControl();
|
|
826
|
+
}, []);
|
|
827
|
+
const onModelSelect = (0, import_react.useCallback)(async (model) => {
|
|
828
|
+
var _a2, _b2, _c, _d, _e;
|
|
829
|
+
const threadId = sessionIdRef.current;
|
|
830
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
831
|
+
const isProcessing2 = currentControl.isProcessing;
|
|
832
|
+
console.log("[control-context] onModelSelect called", {
|
|
833
|
+
model,
|
|
834
|
+
isProcessing: isProcessing2,
|
|
835
|
+
threadId
|
|
836
|
+
});
|
|
837
|
+
if (isProcessing2) {
|
|
838
|
+
console.warn("[control-context] Cannot switch model while processing");
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const namespace = (_d = (_c = currentControl.namespace) != null ? _c : stateRef.current.defaultNamespace) != null ? _d : "default";
|
|
842
|
+
console.log("[control-context] onModelSelect updating metadata", {
|
|
843
|
+
threadId,
|
|
844
|
+
model,
|
|
845
|
+
namespace,
|
|
846
|
+
currentControl
|
|
847
|
+
});
|
|
848
|
+
updateThreadMetadataRef.current(threadId, {
|
|
849
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
850
|
+
model,
|
|
851
|
+
namespace,
|
|
852
|
+
controlDirty: true
|
|
853
|
+
})
|
|
854
|
+
});
|
|
855
|
+
console.log("[control-context] onModelSelect calling backend setModel", {
|
|
856
|
+
threadId,
|
|
857
|
+
model,
|
|
858
|
+
namespace,
|
|
859
|
+
backendUrl: backendApiRef.current
|
|
860
|
+
});
|
|
861
|
+
try {
|
|
862
|
+
const result = await backendApiRef.current.setModel(
|
|
863
|
+
threadId,
|
|
864
|
+
model,
|
|
865
|
+
namespace,
|
|
866
|
+
(_e = stateRef.current.apiKey) != null ? _e : void 0
|
|
867
|
+
);
|
|
868
|
+
console.log("[control-context] onModelSelect backend result", result);
|
|
869
|
+
} catch (err) {
|
|
870
|
+
console.error("[control-context] setModel failed:", err);
|
|
871
|
+
throw err;
|
|
872
|
+
}
|
|
873
|
+
}, []);
|
|
874
|
+
const onNamespaceSelect = (0, import_react.useCallback)((namespace) => {
|
|
875
|
+
var _a2, _b2;
|
|
876
|
+
const threadId = sessionIdRef.current;
|
|
877
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
878
|
+
const isProcessing2 = currentControl.isProcessing;
|
|
879
|
+
console.log("[control-context] onNamespaceSelect called", {
|
|
880
|
+
namespace,
|
|
881
|
+
isProcessing: isProcessing2,
|
|
882
|
+
threadId
|
|
883
|
+
});
|
|
884
|
+
if (isProcessing2) {
|
|
885
|
+
console.warn(
|
|
886
|
+
"[control-context] Cannot switch namespace while processing"
|
|
887
|
+
);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
console.log("[control-context] onNamespaceSelect updating metadata", {
|
|
891
|
+
threadId,
|
|
892
|
+
namespace,
|
|
893
|
+
currentControl
|
|
894
|
+
});
|
|
895
|
+
updateThreadMetadataRef.current(threadId, {
|
|
896
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
897
|
+
namespace,
|
|
898
|
+
controlDirty: true
|
|
899
|
+
})
|
|
900
|
+
});
|
|
901
|
+
console.log("[control-context] onNamespaceSelect metadata updated");
|
|
902
|
+
}, []);
|
|
903
|
+
const markControlSynced = (0, import_react.useCallback)(() => {
|
|
904
|
+
var _a2, _b2;
|
|
905
|
+
const threadId = sessionIdRef.current;
|
|
906
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
907
|
+
if (currentControl.controlDirty) {
|
|
908
|
+
updateThreadMetadataRef.current(threadId, {
|
|
909
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
910
|
+
controlDirty: false
|
|
911
|
+
})
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
}, []);
|
|
915
|
+
const getControlState = (0, import_react.useCallback)(() => stateRef.current, []);
|
|
916
|
+
const onControlStateChange = (0, import_react.useCallback)(
|
|
917
|
+
(callback) => {
|
|
918
|
+
callbacks.current.add(callback);
|
|
919
|
+
return () => {
|
|
920
|
+
callbacks.current.delete(callback);
|
|
921
|
+
};
|
|
922
|
+
},
|
|
923
|
+
[]
|
|
924
|
+
);
|
|
925
|
+
const setState = (0, import_react.useCallback)(
|
|
926
|
+
(updates) => {
|
|
927
|
+
var _a2;
|
|
928
|
+
if ("apiKey" in updates) {
|
|
929
|
+
setApiKey((_a2 = updates.apiKey) != null ? _a2 : null);
|
|
930
|
+
}
|
|
931
|
+
if ("namespace" in updates && updates.namespace !== void 0 && updates.namespace !== null) {
|
|
932
|
+
onNamespaceSelect(updates.namespace);
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
[setApiKey, onNamespaceSelect]
|
|
936
|
+
);
|
|
937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
938
|
+
ControlContext.Provider,
|
|
939
|
+
{
|
|
940
|
+
value: {
|
|
941
|
+
state,
|
|
942
|
+
setApiKey,
|
|
943
|
+
getAvailableModels,
|
|
944
|
+
getAuthorizedNamespaces,
|
|
945
|
+
getCurrentThreadControl,
|
|
946
|
+
onModelSelect,
|
|
947
|
+
onNamespaceSelect,
|
|
948
|
+
isProcessing,
|
|
949
|
+
markControlSynced,
|
|
950
|
+
getControlState,
|
|
951
|
+
onControlStateChange,
|
|
952
|
+
setState
|
|
953
|
+
},
|
|
954
|
+
children
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// packages/react/src/contexts/event-context.tsx
|
|
960
|
+
var import_react2 = require("react");
|
|
961
|
+
|
|
962
|
+
// packages/react/src/backend/types.ts
|
|
434
963
|
function isInlineCall(event) {
|
|
435
964
|
return "InlineCall" in event;
|
|
436
965
|
}
|
|
@@ -444,7 +973,7 @@ function isAsyncCallback(event) {
|
|
|
444
973
|
return "AsyncCallback" in event;
|
|
445
974
|
}
|
|
446
975
|
|
|
447
|
-
// src/state/event-buffer.ts
|
|
976
|
+
// packages/react/src/state/event-buffer.ts
|
|
448
977
|
function createEventBuffer() {
|
|
449
978
|
return {
|
|
450
979
|
inboundQueue: [],
|
|
@@ -488,11 +1017,11 @@ function setSSEStatus(state, status) {
|
|
|
488
1017
|
state.sseStatus = status;
|
|
489
1018
|
}
|
|
490
1019
|
|
|
491
|
-
// src/contexts/event-context.tsx
|
|
492
|
-
var
|
|
493
|
-
var EventContextState = (0,
|
|
1020
|
+
// packages/react/src/contexts/event-context.tsx
|
|
1021
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1022
|
+
var EventContextState = (0, import_react2.createContext)(null);
|
|
494
1023
|
function useEventContext() {
|
|
495
|
-
const context = (0,
|
|
1024
|
+
const context = (0, import_react2.useContext)(EventContextState);
|
|
496
1025
|
if (!context) {
|
|
497
1026
|
throw new Error(
|
|
498
1027
|
"useEventContext must be used within EventContextProvider. Wrap your app with <EventContextProvider>...</EventContextProvider>"
|
|
@@ -505,13 +1034,13 @@ function EventContextProvider({
|
|
|
505
1034
|
backendApi,
|
|
506
1035
|
sessionId
|
|
507
1036
|
}) {
|
|
508
|
-
const bufferRef = (0,
|
|
1037
|
+
const bufferRef = (0, import_react2.useRef)(null);
|
|
509
1038
|
if (!bufferRef.current) {
|
|
510
1039
|
bufferRef.current = createEventBuffer();
|
|
511
1040
|
}
|
|
512
1041
|
const buffer = bufferRef.current;
|
|
513
|
-
const [sseStatus, setSseStatus] = (0,
|
|
514
|
-
(0,
|
|
1042
|
+
const [sseStatus, setSseStatus] = (0, import_react2.useState)("disconnected");
|
|
1043
|
+
(0, import_react2.useEffect)(() => {
|
|
515
1044
|
setSSEStatus(buffer, "connecting");
|
|
516
1045
|
setSseStatus("connecting");
|
|
517
1046
|
const unsubscribe = backendApi.subscribeSSE(
|
|
@@ -545,13 +1074,13 @@ function EventContextProvider({
|
|
|
545
1074
|
setSseStatus("disconnected");
|
|
546
1075
|
};
|
|
547
1076
|
}, [backendApi, sessionId, buffer]);
|
|
548
|
-
const subscribeCallback = (0,
|
|
1077
|
+
const subscribeCallback = (0, import_react2.useCallback)(
|
|
549
1078
|
(type, callback) => {
|
|
550
1079
|
return subscribe(buffer, type, callback);
|
|
551
1080
|
},
|
|
552
1081
|
[buffer]
|
|
553
1082
|
);
|
|
554
|
-
const sendOutbound = (0,
|
|
1083
|
+
const sendOutbound = (0, import_react2.useCallback)(
|
|
555
1084
|
async (event) => {
|
|
556
1085
|
try {
|
|
557
1086
|
const message = JSON.stringify({
|
|
@@ -565,7 +1094,7 @@ function EventContextProvider({
|
|
|
565
1094
|
},
|
|
566
1095
|
[backendApi]
|
|
567
1096
|
);
|
|
568
|
-
const dispatchSystemEvents = (0,
|
|
1097
|
+
const dispatchSystemEvents = (0, import_react2.useCallback)(
|
|
569
1098
|
(sessionId2, events) => {
|
|
570
1099
|
var _a;
|
|
571
1100
|
for (const event of events) {
|
|
@@ -610,15 +1139,15 @@ function EventContextProvider({
|
|
|
610
1139
|
dispatchInboundSystem: dispatchSystemEvents,
|
|
611
1140
|
sseStatus
|
|
612
1141
|
};
|
|
613
|
-
return /* @__PURE__ */ (0,
|
|
1142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EventContextState.Provider, { value: contextValue, children });
|
|
614
1143
|
}
|
|
615
1144
|
|
|
616
|
-
// src/contexts/notification-context.tsx
|
|
617
|
-
var
|
|
618
|
-
var
|
|
619
|
-
var NotificationContext = (0,
|
|
1145
|
+
// packages/react/src/contexts/notification-context.tsx
|
|
1146
|
+
var import_react3 = require("react");
|
|
1147
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1148
|
+
var NotificationContext = (0, import_react3.createContext)(null);
|
|
620
1149
|
function useNotification() {
|
|
621
|
-
const context = (0,
|
|
1150
|
+
const context = (0, import_react3.useContext)(NotificationContext);
|
|
622
1151
|
if (!context) {
|
|
623
1152
|
throw new Error(
|
|
624
1153
|
"useNotification must be used within NotificationContextProvider"
|
|
@@ -633,8 +1162,8 @@ function generateId() {
|
|
|
633
1162
|
function NotificationContextProvider({
|
|
634
1163
|
children
|
|
635
1164
|
}) {
|
|
636
|
-
const [notifications, setNotifications] = (0,
|
|
637
|
-
const showNotification = (0,
|
|
1165
|
+
const [notifications, setNotifications] = (0, import_react3.useState)([]);
|
|
1166
|
+
const showNotification = (0, import_react3.useCallback)((params) => {
|
|
638
1167
|
const id = generateId();
|
|
639
1168
|
const notification = __spreadProps(__spreadValues({}, params), {
|
|
640
1169
|
id,
|
|
@@ -643,10 +1172,10 @@ function NotificationContextProvider({
|
|
|
643
1172
|
setNotifications((prev) => [notification, ...prev]);
|
|
644
1173
|
return id;
|
|
645
1174
|
}, []);
|
|
646
|
-
const dismissNotification = (0,
|
|
1175
|
+
const dismissNotification = (0, import_react3.useCallback)((id) => {
|
|
647
1176
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
648
1177
|
}, []);
|
|
649
|
-
const clearAll = (0,
|
|
1178
|
+
const clearAll = (0, import_react3.useCallback)(() => {
|
|
650
1179
|
setNotifications([]);
|
|
651
1180
|
}, []);
|
|
652
1181
|
const value = {
|
|
@@ -655,166 +1184,15 @@ function NotificationContextProvider({
|
|
|
655
1184
|
dismissNotification,
|
|
656
1185
|
clearAll
|
|
657
1186
|
};
|
|
658
|
-
return /* @__PURE__ */ (0,
|
|
1187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NotificationContext.Provider, { value, children });
|
|
659
1188
|
}
|
|
660
1189
|
|
|
661
|
-
// src/contexts/thread-context.tsx
|
|
662
|
-
var
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
var shouldLogThreadUpdates = process.env.NODE_ENV !== "production";
|
|
666
|
-
var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
667
|
-
if (!shouldLogThreadUpdates) return;
|
|
668
|
-
if (!prev && !next) return;
|
|
669
|
-
if (!prev || !next) {
|
|
670
|
-
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
if (prev.title !== next.title || prev.status !== next.status || prev.lastActiveAt !== next.lastActiveAt) {
|
|
674
|
-
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
var ThreadStore = class {
|
|
678
|
-
constructor(options) {
|
|
679
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
680
|
-
this.subscribe = (listener) => {
|
|
681
|
-
this.listeners.add(listener);
|
|
682
|
-
return () => {
|
|
683
|
-
this.listeners.delete(listener);
|
|
684
|
-
};
|
|
685
|
-
};
|
|
686
|
-
this.getSnapshot = () => this.snapshot;
|
|
687
|
-
this.setCurrentThreadId = (threadId) => {
|
|
688
|
-
this.ensureThreadExists(threadId);
|
|
689
|
-
this.updateState({ currentThreadId: threadId });
|
|
690
|
-
};
|
|
691
|
-
this.bumpThreadViewKey = () => {
|
|
692
|
-
this.updateState({ threadViewKey: this.state.threadViewKey + 1 });
|
|
693
|
-
};
|
|
694
|
-
this.setThreadCnt = (updater) => {
|
|
695
|
-
const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);
|
|
696
|
-
this.updateState({ threadCnt: nextCnt });
|
|
697
|
-
};
|
|
698
|
-
this.setThreads = (updater) => {
|
|
699
|
-
const nextThreads = this.resolveStateAction(updater, this.state.threads);
|
|
700
|
-
this.updateState({ threads: new Map(nextThreads) });
|
|
701
|
-
};
|
|
702
|
-
this.setThreadMetadata = (updater) => {
|
|
703
|
-
const prevMetadata = this.state.threadMetadata;
|
|
704
|
-
const nextMetadata = this.resolveStateAction(updater, prevMetadata);
|
|
705
|
-
for (const [threadId, next] of nextMetadata.entries()) {
|
|
706
|
-
logThreadMetadataChange(
|
|
707
|
-
"setThreadMetadata",
|
|
708
|
-
threadId,
|
|
709
|
-
prevMetadata.get(threadId),
|
|
710
|
-
next
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
for (const [threadId, prev] of prevMetadata.entries()) {
|
|
714
|
-
if (!nextMetadata.has(threadId)) {
|
|
715
|
-
logThreadMetadataChange("setThreadMetadata", threadId, prev, void 0);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
this.updateState({ threadMetadata: new Map(nextMetadata) });
|
|
719
|
-
};
|
|
720
|
-
this.setThreadMessages = (threadId, messages) => {
|
|
721
|
-
this.ensureThreadExists(threadId);
|
|
722
|
-
const nextThreads = new Map(this.state.threads);
|
|
723
|
-
nextThreads.set(threadId, messages);
|
|
724
|
-
this.updateState({ threads: nextThreads });
|
|
725
|
-
};
|
|
726
|
-
this.getThreadMessages = (threadId) => {
|
|
727
|
-
var _a;
|
|
728
|
-
return (_a = this.state.threads.get(threadId)) != null ? _a : [];
|
|
729
|
-
};
|
|
730
|
-
this.getThreadMetadata = (threadId) => {
|
|
731
|
-
return this.state.threadMetadata.get(threadId);
|
|
732
|
-
};
|
|
733
|
-
this.updateThreadMetadata = (threadId, updates) => {
|
|
734
|
-
const existing = this.state.threadMetadata.get(threadId);
|
|
735
|
-
if (!existing) {
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
const next = __spreadValues(__spreadValues({}, existing), updates);
|
|
739
|
-
const nextMetadata = new Map(this.state.threadMetadata);
|
|
740
|
-
nextMetadata.set(threadId, next);
|
|
741
|
-
logThreadMetadataChange("updateThreadMetadata", threadId, existing, next);
|
|
742
|
-
this.updateState({ threadMetadata: nextMetadata });
|
|
743
|
-
};
|
|
744
|
-
var _a;
|
|
745
|
-
const initialThreadId = (_a = options == null ? void 0 : options.initialThreadId) != null ? _a : crypto.randomUUID();
|
|
746
|
-
this.state = {
|
|
747
|
-
currentThreadId: initialThreadId,
|
|
748
|
-
threadViewKey: 0,
|
|
749
|
-
threadCnt: 1,
|
|
750
|
-
threads: /* @__PURE__ */ new Map([[initialThreadId, []]]),
|
|
751
|
-
threadMetadata: /* @__PURE__ */ new Map([
|
|
752
|
-
[
|
|
753
|
-
initialThreadId,
|
|
754
|
-
{
|
|
755
|
-
title: "New Chat",
|
|
756
|
-
status: "pending",
|
|
757
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
758
|
-
}
|
|
759
|
-
]
|
|
760
|
-
])
|
|
761
|
-
};
|
|
762
|
-
this.snapshot = this.buildSnapshot();
|
|
763
|
-
}
|
|
764
|
-
emit() {
|
|
765
|
-
for (const listener of this.listeners) {
|
|
766
|
-
listener();
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
resolveStateAction(updater, current) {
|
|
770
|
-
return typeof updater === "function" ? updater(current) : updater;
|
|
771
|
-
}
|
|
772
|
-
ensureThreadExists(threadId) {
|
|
773
|
-
if (!this.state.threadMetadata.has(threadId)) {
|
|
774
|
-
const nextMetadata = new Map(this.state.threadMetadata);
|
|
775
|
-
nextMetadata.set(threadId, {
|
|
776
|
-
title: "New Chat",
|
|
777
|
-
status: "regular",
|
|
778
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
779
|
-
});
|
|
780
|
-
this.state = __spreadProps(__spreadValues({}, this.state), { threadMetadata: nextMetadata });
|
|
781
|
-
}
|
|
782
|
-
if (!this.state.threads.has(threadId)) {
|
|
783
|
-
const nextThreads = new Map(this.state.threads);
|
|
784
|
-
nextThreads.set(threadId, []);
|
|
785
|
-
this.state = __spreadProps(__spreadValues({}, this.state), { threads: nextThreads });
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
updateState(partial) {
|
|
789
|
-
this.state = __spreadValues(__spreadValues({}, this.state), partial);
|
|
790
|
-
this.snapshot = this.buildSnapshot();
|
|
791
|
-
this.emit();
|
|
792
|
-
}
|
|
793
|
-
buildSnapshot() {
|
|
794
|
-
return {
|
|
795
|
-
currentThreadId: this.state.currentThreadId,
|
|
796
|
-
setCurrentThreadId: this.setCurrentThreadId,
|
|
797
|
-
threadViewKey: this.state.threadViewKey,
|
|
798
|
-
bumpThreadViewKey: this.bumpThreadViewKey,
|
|
799
|
-
allThreads: this.state.threads,
|
|
800
|
-
setThreads: this.setThreads,
|
|
801
|
-
allThreadsMetadata: this.state.threadMetadata,
|
|
802
|
-
setThreadMetadata: this.setThreadMetadata,
|
|
803
|
-
threadCnt: this.state.threadCnt,
|
|
804
|
-
setThreadCnt: this.setThreadCnt,
|
|
805
|
-
getThreadMessages: this.getThreadMessages,
|
|
806
|
-
setThreadMessages: this.setThreadMessages,
|
|
807
|
-
getThreadMetadata: this.getThreadMetadata,
|
|
808
|
-
updateThreadMetadata: this.updateThreadMetadata
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
// src/contexts/thread-context.tsx
|
|
814
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
815
|
-
var ThreadContextState = (0, import_react3.createContext)(null);
|
|
1190
|
+
// packages/react/src/contexts/thread-context.tsx
|
|
1191
|
+
var import_react4 = require("react");
|
|
1192
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1193
|
+
var ThreadContextState = (0, import_react4.createContext)(null);
|
|
816
1194
|
function useThreadContext() {
|
|
817
|
-
const context = (0,
|
|
1195
|
+
const context = (0, import_react4.useContext)(ThreadContextState);
|
|
818
1196
|
if (!context) {
|
|
819
1197
|
throw new Error(
|
|
820
1198
|
"useThreadContext must be used within ThreadContextProvider. Wrap your app with <ThreadContextProvider>...</ThreadContextProvider>"
|
|
@@ -826,39 +1204,39 @@ function ThreadContextProvider({
|
|
|
826
1204
|
children,
|
|
827
1205
|
initialThreadId
|
|
828
1206
|
}) {
|
|
829
|
-
const storeRef = (0,
|
|
1207
|
+
const storeRef = (0, import_react4.useRef)(null);
|
|
830
1208
|
if (!storeRef.current) {
|
|
831
1209
|
storeRef.current = new ThreadStore({ initialThreadId });
|
|
832
1210
|
}
|
|
833
1211
|
const store = storeRef.current;
|
|
834
|
-
const value = (0,
|
|
1212
|
+
const value = (0, import_react4.useSyncExternalStore)(
|
|
835
1213
|
store.subscribe,
|
|
836
1214
|
store.getSnapshot,
|
|
837
1215
|
store.getSnapshot
|
|
838
1216
|
);
|
|
839
|
-
return /* @__PURE__ */ (0,
|
|
1217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ThreadContextState.Provider, { value, children });
|
|
840
1218
|
}
|
|
841
1219
|
function useCurrentThreadMessages() {
|
|
842
1220
|
const { currentThreadId, getThreadMessages } = useThreadContext();
|
|
843
|
-
return (0,
|
|
1221
|
+
return (0, import_react4.useMemo)(
|
|
844
1222
|
() => getThreadMessages(currentThreadId),
|
|
845
1223
|
[currentThreadId, getThreadMessages]
|
|
846
1224
|
);
|
|
847
1225
|
}
|
|
848
1226
|
function useCurrentThreadMetadata() {
|
|
849
1227
|
const { currentThreadId, getThreadMetadata } = useThreadContext();
|
|
850
|
-
return (0,
|
|
1228
|
+
return (0, import_react4.useMemo)(
|
|
851
1229
|
() => getThreadMetadata(currentThreadId),
|
|
852
1230
|
[currentThreadId, getThreadMetadata]
|
|
853
1231
|
);
|
|
854
1232
|
}
|
|
855
1233
|
|
|
856
|
-
// src/contexts/user-context.tsx
|
|
857
|
-
var
|
|
858
|
-
var
|
|
859
|
-
var UserContext = (0,
|
|
1234
|
+
// packages/react/src/contexts/user-context.tsx
|
|
1235
|
+
var import_react5 = require("react");
|
|
1236
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1237
|
+
var UserContext = (0, import_react5.createContext)(void 0);
|
|
860
1238
|
function useUser() {
|
|
861
|
-
const context = (0,
|
|
1239
|
+
const context = (0, import_react5.useContext)(UserContext);
|
|
862
1240
|
if (!context) {
|
|
863
1241
|
throw new Error("useUser must be used within UserContextProvider");
|
|
864
1242
|
}
|
|
@@ -870,18 +1248,18 @@ function useUser() {
|
|
|
870
1248
|
};
|
|
871
1249
|
}
|
|
872
1250
|
function UserContextProvider({ children }) {
|
|
873
|
-
const [user, setUserState] = (0,
|
|
1251
|
+
const [user, setUserState] = (0, import_react5.useState)({
|
|
874
1252
|
isConnected: false,
|
|
875
1253
|
address: void 0,
|
|
876
1254
|
chainId: void 0,
|
|
877
1255
|
ensName: void 0
|
|
878
1256
|
});
|
|
879
|
-
const userRef = (0,
|
|
1257
|
+
const userRef = (0, import_react5.useRef)(user);
|
|
880
1258
|
userRef.current = user;
|
|
881
|
-
const StateChangeCallbacks = (0,
|
|
1259
|
+
const StateChangeCallbacks = (0, import_react5.useRef)(
|
|
882
1260
|
/* @__PURE__ */ new Set()
|
|
883
1261
|
);
|
|
884
|
-
const setUser = (0,
|
|
1262
|
+
const setUser = (0, import_react5.useCallback)((data) => {
|
|
885
1263
|
setUserState((prev) => {
|
|
886
1264
|
const next = __spreadValues(__spreadValues({}, prev), data);
|
|
887
1265
|
StateChangeCallbacks.current.forEach((callback) => {
|
|
@@ -890,8 +1268,8 @@ function UserContextProvider({ children }) {
|
|
|
890
1268
|
return next;
|
|
891
1269
|
});
|
|
892
1270
|
}, []);
|
|
893
|
-
const getUserState = (0,
|
|
894
|
-
const onUserStateChange = (0,
|
|
1271
|
+
const getUserState = (0, import_react5.useCallback)(() => userRef.current, []);
|
|
1272
|
+
const onUserStateChange = (0, import_react5.useCallback)(
|
|
895
1273
|
(callback) => {
|
|
896
1274
|
StateChangeCallbacks.current.add(callback);
|
|
897
1275
|
return () => {
|
|
@@ -900,7 +1278,7 @@ function UserContextProvider({ children }) {
|
|
|
900
1278
|
},
|
|
901
1279
|
[]
|
|
902
1280
|
);
|
|
903
|
-
return /* @__PURE__ */ (0,
|
|
1281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
904
1282
|
UserContext.Provider,
|
|
905
1283
|
{
|
|
906
1284
|
value: {
|
|
@@ -914,14 +1292,14 @@ function UserContextProvider({ children }) {
|
|
|
914
1292
|
);
|
|
915
1293
|
}
|
|
916
1294
|
|
|
917
|
-
// src/runtime/core.tsx
|
|
918
|
-
var
|
|
919
|
-
var
|
|
1295
|
+
// packages/react/src/runtime/core.tsx
|
|
1296
|
+
var import_react8 = require("react");
|
|
1297
|
+
var import_react9 = require("@assistant-ui/react");
|
|
920
1298
|
|
|
921
|
-
// src/runtime/orchestrator.ts
|
|
922
|
-
var
|
|
1299
|
+
// packages/react/src/runtime/orchestrator.ts
|
|
1300
|
+
var import_react6 = require("react");
|
|
923
1301
|
|
|
924
|
-
// src/runtime/utils.ts
|
|
1302
|
+
// packages/react/src/runtime/utils.ts
|
|
925
1303
|
var import_clsx = require("clsx");
|
|
926
1304
|
var import_tailwind_merge = require("tailwind-merge");
|
|
927
1305
|
function cn(...inputs) {
|
|
@@ -1014,7 +1392,7 @@ var getNetworkName = (chainId) => {
|
|
|
1014
1392
|
};
|
|
1015
1393
|
var formatAddress = (addr) => addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : "Connect Wallet";
|
|
1016
1394
|
|
|
1017
|
-
// src/state/backend-state.ts
|
|
1395
|
+
// packages/react/src/state/backend-state.ts
|
|
1018
1396
|
function createBackendState() {
|
|
1019
1397
|
return {
|
|
1020
1398
|
skipInitialFetch: /* @__PURE__ */ new Set(),
|
|
@@ -1065,7 +1443,7 @@ function hasPendingChat(state, threadId) {
|
|
|
1065
1443
|
return ((_b = (_a = state.pendingChat.get(threadId)) == null ? void 0 : _a.length) != null ? _b : 0) > 0;
|
|
1066
1444
|
}
|
|
1067
1445
|
|
|
1068
|
-
// src/runtime/message-controller.ts
|
|
1446
|
+
// packages/react/src/runtime/message-controller.ts
|
|
1069
1447
|
var MessageController = class {
|
|
1070
1448
|
constructor(config) {
|
|
1071
1449
|
this.config = config;
|
|
@@ -1086,7 +1464,7 @@ var MessageController = class {
|
|
|
1086
1464
|
this.getThreadContextApi().setThreadMessages(threadId, threadMessages);
|
|
1087
1465
|
}
|
|
1088
1466
|
async outbound(message, threadId) {
|
|
1089
|
-
var _a, _b, _c;
|
|
1467
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1090
1468
|
const backendState = this.config.backendStateRef.current;
|
|
1091
1469
|
const text = message.content.filter(
|
|
1092
1470
|
(part) => part.type === "text"
|
|
@@ -1111,21 +1489,22 @@ var MessageController = class {
|
|
|
1111
1489
|
return;
|
|
1112
1490
|
}
|
|
1113
1491
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1492
|
+
const namespace = this.config.getNamespace();
|
|
1114
1493
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1494
|
+
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1115
1495
|
try {
|
|
1116
1496
|
this.markRunning(threadId, true);
|
|
1117
|
-
const response =
|
|
1497
|
+
const response = await this.config.backendApiRef.current.postChatMessage(
|
|
1118
1498
|
backendThreadId,
|
|
1119
1499
|
text,
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
text
|
|
1500
|
+
namespace,
|
|
1501
|
+
publicKey,
|
|
1502
|
+
apiKey
|
|
1124
1503
|
);
|
|
1125
1504
|
if (response == null ? void 0 : response.messages) {
|
|
1126
1505
|
this.inbound(threadId, response.messages);
|
|
1127
1506
|
}
|
|
1128
|
-
if (((
|
|
1507
|
+
if (((_f = response == null ? void 0 : response.system_events) == null ? void 0 : _f.length) && this.config.onSyncEvents) {
|
|
1129
1508
|
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1130
1509
|
}
|
|
1131
1510
|
if (response == null ? void 0 : response.is_processing) {
|
|
@@ -1139,26 +1518,23 @@ var MessageController = class {
|
|
|
1139
1518
|
}
|
|
1140
1519
|
}
|
|
1141
1520
|
async flushPendingChat(threadId) {
|
|
1142
|
-
var _a, _b;
|
|
1521
|
+
var _a, _b, _c, _d, _e;
|
|
1143
1522
|
const backendState = this.config.backendStateRef.current;
|
|
1144
1523
|
const pending = dequeuePendingChat(backendState, threadId);
|
|
1145
1524
|
if (!pending.length) return;
|
|
1146
1525
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1526
|
+
const namespace = this.config.getNamespace();
|
|
1147
1527
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1528
|
+
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1148
1529
|
for (const text of pending) {
|
|
1149
1530
|
try {
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
await this.config.backendApiRef.current.postChatMessage(
|
|
1158
|
-
backendThreadId,
|
|
1159
|
-
text
|
|
1160
|
-
);
|
|
1161
|
-
}
|
|
1531
|
+
await this.config.backendApiRef.current.postChatMessage(
|
|
1532
|
+
backendThreadId,
|
|
1533
|
+
text,
|
|
1534
|
+
namespace,
|
|
1535
|
+
publicKey,
|
|
1536
|
+
apiKey
|
|
1537
|
+
);
|
|
1162
1538
|
} catch (error) {
|
|
1163
1539
|
console.error("Failed to send queued message:", error);
|
|
1164
1540
|
}
|
|
@@ -1197,7 +1573,7 @@ var MessageController = class {
|
|
|
1197
1573
|
}
|
|
1198
1574
|
};
|
|
1199
1575
|
|
|
1200
|
-
// src/runtime/polling-controller.ts
|
|
1576
|
+
// packages/react/src/runtime/polling-controller.ts
|
|
1201
1577
|
var PollingController = class {
|
|
1202
1578
|
constructor(config) {
|
|
1203
1579
|
this.config = config;
|
|
@@ -1268,18 +1644,18 @@ var PollingController = class {
|
|
|
1268
1644
|
}
|
|
1269
1645
|
};
|
|
1270
1646
|
|
|
1271
|
-
// src/runtime/orchestrator.ts
|
|
1647
|
+
// packages/react/src/runtime/orchestrator.ts
|
|
1272
1648
|
function useRuntimeOrchestrator(backendApi, options) {
|
|
1273
1649
|
const threadContext = useThreadContext();
|
|
1274
|
-
const threadContextRef = (0,
|
|
1650
|
+
const threadContextRef = (0, import_react6.useRef)(threadContext);
|
|
1275
1651
|
threadContextRef.current = threadContext;
|
|
1276
|
-
const backendApiRef = (0,
|
|
1652
|
+
const backendApiRef = (0, import_react6.useRef)(backendApi);
|
|
1277
1653
|
backendApiRef.current = backendApi;
|
|
1278
|
-
const backendStateRef = (0,
|
|
1279
|
-
const [isRunning, setIsRunning] = (0,
|
|
1280
|
-
const messageControllerRef = (0,
|
|
1281
|
-
const pollingRef = (0,
|
|
1282
|
-
const pendingFetches = (0,
|
|
1654
|
+
const backendStateRef = (0, import_react6.useRef)(createBackendState());
|
|
1655
|
+
const [isRunning, setIsRunning] = (0, import_react6.useState)(false);
|
|
1656
|
+
const messageControllerRef = (0, import_react6.useRef)(null);
|
|
1657
|
+
const pollingRef = (0, import_react6.useRef)(null);
|
|
1658
|
+
const pendingFetches = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1283
1659
|
if (!pollingRef.current) {
|
|
1284
1660
|
pollingRef.current = new PollingController({
|
|
1285
1661
|
backendApiRef,
|
|
@@ -1288,8 +1664,8 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1288
1664
|
var _a;
|
|
1289
1665
|
(_a = messageControllerRef.current) == null ? void 0 : _a.inbound(threadId, msgs);
|
|
1290
1666
|
},
|
|
1291
|
-
onSyncEvents: options
|
|
1292
|
-
getUserState: options
|
|
1667
|
+
onSyncEvents: options.onSyncEvents,
|
|
1668
|
+
getUserState: options.getUserState,
|
|
1293
1669
|
onStart: (threadId) => {
|
|
1294
1670
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1295
1671
|
setIsRunning(true);
|
|
@@ -1309,11 +1685,13 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1309
1685
|
threadContextRef,
|
|
1310
1686
|
polling: pollingRef.current,
|
|
1311
1687
|
setGlobalIsRunning: setIsRunning,
|
|
1312
|
-
getPublicKey: options
|
|
1313
|
-
|
|
1688
|
+
getPublicKey: options.getPublicKey,
|
|
1689
|
+
getNamespace: options.getNamespace,
|
|
1690
|
+
getApiKey: options.getApiKey,
|
|
1691
|
+
onSyncEvents: options.onSyncEvents
|
|
1314
1692
|
});
|
|
1315
1693
|
}
|
|
1316
|
-
const ensureInitialState = (0,
|
|
1694
|
+
const ensureInitialState = (0, import_react6.useCallback)(async (threadId) => {
|
|
1317
1695
|
var _a, _b, _c, _d;
|
|
1318
1696
|
const backendState = backendStateRef.current;
|
|
1319
1697
|
if (shouldSkipInitialFetch(backendState, threadId)) {
|
|
@@ -1333,13 +1711,13 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1333
1711
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1334
1712
|
pendingFetches.current.add(threadId);
|
|
1335
1713
|
try {
|
|
1336
|
-
const userState = (_a = options
|
|
1714
|
+
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1337
1715
|
const state = await backendApiRef.current.fetchState(
|
|
1338
1716
|
backendThreadId,
|
|
1339
1717
|
userState
|
|
1340
1718
|
);
|
|
1341
1719
|
(_b = messageControllerRef.current) == null ? void 0 : _b.inbound(threadId, state.messages);
|
|
1342
|
-
if (((_c = state.system_events) == null ? void 0 : _c.length) &&
|
|
1720
|
+
if (((_c = state.system_events) == null ? void 0 : _c.length) && options.onSyncEvents) {
|
|
1343
1721
|
options.onSyncEvents(backendThreadId, state.system_events);
|
|
1344
1722
|
}
|
|
1345
1723
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
@@ -1370,7 +1748,7 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1370
1748
|
};
|
|
1371
1749
|
}
|
|
1372
1750
|
|
|
1373
|
-
// src/runtime/threadlist-adapter.ts
|
|
1751
|
+
// packages/react/src/runtime/threadlist-adapter.ts
|
|
1374
1752
|
var sortByLastActiveDesc = ([, metaA], [, metaB]) => {
|
|
1375
1753
|
const tsA = parseTimestamp(metaA.lastActiveAt);
|
|
1376
1754
|
const tsB = parseTimestamp(metaB.lastActiveAt);
|
|
@@ -1403,7 +1781,9 @@ function buildThreadListAdapter({
|
|
|
1403
1781
|
currentThreadIdRef,
|
|
1404
1782
|
polling,
|
|
1405
1783
|
userAddress,
|
|
1406
|
-
setIsRunning
|
|
1784
|
+
setIsRunning,
|
|
1785
|
+
getNamespace,
|
|
1786
|
+
getApiKey
|
|
1407
1787
|
}) {
|
|
1408
1788
|
const backendState = backendStateRef.current;
|
|
1409
1789
|
const { regularThreads, archivedThreads } = buildThreadLists(
|
|
@@ -1431,7 +1811,8 @@ function buildThreadListAdapter({
|
|
|
1431
1811
|
(prev) => new Map(prev).set(threadId, {
|
|
1432
1812
|
title: "New Chat",
|
|
1433
1813
|
status: "pending",
|
|
1434
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1814
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1815
|
+
control: initThreadControl()
|
|
1435
1816
|
})
|
|
1436
1817
|
);
|
|
1437
1818
|
threadContext.setThreadMessages(threadId, []);
|
|
@@ -1458,15 +1839,13 @@ function buildThreadListAdapter({
|
|
|
1458
1839
|
return;
|
|
1459
1840
|
}
|
|
1460
1841
|
if (backendState.createThreadPromise) {
|
|
1461
|
-
preparePendingThread(
|
|
1462
|
-
(_a = backendState.creatingThreadId) != null ? _a : crypto.randomUUID()
|
|
1463
|
-
);
|
|
1842
|
+
preparePendingThread((_a = backendState.creatingThreadId) != null ? _a : generateUUID());
|
|
1464
1843
|
return;
|
|
1465
1844
|
}
|
|
1466
|
-
const threadId =
|
|
1845
|
+
const threadId = generateUUID();
|
|
1467
1846
|
preparePendingThread(threadId);
|
|
1468
1847
|
const createPromise = backendApiRef.current.createThread(threadId, userAddress).then(async (newThread) => {
|
|
1469
|
-
var _a2;
|
|
1848
|
+
var _a2, _b;
|
|
1470
1849
|
const uiThreadId = (_a2 = backendState.creatingThreadId) != null ? _a2 : threadId;
|
|
1471
1850
|
const backendId = newThread.session_id;
|
|
1472
1851
|
if (uiThreadId !== backendId) {
|
|
@@ -1477,14 +1856,15 @@ function buildThreadListAdapter({
|
|
|
1477
1856
|
}
|
|
1478
1857
|
markSkipInitialFetch(backendState, uiThreadId);
|
|
1479
1858
|
threadContext.setThreadMetadata((prev) => {
|
|
1480
|
-
var _a3,
|
|
1859
|
+
var _a3, _b2, _c;
|
|
1481
1860
|
const next = new Map(prev);
|
|
1482
1861
|
const existing = next.get(uiThreadId);
|
|
1483
1862
|
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1484
1863
|
next.set(uiThreadId, {
|
|
1485
1864
|
title: (_a3 = existing == null ? void 0 : existing.title) != null ? _a3 : "New Chat",
|
|
1486
1865
|
status: nextStatus,
|
|
1487
|
-
lastActiveAt: (
|
|
1866
|
+
lastActiveAt: (_b2 = existing == null ? void 0 : existing.lastActiveAt) != null ? _b2 : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1867
|
+
control: (_c = existing == null ? void 0 : existing.control) != null ? _c : initThreadControl()
|
|
1488
1868
|
});
|
|
1489
1869
|
return next;
|
|
1490
1870
|
});
|
|
@@ -1494,9 +1874,17 @@ function buildThreadListAdapter({
|
|
|
1494
1874
|
const pendingMessages = backendState.pendingChat.get(uiThreadId);
|
|
1495
1875
|
if (pendingMessages == null ? void 0 : pendingMessages.length) {
|
|
1496
1876
|
backendState.pendingChat.delete(uiThreadId);
|
|
1877
|
+
const namespace = getNamespace();
|
|
1878
|
+
const apiKey = (_b = getApiKey == null ? void 0 : getApiKey()) != null ? _b : void 0;
|
|
1497
1879
|
for (const text of pendingMessages) {
|
|
1498
1880
|
try {
|
|
1499
|
-
await backendApiRef.current.postChatMessage(
|
|
1881
|
+
await backendApiRef.current.postChatMessage(
|
|
1882
|
+
backendId,
|
|
1883
|
+
text,
|
|
1884
|
+
namespace,
|
|
1885
|
+
userAddress,
|
|
1886
|
+
apiKey
|
|
1887
|
+
);
|
|
1500
1888
|
} catch (error) {
|
|
1501
1889
|
console.error("Failed to send queued message:", error);
|
|
1502
1890
|
}
|
|
@@ -1595,7 +1983,8 @@ function buildThreadListAdapter({
|
|
|
1595
1983
|
(prev) => new Map(prev).set(defaultId, {
|
|
1596
1984
|
title: "New Chat",
|
|
1597
1985
|
status: "regular",
|
|
1598
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1986
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1987
|
+
control: initThreadControl()
|
|
1599
1988
|
})
|
|
1600
1989
|
);
|
|
1601
1990
|
threadContext.setThreadMessages(defaultId, []);
|
|
@@ -1610,12 +1999,12 @@ function buildThreadListAdapter({
|
|
|
1610
1999
|
};
|
|
1611
2000
|
}
|
|
1612
2001
|
|
|
1613
|
-
// src/interface.tsx
|
|
1614
|
-
var
|
|
1615
|
-
var AomiRuntimeContext = (0,
|
|
2002
|
+
// packages/react/src/interface.tsx
|
|
2003
|
+
var import_react7 = require("react");
|
|
2004
|
+
var AomiRuntimeContext = (0, import_react7.createContext)(null);
|
|
1616
2005
|
var AomiRuntimeApiProvider = AomiRuntimeContext.Provider;
|
|
1617
2006
|
function useAomiRuntime() {
|
|
1618
|
-
const context = (0,
|
|
2007
|
+
const context = (0, import_react7.useContext)(AomiRuntimeContext);
|
|
1619
2008
|
if (!context) {
|
|
1620
2009
|
throw new Error(
|
|
1621
2010
|
"useAomiRuntime must be used within AomiRuntimeProvider. Wrap your app with <AomiRuntimeProvider>...</AomiRuntimeProvider>"
|
|
@@ -1624,8 +2013,8 @@ function useAomiRuntime() {
|
|
|
1624
2013
|
return context;
|
|
1625
2014
|
}
|
|
1626
2015
|
|
|
1627
|
-
// src/runtime/core.tsx
|
|
1628
|
-
var
|
|
2016
|
+
// packages/react/src/runtime/core.tsx
|
|
2017
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1629
2018
|
function AomiRuntimeCore({
|
|
1630
2019
|
children,
|
|
1631
2020
|
backendApi
|
|
@@ -1635,6 +2024,7 @@ function AomiRuntimeCore({
|
|
|
1635
2024
|
const notificationContext = useNotification();
|
|
1636
2025
|
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1637
2026
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
2027
|
+
const { getControlState, getCurrentThreadControl } = useControl();
|
|
1638
2028
|
const {
|
|
1639
2029
|
backendStateRef,
|
|
1640
2030
|
polling,
|
|
@@ -1646,9 +2036,14 @@ function AomiRuntimeCore({
|
|
|
1646
2036
|
} = useRuntimeOrchestrator(backendApi, {
|
|
1647
2037
|
onSyncEvents: dispatchSystemEvents,
|
|
1648
2038
|
getPublicKey: () => getUserState().address,
|
|
1649
|
-
getUserState
|
|
2039
|
+
getUserState,
|
|
2040
|
+
getNamespace: () => {
|
|
2041
|
+
var _a, _b;
|
|
2042
|
+
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
2043
|
+
},
|
|
2044
|
+
getApiKey: () => getControlState().apiKey
|
|
1650
2045
|
});
|
|
1651
|
-
(0,
|
|
2046
|
+
(0, import_react8.useEffect)(() => {
|
|
1652
2047
|
const unsubscribe = onUserStateChange(async (newUser) => {
|
|
1653
2048
|
const sessionId = threadContext.currentThreadId;
|
|
1654
2049
|
const message = JSON.stringify({
|
|
@@ -1664,23 +2059,34 @@ function AomiRuntimeCore({
|
|
|
1664
2059
|
});
|
|
1665
2060
|
return unsubscribe;
|
|
1666
2061
|
}, [onUserStateChange, backendApiRef, threadContext.currentThreadId]);
|
|
1667
|
-
const threadContextRef = (0,
|
|
2062
|
+
const threadContextRef = (0, import_react8.useRef)(threadContext);
|
|
1668
2063
|
threadContextRef.current = threadContext;
|
|
1669
|
-
const currentThreadIdRef = (0,
|
|
1670
|
-
(0,
|
|
2064
|
+
const currentThreadIdRef = (0, import_react8.useRef)(threadContext.currentThreadId);
|
|
2065
|
+
(0, import_react8.useEffect)(() => {
|
|
1671
2066
|
currentThreadIdRef.current = threadContext.currentThreadId;
|
|
1672
2067
|
}, [threadContext.currentThreadId]);
|
|
1673
|
-
(0,
|
|
2068
|
+
(0, import_react8.useEffect)(() => {
|
|
1674
2069
|
void ensureInitialState(threadContext.currentThreadId);
|
|
1675
2070
|
}, [ensureInitialState, threadContext.currentThreadId]);
|
|
1676
|
-
(0,
|
|
2071
|
+
(0, import_react8.useEffect)(() => {
|
|
1677
2072
|
const threadId = threadContext.currentThreadId;
|
|
1678
2073
|
setIsRunning(isThreadRunning(backendStateRef.current, threadId));
|
|
1679
2074
|
}, [backendStateRef, setIsRunning, threadContext.currentThreadId]);
|
|
2075
|
+
(0, import_react8.useEffect)(() => {
|
|
2076
|
+
const threadId = threadContext.currentThreadId;
|
|
2077
|
+
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
2078
|
+
if (currentMeta && currentMeta.control.isProcessing !== isRunning) {
|
|
2079
|
+
threadContext.updateThreadMetadata(threadId, {
|
|
2080
|
+
control: __spreadProps(__spreadValues({}, currentMeta.control), {
|
|
2081
|
+
isProcessing: isRunning
|
|
2082
|
+
})
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
}, [isRunning, threadContext]);
|
|
1680
2086
|
const currentMessages = threadContext.getThreadMessages(
|
|
1681
2087
|
threadContext.currentThreadId
|
|
1682
2088
|
);
|
|
1683
|
-
const resolvedSessionId = (0,
|
|
2089
|
+
const resolvedSessionId = (0, import_react8.useMemo)(
|
|
1684
2090
|
() => resolveThreadId(backendStateRef.current, threadContext.currentThreadId),
|
|
1685
2091
|
[
|
|
1686
2092
|
backendStateRef,
|
|
@@ -1688,11 +2094,11 @@ function AomiRuntimeCore({
|
|
|
1688
2094
|
threadContext.allThreadsMetadata
|
|
1689
2095
|
]
|
|
1690
2096
|
);
|
|
1691
|
-
(0,
|
|
2097
|
+
(0, import_react8.useEffect)(() => {
|
|
1692
2098
|
const userAddress = user.address;
|
|
1693
2099
|
if (!userAddress) return;
|
|
1694
2100
|
const fetchThreadList = async () => {
|
|
1695
|
-
var _a, _b;
|
|
2101
|
+
var _a, _b, _c;
|
|
1696
2102
|
try {
|
|
1697
2103
|
const threadList = await backendApiRef.current.fetchThreads(userAddress);
|
|
1698
2104
|
const currentContext = threadContextRef.current;
|
|
@@ -1702,10 +2108,12 @@ function AomiRuntimeCore({
|
|
|
1702
2108
|
const rawTitle = (_a = thread.title) != null ? _a : "";
|
|
1703
2109
|
const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
|
|
1704
2110
|
const lastActive = ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
|
|
2111
|
+
const existingControl = (_c = newMetadata.get(thread.session_id)) == null ? void 0 : _c.control;
|
|
1705
2112
|
newMetadata.set(thread.session_id, {
|
|
1706
2113
|
title,
|
|
1707
2114
|
status: thread.is_archived ? "archived" : "regular",
|
|
1708
|
-
lastActiveAt: lastActive
|
|
2115
|
+
lastActiveAt: lastActive,
|
|
2116
|
+
control: existingControl != null ? existingControl : initThreadControl()
|
|
1709
2117
|
});
|
|
1710
2118
|
const match = title.match(/^Chat (\d+)$/);
|
|
1711
2119
|
if (match) {
|
|
@@ -1725,7 +2133,7 @@ function AomiRuntimeCore({
|
|
|
1725
2133
|
};
|
|
1726
2134
|
void fetchThreadList();
|
|
1727
2135
|
}, [user.address, backendApiRef]);
|
|
1728
|
-
const threadListAdapter = (0,
|
|
2136
|
+
const threadListAdapter = (0, import_react8.useMemo)(
|
|
1729
2137
|
() => buildThreadListAdapter({
|
|
1730
2138
|
backendStateRef,
|
|
1731
2139
|
backendApiRef,
|
|
@@ -1733,7 +2141,12 @@ function AomiRuntimeCore({
|
|
|
1733
2141
|
currentThreadIdRef,
|
|
1734
2142
|
polling,
|
|
1735
2143
|
userAddress: user.address,
|
|
1736
|
-
setIsRunning
|
|
2144
|
+
setIsRunning,
|
|
2145
|
+
getNamespace: () => {
|
|
2146
|
+
var _a, _b;
|
|
2147
|
+
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
2148
|
+
},
|
|
2149
|
+
getApiKey: () => getControlState().apiKey
|
|
1737
2150
|
}),
|
|
1738
2151
|
[
|
|
1739
2152
|
backendApiRef,
|
|
@@ -1743,10 +2156,11 @@ function AomiRuntimeCore({
|
|
|
1743
2156
|
setIsRunning,
|
|
1744
2157
|
threadContext,
|
|
1745
2158
|
threadContext.currentThreadId,
|
|
1746
|
-
threadContext.allThreadsMetadata
|
|
2159
|
+
threadContext.allThreadsMetadata,
|
|
2160
|
+
getControlState
|
|
1747
2161
|
]
|
|
1748
2162
|
);
|
|
1749
|
-
(0,
|
|
2163
|
+
(0, import_react8.useEffect)(() => {
|
|
1750
2164
|
const backendState = backendStateRef.current;
|
|
1751
2165
|
const currentSessionId = threadContext.currentThreadId;
|
|
1752
2166
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -1777,14 +2191,15 @@ function AomiRuntimeCore({
|
|
|
1777
2191
|
});
|
|
1778
2192
|
}
|
|
1779
2193
|
threadContextRef.current.setThreadMetadata((prev) => {
|
|
1780
|
-
var _a;
|
|
2194
|
+
var _a, _b;
|
|
1781
2195
|
const next = new Map(prev);
|
|
1782
2196
|
const existing = next.get(targetThreadId);
|
|
1783
2197
|
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1784
2198
|
next.set(targetThreadId, {
|
|
1785
2199
|
title: normalizedTitle,
|
|
1786
2200
|
status: nextStatus,
|
|
1787
|
-
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString()
|
|
2201
|
+
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
|
|
2202
|
+
control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
|
|
1788
2203
|
});
|
|
1789
2204
|
return next;
|
|
1790
2205
|
});
|
|
@@ -1803,12 +2218,12 @@ function AomiRuntimeCore({
|
|
|
1803
2218
|
threadContext.currentThreadId,
|
|
1804
2219
|
resolvedSessionId
|
|
1805
2220
|
]);
|
|
1806
|
-
(0,
|
|
2221
|
+
(0, import_react8.useEffect)(() => {
|
|
1807
2222
|
const threadId = threadContext.currentThreadId;
|
|
1808
2223
|
if (!isThreadReady(backendStateRef.current, threadId)) return;
|
|
1809
2224
|
void messageController.flushPendingChat(threadId);
|
|
1810
2225
|
}, [messageController, backendStateRef, threadContext.currentThreadId]);
|
|
1811
|
-
(0,
|
|
2226
|
+
(0, import_react8.useEffect)(() => {
|
|
1812
2227
|
const showToolNotification = (eventType) => (event) => {
|
|
1813
2228
|
const payload = event.payload;
|
|
1814
2229
|
const toolName = typeof (payload == null ? void 0 : payload.tool_name) === "string" ? payload.tool_name : void 0;
|
|
@@ -1833,19 +2248,14 @@ function AomiRuntimeCore({
|
|
|
1833
2248
|
unsubscribeComplete();
|
|
1834
2249
|
};
|
|
1835
2250
|
}, [eventContext, notificationContext]);
|
|
1836
|
-
(0,
|
|
2251
|
+
(0, import_react8.useEffect)(() => {
|
|
1837
2252
|
const unsubscribe = eventContext.subscribe("system_notice", (event) => {
|
|
1838
2253
|
const payload = event.payload;
|
|
1839
2254
|
const message = payload == null ? void 0 : payload.message;
|
|
1840
|
-
notificationContext.showNotification({
|
|
1841
|
-
type: "notice",
|
|
1842
|
-
title: "System notice",
|
|
1843
|
-
message
|
|
1844
|
-
});
|
|
1845
2255
|
});
|
|
1846
2256
|
return unsubscribe;
|
|
1847
2257
|
}, [eventContext, notificationContext]);
|
|
1848
|
-
const runtime = (0,
|
|
2258
|
+
const runtime = (0, import_react9.useExternalStoreRuntime)({
|
|
1849
2259
|
messages: currentMessages,
|
|
1850
2260
|
setMessages: (msgs) => threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),
|
|
1851
2261
|
isRunning,
|
|
@@ -1854,13 +2264,13 @@ function AomiRuntimeCore({
|
|
|
1854
2264
|
convertMessage: (msg) => msg,
|
|
1855
2265
|
adapters: { threadList: threadListAdapter }
|
|
1856
2266
|
});
|
|
1857
|
-
(0,
|
|
2267
|
+
(0, import_react8.useEffect)(() => {
|
|
1858
2268
|
return () => {
|
|
1859
2269
|
polling.stopAll();
|
|
1860
2270
|
};
|
|
1861
2271
|
}, [polling]);
|
|
1862
2272
|
const userContext = useUser();
|
|
1863
|
-
const sendMessage = (0,
|
|
2273
|
+
const sendMessage = (0, import_react8.useCallback)(
|
|
1864
2274
|
async (text) => {
|
|
1865
2275
|
const appendMessage = {
|
|
1866
2276
|
role: "user",
|
|
@@ -1873,39 +2283,39 @@ function AomiRuntimeCore({
|
|
|
1873
2283
|
},
|
|
1874
2284
|
[messageController, threadContext.currentThreadId]
|
|
1875
2285
|
);
|
|
1876
|
-
const cancelGeneration = (0,
|
|
2286
|
+
const cancelGeneration = (0, import_react8.useCallback)(() => {
|
|
1877
2287
|
messageController.cancel(threadContext.currentThreadId);
|
|
1878
2288
|
}, [messageController, threadContext.currentThreadId]);
|
|
1879
|
-
const getMessages = (0,
|
|
2289
|
+
const getMessages = (0, import_react8.useCallback)(
|
|
1880
2290
|
(threadId) => {
|
|
1881
2291
|
const id = threadId != null ? threadId : threadContext.currentThreadId;
|
|
1882
2292
|
return threadContext.getThreadMessages(id);
|
|
1883
2293
|
},
|
|
1884
2294
|
[threadContext]
|
|
1885
2295
|
);
|
|
1886
|
-
const createThread = (0,
|
|
2296
|
+
const createThread = (0, import_react8.useCallback)(async () => {
|
|
1887
2297
|
await threadListAdapter.onSwitchToNewThread();
|
|
1888
2298
|
return threadContextRef.current.currentThreadId;
|
|
1889
2299
|
}, [threadListAdapter]);
|
|
1890
|
-
const deleteThread = (0,
|
|
2300
|
+
const deleteThread = (0, import_react8.useCallback)(
|
|
1891
2301
|
async (threadId) => {
|
|
1892
2302
|
await threadListAdapter.onDelete(threadId);
|
|
1893
2303
|
},
|
|
1894
2304
|
[threadListAdapter]
|
|
1895
2305
|
);
|
|
1896
|
-
const renameThread = (0,
|
|
2306
|
+
const renameThread = (0, import_react8.useCallback)(
|
|
1897
2307
|
async (threadId, title) => {
|
|
1898
2308
|
await threadListAdapter.onRename(threadId, title);
|
|
1899
2309
|
},
|
|
1900
2310
|
[threadListAdapter]
|
|
1901
2311
|
);
|
|
1902
|
-
const archiveThread = (0,
|
|
2312
|
+
const archiveThread = (0, import_react8.useCallback)(
|
|
1903
2313
|
async (threadId) => {
|
|
1904
2314
|
await threadListAdapter.onArchive(threadId);
|
|
1905
2315
|
},
|
|
1906
2316
|
[threadListAdapter]
|
|
1907
2317
|
);
|
|
1908
|
-
const selectThread = (0,
|
|
2318
|
+
const selectThread = (0, import_react8.useCallback)(
|
|
1909
2319
|
(threadId) => {
|
|
1910
2320
|
if (threadContext.allThreadsMetadata.has(threadId)) {
|
|
1911
2321
|
threadListAdapter.onSwitchToThread(threadId);
|
|
@@ -1915,7 +2325,7 @@ function AomiRuntimeCore({
|
|
|
1915
2325
|
},
|
|
1916
2326
|
[threadContext.allThreadsMetadata, threadListAdapter]
|
|
1917
2327
|
);
|
|
1918
|
-
const aomiRuntimeApi = (0,
|
|
2328
|
+
const aomiRuntimeApi = (0, import_react8.useMemo)(
|
|
1919
2329
|
() => ({
|
|
1920
2330
|
// User API
|
|
1921
2331
|
user: userContext.user,
|
|
@@ -1966,45 +2376,57 @@ function AomiRuntimeCore({
|
|
|
1966
2376
|
eventContext
|
|
1967
2377
|
]
|
|
1968
2378
|
);
|
|
1969
|
-
return /* @__PURE__ */ (0,
|
|
2379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AomiRuntimeApiProvider, { value: aomiRuntimeApi, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react9.AssistantRuntimeProvider, { runtime, children }) });
|
|
1970
2380
|
}
|
|
1971
2381
|
|
|
1972
|
-
// src/runtime/aomi-runtime.tsx
|
|
1973
|
-
var
|
|
2382
|
+
// packages/react/src/runtime/aomi-runtime.tsx
|
|
2383
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1974
2384
|
function AomiRuntimeProvider({
|
|
1975
2385
|
children,
|
|
1976
2386
|
backendUrl = "http://localhost:8080"
|
|
1977
2387
|
}) {
|
|
1978
|
-
const backendApi = (0,
|
|
1979
|
-
return /* @__PURE__ */ (0,
|
|
2388
|
+
const backendApi = (0, import_react10.useMemo)(() => new BackendApi(backendUrl), [backendUrl]);
|
|
2389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThreadContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NotificationContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AomiRuntimeInner, { backendApi, children }) }) }) });
|
|
1980
2390
|
}
|
|
1981
2391
|
function AomiRuntimeInner({
|
|
1982
2392
|
children,
|
|
1983
2393
|
backendApi
|
|
1984
2394
|
}) {
|
|
2395
|
+
var _a;
|
|
1985
2396
|
const threadContext = useThreadContext();
|
|
1986
|
-
|
|
1987
|
-
|
|
2397
|
+
const { user } = useUser();
|
|
2398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2399
|
+
ControlContextProvider,
|
|
1988
2400
|
{
|
|
1989
2401
|
backendApi,
|
|
1990
2402
|
sessionId: threadContext.currentThreadId,
|
|
1991
|
-
|
|
2403
|
+
publicKey: (_a = user.address) != null ? _a : void 0,
|
|
2404
|
+
getThreadMetadata: threadContext.getThreadMetadata,
|
|
2405
|
+
updateThreadMetadata: threadContext.updateThreadMetadata,
|
|
2406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2407
|
+
EventContextProvider,
|
|
2408
|
+
{
|
|
2409
|
+
backendApi,
|
|
2410
|
+
sessionId: threadContext.currentThreadId,
|
|
2411
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AomiRuntimeCore, { backendApi, children })
|
|
2412
|
+
}
|
|
2413
|
+
)
|
|
1992
2414
|
}
|
|
1993
2415
|
);
|
|
1994
2416
|
}
|
|
1995
2417
|
|
|
1996
|
-
// src/handlers/wallet-handler.ts
|
|
1997
|
-
var
|
|
2418
|
+
// packages/react/src/handlers/wallet-handler.ts
|
|
2419
|
+
var import_react11 = require("react");
|
|
1998
2420
|
function useWalletHandler({
|
|
1999
2421
|
sessionId,
|
|
2000
2422
|
onTxRequest
|
|
2001
2423
|
}) {
|
|
2002
2424
|
const { subscribe: subscribe2, sendOutboundSystem: sendOutbound } = useEventContext();
|
|
2003
2425
|
const { setUser, getUserState } = useUser();
|
|
2004
|
-
const [pendingTxRequests, setPendingTxRequests] = (0,
|
|
2426
|
+
const [pendingTxRequests, setPendingTxRequests] = (0, import_react11.useState)(
|
|
2005
2427
|
[]
|
|
2006
2428
|
);
|
|
2007
|
-
(0,
|
|
2429
|
+
(0, import_react11.useEffect)(() => {
|
|
2008
2430
|
const unsubscribe = subscribe2(
|
|
2009
2431
|
"wallet_tx_request",
|
|
2010
2432
|
(event) => {
|
|
@@ -2015,7 +2437,7 @@ function useWalletHandler({
|
|
|
2015
2437
|
);
|
|
2016
2438
|
return unsubscribe;
|
|
2017
2439
|
}, [subscribe2, onTxRequest]);
|
|
2018
|
-
(0,
|
|
2440
|
+
(0, import_react11.useEffect)(() => {
|
|
2019
2441
|
const unsubscribe = subscribe2(
|
|
2020
2442
|
"user_state_request",
|
|
2021
2443
|
(event) => {
|
|
@@ -2028,7 +2450,7 @@ function useWalletHandler({
|
|
|
2028
2450
|
);
|
|
2029
2451
|
return unsubscribe;
|
|
2030
2452
|
}, [subscribe2, onTxRequest]);
|
|
2031
|
-
const sendTxComplete = (0,
|
|
2453
|
+
const sendTxComplete = (0, import_react11.useCallback)(
|
|
2032
2454
|
(tx) => {
|
|
2033
2455
|
sendOutbound({
|
|
2034
2456
|
type: "wallet:tx_complete",
|
|
@@ -2038,7 +2460,7 @@ function useWalletHandler({
|
|
|
2038
2460
|
},
|
|
2039
2461
|
[sendOutbound, sessionId]
|
|
2040
2462
|
);
|
|
2041
|
-
const sendConnectionChange = (0,
|
|
2463
|
+
const sendConnectionChange = (0, import_react11.useCallback)(
|
|
2042
2464
|
(status, address, chainId) => {
|
|
2043
2465
|
if (status === "connected") {
|
|
2044
2466
|
setUser({
|
|
@@ -2061,7 +2483,7 @@ function useWalletHandler({
|
|
|
2061
2483
|
},
|
|
2062
2484
|
[setUser, sendOutbound, sessionId]
|
|
2063
2485
|
);
|
|
2064
|
-
const clearTxRequest = (0,
|
|
2486
|
+
const clearTxRequest = (0, import_react11.useCallback)((index) => {
|
|
2065
2487
|
setPendingTxRequests((prev) => prev.filter((_, i) => i !== index));
|
|
2066
2488
|
}, []);
|
|
2067
2489
|
return {
|
|
@@ -2072,8 +2494,8 @@ function useWalletHandler({
|
|
|
2072
2494
|
};
|
|
2073
2495
|
}
|
|
2074
2496
|
|
|
2075
|
-
// src/handlers/notification-handler.ts
|
|
2076
|
-
var
|
|
2497
|
+
// packages/react/src/handlers/notification-handler.ts
|
|
2498
|
+
var import_react12 = require("react");
|
|
2077
2499
|
var notificationIdCounter2 = 0;
|
|
2078
2500
|
function generateNotificationId() {
|
|
2079
2501
|
return `notif-${Date.now()}-${++notificationIdCounter2}`;
|
|
@@ -2082,8 +2504,8 @@ function useNotificationHandler({
|
|
|
2082
2504
|
onNotification
|
|
2083
2505
|
} = {}) {
|
|
2084
2506
|
const { subscribe: subscribe2 } = useEventContext();
|
|
2085
|
-
const [notifications, setNotifications] = (0,
|
|
2086
|
-
(0,
|
|
2507
|
+
const [notifications, setNotifications] = (0, import_react12.useState)([]);
|
|
2508
|
+
(0, import_react12.useEffect)(() => {
|
|
2087
2509
|
const unsubscribe = subscribe2("notification", (event) => {
|
|
2088
2510
|
var _a, _b;
|
|
2089
2511
|
const payload = event.payload;
|
|
@@ -2102,7 +2524,7 @@ function useNotificationHandler({
|
|
|
2102
2524
|
return unsubscribe;
|
|
2103
2525
|
}, [subscribe2, onNotification]);
|
|
2104
2526
|
const unhandledCount = notifications.filter((n) => !n.handled).length;
|
|
2105
|
-
const markHandled = (0,
|
|
2527
|
+
const markHandled = (0, import_react12.useCallback)((id) => {
|
|
2106
2528
|
setNotifications(
|
|
2107
2529
|
(prev) => prev.map((n) => n.id === id ? __spreadProps(__spreadValues({}, n), { handled: true }) : n)
|
|
2108
2530
|
);
|
|
@@ -2117,6 +2539,7 @@ function useNotificationHandler({
|
|
|
2117
2539
|
0 && (module.exports = {
|
|
2118
2540
|
AomiRuntimeProvider,
|
|
2119
2541
|
BackendApi,
|
|
2542
|
+
ControlContextProvider,
|
|
2120
2543
|
EventContextProvider,
|
|
2121
2544
|
NotificationContextProvider,
|
|
2122
2545
|
ThreadContextProvider,
|
|
@@ -2124,7 +2547,9 @@ function useNotificationHandler({
|
|
|
2124
2547
|
cn,
|
|
2125
2548
|
formatAddress,
|
|
2126
2549
|
getNetworkName,
|
|
2550
|
+
initThreadControl,
|
|
2127
2551
|
useAomiRuntime,
|
|
2552
|
+
useControl,
|
|
2128
2553
|
useCurrentThreadMessages,
|
|
2129
2554
|
useCurrentThreadMetadata,
|
|
2130
2555
|
useEventContext,
|