@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.js
CHANGED
|
@@ -18,7 +18,7 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
20
|
|
|
21
|
-
// src/backend/sse.ts
|
|
21
|
+
// packages/react/src/backend/sse.ts
|
|
22
22
|
function extractSseData(rawEvent) {
|
|
23
23
|
const dataLines = rawEvent.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart());
|
|
24
24
|
if (!dataLines.length) return null;
|
|
@@ -204,8 +204,9 @@ function createSseSubscriber({
|
|
|
204
204
|
return { subscribe: subscribe2 };
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
// src/backend/client.ts
|
|
207
|
+
// packages/react/src/backend/client.ts
|
|
208
208
|
var SESSION_ID_HEADER = "X-Session-Id";
|
|
209
|
+
var API_KEY_HEADER = "X-API-Key";
|
|
209
210
|
function toQueryString(payload) {
|
|
210
211
|
const params = new URLSearchParams();
|
|
211
212
|
for (const [key, value] of Object.entries(payload)) {
|
|
@@ -220,12 +221,16 @@ function withSessionHeader(sessionId, init) {
|
|
|
220
221
|
headers.set(SESSION_ID_HEADER, sessionId);
|
|
221
222
|
return headers;
|
|
222
223
|
}
|
|
223
|
-
async function postState(backendUrl, path, payload, sessionId) {
|
|
224
|
+
async function postState(backendUrl, path, payload, sessionId, apiKey) {
|
|
224
225
|
const query = toQueryString(payload);
|
|
225
226
|
const url = `${backendUrl}${path}${query}`;
|
|
227
|
+
const headers = new Headers(withSessionHeader(sessionId));
|
|
228
|
+
if (apiKey) {
|
|
229
|
+
headers.set(API_KEY_HEADER, apiKey);
|
|
230
|
+
}
|
|
226
231
|
const response = await fetch(url, {
|
|
227
232
|
method: "POST",
|
|
228
|
-
headers
|
|
233
|
+
headers
|
|
229
234
|
});
|
|
230
235
|
if (!response.ok) {
|
|
231
236
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -253,15 +258,17 @@ var BackendApi = class {
|
|
|
253
258
|
}
|
|
254
259
|
return await response.json();
|
|
255
260
|
}
|
|
256
|
-
async postChatMessage(sessionId, message, publicKey) {
|
|
261
|
+
async postChatMessage(sessionId, message, namespace, publicKey, apiKey) {
|
|
262
|
+
const payload = { message, namespace };
|
|
263
|
+
if (publicKey) {
|
|
264
|
+
payload.public_key = publicKey;
|
|
265
|
+
}
|
|
257
266
|
return postState(
|
|
258
267
|
this.backendUrl,
|
|
259
268
|
"/api/chat",
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
},
|
|
264
|
-
sessionId
|
|
269
|
+
payload,
|
|
270
|
+
sessionId,
|
|
271
|
+
apiKey
|
|
265
272
|
);
|
|
266
273
|
}
|
|
267
274
|
async postSystemMessage(sessionId, message) {
|
|
@@ -379,25 +386,551 @@ var BackendApi = class {
|
|
|
379
386
|
if (response.status === 404) return [];
|
|
380
387
|
throw new Error(`Failed to get system events: HTTP ${response.status}`);
|
|
381
388
|
}
|
|
382
|
-
return await response.json();
|
|
383
|
-
}
|
|
384
|
-
//
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
+
return await response.json();
|
|
390
|
+
}
|
|
391
|
+
// ===========================================================================
|
|
392
|
+
// Control API
|
|
393
|
+
// ===========================================================================
|
|
394
|
+
/**
|
|
395
|
+
* Get allowed namespaces for the current request context.
|
|
396
|
+
*/
|
|
397
|
+
async getNamespaces(sessionId, publicKey, apiKey) {
|
|
398
|
+
const url = new URL("/api/control/namespaces", this.backendUrl);
|
|
399
|
+
if (publicKey) {
|
|
400
|
+
url.searchParams.set("public_key", publicKey);
|
|
401
|
+
}
|
|
402
|
+
console.log("[BackendApi.getNamespaces]", {
|
|
403
|
+
backendUrl: this.backendUrl,
|
|
404
|
+
fullUrl: url.toString(),
|
|
405
|
+
sessionId,
|
|
406
|
+
publicKey
|
|
407
|
+
});
|
|
408
|
+
const headers = new Headers(withSessionHeader(sessionId));
|
|
409
|
+
if (apiKey) {
|
|
410
|
+
headers.set(API_KEY_HEADER, apiKey);
|
|
411
|
+
}
|
|
412
|
+
const response = await fetch(url.toString(), { headers });
|
|
413
|
+
if (!response.ok) {
|
|
414
|
+
throw new Error(`Failed to get namespaces: HTTP ${response.status}`);
|
|
415
|
+
}
|
|
416
|
+
return await response.json();
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Get available models.
|
|
420
|
+
*/
|
|
421
|
+
async getModels(sessionId) {
|
|
422
|
+
const url = new URL("/api/control/models", this.backendUrl);
|
|
423
|
+
console.log("[BackendApi.getModels]", {
|
|
424
|
+
backendUrl: this.backendUrl,
|
|
425
|
+
fullUrl: url.toString(),
|
|
426
|
+
sessionId
|
|
427
|
+
});
|
|
428
|
+
const response = await fetch(url.toString(), {
|
|
429
|
+
headers: withSessionHeader(sessionId)
|
|
430
|
+
});
|
|
431
|
+
if (!response.ok) {
|
|
432
|
+
throw new Error(`Failed to get models: HTTP ${response.status}`);
|
|
433
|
+
}
|
|
434
|
+
return await response.json();
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Set the model selection for a session.
|
|
438
|
+
*/
|
|
439
|
+
async setModel(sessionId, rig, namespace, apiKey) {
|
|
440
|
+
const payload = { rig };
|
|
441
|
+
if (namespace) {
|
|
442
|
+
payload.namespace = namespace;
|
|
443
|
+
}
|
|
444
|
+
return postState(this.backendUrl, "/api/control/model", payload, sessionId, apiKey);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// packages/react/src/runtime/aomi-runtime.tsx
|
|
449
|
+
import { useMemo as useMemo3 } from "react";
|
|
450
|
+
|
|
451
|
+
// packages/react/src/contexts/control-context.tsx
|
|
452
|
+
import {
|
|
453
|
+
createContext,
|
|
454
|
+
useCallback,
|
|
455
|
+
useContext,
|
|
456
|
+
useRef,
|
|
457
|
+
useState,
|
|
458
|
+
useEffect
|
|
459
|
+
} from "react";
|
|
460
|
+
|
|
461
|
+
// packages/react/src/utils/uuid.ts
|
|
462
|
+
function generateUUID() {
|
|
463
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
464
|
+
return crypto.randomUUID();
|
|
465
|
+
}
|
|
466
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
467
|
+
const r = Math.random() * 16 | 0;
|
|
468
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
469
|
+
return v.toString(16);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// packages/react/src/state/thread-store.ts
|
|
474
|
+
var shouldLogThreadUpdates = process.env.NODE_ENV !== "production";
|
|
475
|
+
var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
476
|
+
if (!shouldLogThreadUpdates) return;
|
|
477
|
+
if (!prev && !next) return;
|
|
478
|
+
if (!prev || !next) {
|
|
479
|
+
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (prev.title !== next.title || prev.status !== next.status || prev.lastActiveAt !== next.lastActiveAt) {
|
|
483
|
+
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
function initThreadControl() {
|
|
487
|
+
return {
|
|
488
|
+
model: null,
|
|
489
|
+
namespace: null,
|
|
490
|
+
controlDirty: false,
|
|
491
|
+
isProcessing: false
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
var ThreadStore = class {
|
|
495
|
+
constructor(options) {
|
|
496
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
497
|
+
this.subscribe = (listener) => {
|
|
498
|
+
this.listeners.add(listener);
|
|
499
|
+
return () => {
|
|
500
|
+
this.listeners.delete(listener);
|
|
501
|
+
};
|
|
502
|
+
};
|
|
503
|
+
this.getSnapshot = () => this.snapshot;
|
|
504
|
+
this.setCurrentThreadId = (threadId) => {
|
|
505
|
+
this.ensureThreadExists(threadId);
|
|
506
|
+
this.updateState({ currentThreadId: threadId });
|
|
507
|
+
};
|
|
508
|
+
this.bumpThreadViewKey = () => {
|
|
509
|
+
this.updateState({ threadViewKey: this.state.threadViewKey + 1 });
|
|
510
|
+
};
|
|
511
|
+
this.setThreadCnt = (updater) => {
|
|
512
|
+
const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);
|
|
513
|
+
this.updateState({ threadCnt: nextCnt });
|
|
514
|
+
};
|
|
515
|
+
this.setThreads = (updater) => {
|
|
516
|
+
const nextThreads = this.resolveStateAction(updater, this.state.threads);
|
|
517
|
+
this.updateState({ threads: new Map(nextThreads) });
|
|
518
|
+
};
|
|
519
|
+
this.setThreadMetadata = (updater) => {
|
|
520
|
+
const prevMetadata = this.state.threadMetadata;
|
|
521
|
+
const nextMetadata = this.resolveStateAction(updater, prevMetadata);
|
|
522
|
+
for (const [threadId, next] of nextMetadata.entries()) {
|
|
523
|
+
logThreadMetadataChange(
|
|
524
|
+
"setThreadMetadata",
|
|
525
|
+
threadId,
|
|
526
|
+
prevMetadata.get(threadId),
|
|
527
|
+
next
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
for (const [threadId, prev] of prevMetadata.entries()) {
|
|
531
|
+
if (!nextMetadata.has(threadId)) {
|
|
532
|
+
logThreadMetadataChange("setThreadMetadata", threadId, prev, void 0);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
this.updateState({ threadMetadata: new Map(nextMetadata) });
|
|
536
|
+
};
|
|
537
|
+
this.setThreadMessages = (threadId, messages) => {
|
|
538
|
+
this.ensureThreadExists(threadId);
|
|
539
|
+
const nextThreads = new Map(this.state.threads);
|
|
540
|
+
nextThreads.set(threadId, messages);
|
|
541
|
+
this.updateState({ threads: nextThreads });
|
|
542
|
+
};
|
|
543
|
+
this.getThreadMessages = (threadId) => {
|
|
544
|
+
var _a;
|
|
545
|
+
return (_a = this.state.threads.get(threadId)) != null ? _a : [];
|
|
546
|
+
};
|
|
547
|
+
this.getThreadMetadata = (threadId) => {
|
|
548
|
+
return this.state.threadMetadata.get(threadId);
|
|
549
|
+
};
|
|
550
|
+
this.updateThreadMetadata = (threadId, updates) => {
|
|
551
|
+
const existing = this.state.threadMetadata.get(threadId);
|
|
552
|
+
if (!existing) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const next = __spreadValues(__spreadValues({}, existing), updates);
|
|
556
|
+
const nextMetadata = new Map(this.state.threadMetadata);
|
|
557
|
+
nextMetadata.set(threadId, next);
|
|
558
|
+
logThreadMetadataChange("updateThreadMetadata", threadId, existing, next);
|
|
559
|
+
this.updateState({ threadMetadata: nextMetadata });
|
|
560
|
+
};
|
|
561
|
+
var _a;
|
|
562
|
+
const initialThreadId = (_a = options == null ? void 0 : options.initialThreadId) != null ? _a : generateUUID();
|
|
563
|
+
this.state = {
|
|
564
|
+
currentThreadId: initialThreadId,
|
|
565
|
+
threadViewKey: 0,
|
|
566
|
+
threadCnt: 1,
|
|
567
|
+
threads: /* @__PURE__ */ new Map([[initialThreadId, []]]),
|
|
568
|
+
threadMetadata: /* @__PURE__ */ new Map([
|
|
569
|
+
[
|
|
570
|
+
initialThreadId,
|
|
571
|
+
{
|
|
572
|
+
title: "New Chat",
|
|
573
|
+
status: "pending",
|
|
574
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
575
|
+
control: initThreadControl()
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
])
|
|
579
|
+
};
|
|
580
|
+
this.snapshot = this.buildSnapshot();
|
|
581
|
+
}
|
|
582
|
+
emit() {
|
|
583
|
+
for (const listener of this.listeners) {
|
|
584
|
+
listener();
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
resolveStateAction(updater, current) {
|
|
588
|
+
return typeof updater === "function" ? updater(current) : updater;
|
|
589
|
+
}
|
|
590
|
+
ensureThreadExists(threadId) {
|
|
591
|
+
if (!this.state.threadMetadata.has(threadId)) {
|
|
592
|
+
const nextMetadata = new Map(this.state.threadMetadata);
|
|
593
|
+
nextMetadata.set(threadId, {
|
|
594
|
+
title: "New Chat",
|
|
595
|
+
status: "regular",
|
|
596
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
597
|
+
control: initThreadControl()
|
|
598
|
+
});
|
|
599
|
+
this.state = __spreadProps(__spreadValues({}, this.state), { threadMetadata: nextMetadata });
|
|
600
|
+
}
|
|
601
|
+
if (!this.state.threads.has(threadId)) {
|
|
602
|
+
const nextThreads = new Map(this.state.threads);
|
|
603
|
+
nextThreads.set(threadId, []);
|
|
604
|
+
this.state = __spreadProps(__spreadValues({}, this.state), { threads: nextThreads });
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
updateState(partial) {
|
|
608
|
+
this.state = __spreadValues(__spreadValues({}, this.state), partial);
|
|
609
|
+
this.snapshot = this.buildSnapshot();
|
|
610
|
+
this.emit();
|
|
611
|
+
}
|
|
612
|
+
buildSnapshot() {
|
|
613
|
+
return {
|
|
614
|
+
currentThreadId: this.state.currentThreadId,
|
|
615
|
+
setCurrentThreadId: this.setCurrentThreadId,
|
|
616
|
+
threadViewKey: this.state.threadViewKey,
|
|
617
|
+
bumpThreadViewKey: this.bumpThreadViewKey,
|
|
618
|
+
allThreads: this.state.threads,
|
|
619
|
+
setThreads: this.setThreads,
|
|
620
|
+
allThreadsMetadata: this.state.threadMetadata,
|
|
621
|
+
setThreadMetadata: this.setThreadMetadata,
|
|
622
|
+
threadCnt: this.state.threadCnt,
|
|
623
|
+
setThreadCnt: this.setThreadCnt,
|
|
624
|
+
getThreadMessages: this.getThreadMessages,
|
|
625
|
+
setThreadMessages: this.setThreadMessages,
|
|
626
|
+
getThreadMetadata: this.getThreadMetadata,
|
|
627
|
+
updateThreadMetadata: this.updateThreadMetadata
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// packages/react/src/contexts/control-context.tsx
|
|
633
|
+
import { jsx } from "react/jsx-runtime";
|
|
634
|
+
var API_KEY_STORAGE_KEY = "aomi_api_key";
|
|
635
|
+
var ControlContext = createContext(null);
|
|
636
|
+
function useControl() {
|
|
637
|
+
const ctx = useContext(ControlContext);
|
|
638
|
+
if (!ctx) {
|
|
639
|
+
throw new Error("useControl must be used within ControlContextProvider");
|
|
640
|
+
}
|
|
641
|
+
return ctx;
|
|
642
|
+
}
|
|
643
|
+
function ControlContextProvider({
|
|
644
|
+
children,
|
|
645
|
+
backendApi,
|
|
646
|
+
sessionId,
|
|
647
|
+
publicKey,
|
|
648
|
+
getThreadMetadata,
|
|
649
|
+
updateThreadMetadata
|
|
650
|
+
}) {
|
|
651
|
+
var _a, _b;
|
|
652
|
+
const [state, setStateInternal] = useState(() => ({
|
|
653
|
+
apiKey: null,
|
|
654
|
+
availableModels: [],
|
|
655
|
+
authorizedNamespaces: [],
|
|
656
|
+
defaultModel: null,
|
|
657
|
+
defaultNamespace: null
|
|
658
|
+
}));
|
|
659
|
+
const stateRef = useRef(state);
|
|
660
|
+
stateRef.current = state;
|
|
661
|
+
const backendApiRef = useRef(backendApi);
|
|
662
|
+
backendApiRef.current = backendApi;
|
|
663
|
+
const sessionIdRef = useRef(sessionId);
|
|
664
|
+
sessionIdRef.current = sessionId;
|
|
665
|
+
const publicKeyRef = useRef(publicKey);
|
|
666
|
+
publicKeyRef.current = publicKey;
|
|
667
|
+
const getThreadMetadataRef = useRef(getThreadMetadata);
|
|
668
|
+
getThreadMetadataRef.current = getThreadMetadata;
|
|
669
|
+
const updateThreadMetadataRef = useRef(updateThreadMetadata);
|
|
670
|
+
updateThreadMetadataRef.current = updateThreadMetadata;
|
|
671
|
+
const callbacks = useRef(/* @__PURE__ */ new Set());
|
|
672
|
+
const currentThreadMetadata = getThreadMetadata(sessionId);
|
|
673
|
+
const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
|
|
674
|
+
useEffect(() => {
|
|
675
|
+
var _a2, _b2;
|
|
676
|
+
try {
|
|
677
|
+
const storedApiKey = (_b2 = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(API_KEY_STORAGE_KEY)) != null ? _b2 : null;
|
|
678
|
+
if (storedApiKey) {
|
|
679
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { apiKey: storedApiKey }));
|
|
680
|
+
}
|
|
681
|
+
} catch (e) {
|
|
682
|
+
}
|
|
683
|
+
}, []);
|
|
684
|
+
useEffect(() => {
|
|
685
|
+
var _a2, _b2;
|
|
686
|
+
try {
|
|
687
|
+
if (state.apiKey) {
|
|
688
|
+
(_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(API_KEY_STORAGE_KEY, state.apiKey);
|
|
689
|
+
} else {
|
|
690
|
+
(_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(API_KEY_STORAGE_KEY);
|
|
691
|
+
}
|
|
692
|
+
} catch (e) {
|
|
693
|
+
}
|
|
694
|
+
}, [state.apiKey]);
|
|
695
|
+
useEffect(() => {
|
|
696
|
+
const fetchNamespaces = async () => {
|
|
697
|
+
var _a2, _b2;
|
|
698
|
+
try {
|
|
699
|
+
const namespaces = await backendApiRef.current.getNamespaces(
|
|
700
|
+
sessionIdRef.current,
|
|
701
|
+
publicKeyRef.current,
|
|
702
|
+
(_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
703
|
+
);
|
|
704
|
+
const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
|
|
705
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
706
|
+
authorizedNamespaces: namespaces,
|
|
707
|
+
defaultNamespace: defaultNs
|
|
708
|
+
}));
|
|
709
|
+
} catch (error) {
|
|
710
|
+
console.error("Failed to fetch namespaces:", error);
|
|
711
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
712
|
+
authorizedNamespaces: ["default"],
|
|
713
|
+
defaultNamespace: "default"
|
|
714
|
+
}));
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
void fetchNamespaces();
|
|
718
|
+
}, [state.apiKey]);
|
|
719
|
+
useEffect(() => {
|
|
720
|
+
const fetchModels = async () => {
|
|
721
|
+
try {
|
|
722
|
+
const models = await backendApiRef.current.getModels(
|
|
723
|
+
sessionIdRef.current
|
|
724
|
+
);
|
|
725
|
+
setStateInternal((prev) => {
|
|
726
|
+
var _a2;
|
|
727
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
728
|
+
availableModels: models,
|
|
729
|
+
defaultModel: (_a2 = models[0]) != null ? _a2 : null
|
|
730
|
+
});
|
|
731
|
+
});
|
|
732
|
+
} catch (error) {
|
|
733
|
+
console.error("Failed to fetch models:", error);
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
void fetchModels();
|
|
737
|
+
}, []);
|
|
738
|
+
const setApiKey = useCallback((apiKey) => {
|
|
739
|
+
setStateInternal((prev) => {
|
|
740
|
+
const next = __spreadProps(__spreadValues({}, prev), { apiKey: apiKey === "" ? null : apiKey });
|
|
741
|
+
callbacks.current.forEach((cb) => cb(next));
|
|
742
|
+
return next;
|
|
743
|
+
});
|
|
744
|
+
}, []);
|
|
745
|
+
const getAvailableModels = useCallback(async () => {
|
|
746
|
+
try {
|
|
747
|
+
const models = await backendApiRef.current.getModels(
|
|
748
|
+
sessionIdRef.current
|
|
749
|
+
);
|
|
750
|
+
setStateInternal((prev) => {
|
|
751
|
+
var _a2, _b2;
|
|
752
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
753
|
+
availableModels: models,
|
|
754
|
+
defaultModel: (_b2 = (_a2 = prev.defaultModel) != null ? _a2 : models[0]) != null ? _b2 : null
|
|
755
|
+
});
|
|
756
|
+
});
|
|
757
|
+
return models;
|
|
758
|
+
} catch (error) {
|
|
759
|
+
console.error("Failed to fetch models:", error);
|
|
760
|
+
return [];
|
|
761
|
+
}
|
|
762
|
+
}, []);
|
|
763
|
+
const getAuthorizedNamespaces = useCallback(async () => {
|
|
764
|
+
var _a2, _b2;
|
|
765
|
+
try {
|
|
766
|
+
const namespaces = await backendApiRef.current.getNamespaces(
|
|
767
|
+
sessionIdRef.current,
|
|
768
|
+
publicKeyRef.current,
|
|
769
|
+
(_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
770
|
+
);
|
|
771
|
+
const defaultNs = namespaces.includes("default") ? "default" : (_b2 = namespaces[0]) != null ? _b2 : null;
|
|
772
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
773
|
+
authorizedNamespaces: namespaces,
|
|
774
|
+
defaultNamespace: defaultNs
|
|
775
|
+
}));
|
|
776
|
+
return namespaces;
|
|
777
|
+
} catch (error) {
|
|
778
|
+
console.error("Failed to fetch namespaces:", error);
|
|
779
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
780
|
+
authorizedNamespaces: ["default"],
|
|
781
|
+
defaultNamespace: "default"
|
|
782
|
+
}));
|
|
783
|
+
return ["default"];
|
|
784
|
+
}
|
|
785
|
+
}, []);
|
|
786
|
+
const getCurrentThreadControl = useCallback(() => {
|
|
787
|
+
var _a2;
|
|
788
|
+
const metadata = getThreadMetadataRef.current(sessionIdRef.current);
|
|
789
|
+
return (_a2 = metadata == null ? void 0 : metadata.control) != null ? _a2 : initThreadControl();
|
|
790
|
+
}, []);
|
|
791
|
+
const onModelSelect = useCallback(async (model) => {
|
|
792
|
+
var _a2, _b2, _c, _d, _e;
|
|
793
|
+
const threadId = sessionIdRef.current;
|
|
794
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
795
|
+
const isProcessing2 = currentControl.isProcessing;
|
|
796
|
+
console.log("[control-context] onModelSelect called", {
|
|
797
|
+
model,
|
|
798
|
+
isProcessing: isProcessing2,
|
|
799
|
+
threadId
|
|
800
|
+
});
|
|
801
|
+
if (isProcessing2) {
|
|
802
|
+
console.warn("[control-context] Cannot switch model while processing");
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
const namespace = (_d = (_c = currentControl.namespace) != null ? _c : stateRef.current.defaultNamespace) != null ? _d : "default";
|
|
806
|
+
console.log("[control-context] onModelSelect updating metadata", {
|
|
807
|
+
threadId,
|
|
808
|
+
model,
|
|
809
|
+
namespace,
|
|
810
|
+
currentControl
|
|
811
|
+
});
|
|
812
|
+
updateThreadMetadataRef.current(threadId, {
|
|
813
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
814
|
+
model,
|
|
815
|
+
namespace,
|
|
816
|
+
controlDirty: true
|
|
817
|
+
})
|
|
818
|
+
});
|
|
819
|
+
console.log("[control-context] onModelSelect calling backend setModel", {
|
|
820
|
+
threadId,
|
|
821
|
+
model,
|
|
822
|
+
namespace,
|
|
823
|
+
backendUrl: backendApiRef.current
|
|
824
|
+
});
|
|
825
|
+
try {
|
|
826
|
+
const result = await backendApiRef.current.setModel(
|
|
827
|
+
threadId,
|
|
828
|
+
model,
|
|
829
|
+
namespace,
|
|
830
|
+
(_e = stateRef.current.apiKey) != null ? _e : void 0
|
|
831
|
+
);
|
|
832
|
+
console.log("[control-context] onModelSelect backend result", result);
|
|
833
|
+
} catch (err) {
|
|
834
|
+
console.error("[control-context] setModel failed:", err);
|
|
835
|
+
throw err;
|
|
836
|
+
}
|
|
837
|
+
}, []);
|
|
838
|
+
const onNamespaceSelect = useCallback((namespace) => {
|
|
839
|
+
var _a2, _b2;
|
|
840
|
+
const threadId = sessionIdRef.current;
|
|
841
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
842
|
+
const isProcessing2 = currentControl.isProcessing;
|
|
843
|
+
console.log("[control-context] onNamespaceSelect called", {
|
|
844
|
+
namespace,
|
|
845
|
+
isProcessing: isProcessing2,
|
|
846
|
+
threadId
|
|
847
|
+
});
|
|
848
|
+
if (isProcessing2) {
|
|
849
|
+
console.warn(
|
|
850
|
+
"[control-context] Cannot switch namespace while processing"
|
|
851
|
+
);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
console.log("[control-context] onNamespaceSelect updating metadata", {
|
|
855
|
+
threadId,
|
|
856
|
+
namespace,
|
|
857
|
+
currentControl
|
|
858
|
+
});
|
|
859
|
+
updateThreadMetadataRef.current(threadId, {
|
|
860
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
861
|
+
namespace,
|
|
862
|
+
controlDirty: true
|
|
863
|
+
})
|
|
864
|
+
});
|
|
865
|
+
console.log("[control-context] onNamespaceSelect metadata updated");
|
|
866
|
+
}, []);
|
|
867
|
+
const markControlSynced = useCallback(() => {
|
|
868
|
+
var _a2, _b2;
|
|
869
|
+
const threadId = sessionIdRef.current;
|
|
870
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
871
|
+
if (currentControl.controlDirty) {
|
|
872
|
+
updateThreadMetadataRef.current(threadId, {
|
|
873
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
874
|
+
controlDirty: false
|
|
875
|
+
})
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
}, []);
|
|
879
|
+
const getControlState = useCallback(() => stateRef.current, []);
|
|
880
|
+
const onControlStateChange = useCallback(
|
|
881
|
+
(callback) => {
|
|
882
|
+
callbacks.current.add(callback);
|
|
883
|
+
return () => {
|
|
884
|
+
callbacks.current.delete(callback);
|
|
885
|
+
};
|
|
886
|
+
},
|
|
887
|
+
[]
|
|
888
|
+
);
|
|
889
|
+
const setState = useCallback(
|
|
890
|
+
(updates) => {
|
|
891
|
+
var _a2;
|
|
892
|
+
if ("apiKey" in updates) {
|
|
893
|
+
setApiKey((_a2 = updates.apiKey) != null ? _a2 : null);
|
|
894
|
+
}
|
|
895
|
+
if ("namespace" in updates && updates.namespace !== void 0 && updates.namespace !== null) {
|
|
896
|
+
onNamespaceSelect(updates.namespace);
|
|
897
|
+
}
|
|
898
|
+
},
|
|
899
|
+
[setApiKey, onNamespaceSelect]
|
|
900
|
+
);
|
|
901
|
+
return /* @__PURE__ */ jsx(
|
|
902
|
+
ControlContext.Provider,
|
|
903
|
+
{
|
|
904
|
+
value: {
|
|
905
|
+
state,
|
|
906
|
+
setApiKey,
|
|
907
|
+
getAvailableModels,
|
|
908
|
+
getAuthorizedNamespaces,
|
|
909
|
+
getCurrentThreadControl,
|
|
910
|
+
onModelSelect,
|
|
911
|
+
onNamespaceSelect,
|
|
912
|
+
isProcessing,
|
|
913
|
+
markControlSynced,
|
|
914
|
+
getControlState,
|
|
915
|
+
onControlStateChange,
|
|
916
|
+
setState
|
|
917
|
+
},
|
|
918
|
+
children
|
|
919
|
+
}
|
|
920
|
+
);
|
|
921
|
+
}
|
|
389
922
|
|
|
390
|
-
// src/contexts/event-context.tsx
|
|
923
|
+
// packages/react/src/contexts/event-context.tsx
|
|
391
924
|
import {
|
|
392
|
-
createContext,
|
|
393
|
-
useCallback,
|
|
394
|
-
useContext,
|
|
395
|
-
useEffect,
|
|
396
|
-
useRef,
|
|
397
|
-
useState
|
|
925
|
+
createContext as createContext2,
|
|
926
|
+
useCallback as useCallback2,
|
|
927
|
+
useContext as useContext2,
|
|
928
|
+
useEffect as useEffect2,
|
|
929
|
+
useRef as useRef2,
|
|
930
|
+
useState as useState2
|
|
398
931
|
} from "react";
|
|
399
932
|
|
|
400
|
-
// src/backend/types.ts
|
|
933
|
+
// packages/react/src/backend/types.ts
|
|
401
934
|
function isInlineCall(event) {
|
|
402
935
|
return "InlineCall" in event;
|
|
403
936
|
}
|
|
@@ -411,7 +944,7 @@ function isAsyncCallback(event) {
|
|
|
411
944
|
return "AsyncCallback" in event;
|
|
412
945
|
}
|
|
413
946
|
|
|
414
|
-
// src/state/event-buffer.ts
|
|
947
|
+
// packages/react/src/state/event-buffer.ts
|
|
415
948
|
function createEventBuffer() {
|
|
416
949
|
return {
|
|
417
950
|
inboundQueue: [],
|
|
@@ -455,11 +988,11 @@ function setSSEStatus(state, status) {
|
|
|
455
988
|
state.sseStatus = status;
|
|
456
989
|
}
|
|
457
990
|
|
|
458
|
-
// src/contexts/event-context.tsx
|
|
459
|
-
import { jsx } from "react/jsx-runtime";
|
|
460
|
-
var EventContextState =
|
|
991
|
+
// packages/react/src/contexts/event-context.tsx
|
|
992
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
993
|
+
var EventContextState = createContext2(null);
|
|
461
994
|
function useEventContext() {
|
|
462
|
-
const context =
|
|
995
|
+
const context = useContext2(EventContextState);
|
|
463
996
|
if (!context) {
|
|
464
997
|
throw new Error(
|
|
465
998
|
"useEventContext must be used within EventContextProvider. Wrap your app with <EventContextProvider>...</EventContextProvider>"
|
|
@@ -472,13 +1005,13 @@ function EventContextProvider({
|
|
|
472
1005
|
backendApi,
|
|
473
1006
|
sessionId
|
|
474
1007
|
}) {
|
|
475
|
-
const bufferRef =
|
|
1008
|
+
const bufferRef = useRef2(null);
|
|
476
1009
|
if (!bufferRef.current) {
|
|
477
1010
|
bufferRef.current = createEventBuffer();
|
|
478
1011
|
}
|
|
479
1012
|
const buffer = bufferRef.current;
|
|
480
|
-
const [sseStatus, setSseStatus] =
|
|
481
|
-
|
|
1013
|
+
const [sseStatus, setSseStatus] = useState2("disconnected");
|
|
1014
|
+
useEffect2(() => {
|
|
482
1015
|
setSSEStatus(buffer, "connecting");
|
|
483
1016
|
setSseStatus("connecting");
|
|
484
1017
|
const unsubscribe = backendApi.subscribeSSE(
|
|
@@ -512,13 +1045,13 @@ function EventContextProvider({
|
|
|
512
1045
|
setSseStatus("disconnected");
|
|
513
1046
|
};
|
|
514
1047
|
}, [backendApi, sessionId, buffer]);
|
|
515
|
-
const subscribeCallback =
|
|
1048
|
+
const subscribeCallback = useCallback2(
|
|
516
1049
|
(type, callback) => {
|
|
517
1050
|
return subscribe(buffer, type, callback);
|
|
518
1051
|
},
|
|
519
1052
|
[buffer]
|
|
520
1053
|
);
|
|
521
|
-
const sendOutbound =
|
|
1054
|
+
const sendOutbound = useCallback2(
|
|
522
1055
|
async (event) => {
|
|
523
1056
|
try {
|
|
524
1057
|
const message = JSON.stringify({
|
|
@@ -532,7 +1065,7 @@ function EventContextProvider({
|
|
|
532
1065
|
},
|
|
533
1066
|
[backendApi]
|
|
534
1067
|
);
|
|
535
|
-
const dispatchSystemEvents =
|
|
1068
|
+
const dispatchSystemEvents = useCallback2(
|
|
536
1069
|
(sessionId2, events) => {
|
|
537
1070
|
var _a;
|
|
538
1071
|
for (const event of events) {
|
|
@@ -577,20 +1110,20 @@ function EventContextProvider({
|
|
|
577
1110
|
dispatchInboundSystem: dispatchSystemEvents,
|
|
578
1111
|
sseStatus
|
|
579
1112
|
};
|
|
580
|
-
return /* @__PURE__ */
|
|
1113
|
+
return /* @__PURE__ */ jsx2(EventContextState.Provider, { value: contextValue, children });
|
|
581
1114
|
}
|
|
582
1115
|
|
|
583
|
-
// src/contexts/notification-context.tsx
|
|
1116
|
+
// packages/react/src/contexts/notification-context.tsx
|
|
584
1117
|
import {
|
|
585
|
-
createContext as
|
|
586
|
-
useCallback as
|
|
587
|
-
useContext as
|
|
588
|
-
useState as
|
|
1118
|
+
createContext as createContext3,
|
|
1119
|
+
useCallback as useCallback3,
|
|
1120
|
+
useContext as useContext3,
|
|
1121
|
+
useState as useState3
|
|
589
1122
|
} from "react";
|
|
590
|
-
import { jsx as
|
|
591
|
-
var NotificationContext =
|
|
1123
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1124
|
+
var NotificationContext = createContext3(null);
|
|
592
1125
|
function useNotification() {
|
|
593
|
-
const context =
|
|
1126
|
+
const context = useContext3(NotificationContext);
|
|
594
1127
|
if (!context) {
|
|
595
1128
|
throw new Error(
|
|
596
1129
|
"useNotification must be used within NotificationContextProvider"
|
|
@@ -605,8 +1138,8 @@ function generateId() {
|
|
|
605
1138
|
function NotificationContextProvider({
|
|
606
1139
|
children
|
|
607
1140
|
}) {
|
|
608
|
-
const [notifications, setNotifications] =
|
|
609
|
-
const showNotification =
|
|
1141
|
+
const [notifications, setNotifications] = useState3([]);
|
|
1142
|
+
const showNotification = useCallback3((params) => {
|
|
610
1143
|
const id = generateId();
|
|
611
1144
|
const notification = __spreadProps(__spreadValues({}, params), {
|
|
612
1145
|
id,
|
|
@@ -615,10 +1148,10 @@ function NotificationContextProvider({
|
|
|
615
1148
|
setNotifications((prev) => [notification, ...prev]);
|
|
616
1149
|
return id;
|
|
617
1150
|
}, []);
|
|
618
|
-
const dismissNotification =
|
|
1151
|
+
const dismissNotification = useCallback3((id) => {
|
|
619
1152
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
620
1153
|
}, []);
|
|
621
|
-
const clearAll =
|
|
1154
|
+
const clearAll = useCallback3(() => {
|
|
622
1155
|
setNotifications([]);
|
|
623
1156
|
}, []);
|
|
624
1157
|
const value = {
|
|
@@ -627,172 +1160,21 @@ function NotificationContextProvider({
|
|
|
627
1160
|
dismissNotification,
|
|
628
1161
|
clearAll
|
|
629
1162
|
};
|
|
630
|
-
return /* @__PURE__ */
|
|
1163
|
+
return /* @__PURE__ */ jsx3(NotificationContext.Provider, { value, children });
|
|
631
1164
|
}
|
|
632
1165
|
|
|
633
|
-
// src/contexts/thread-context.tsx
|
|
1166
|
+
// packages/react/src/contexts/thread-context.tsx
|
|
634
1167
|
import {
|
|
635
|
-
createContext as
|
|
636
|
-
useContext as
|
|
1168
|
+
createContext as createContext4,
|
|
1169
|
+
useContext as useContext4,
|
|
637
1170
|
useMemo,
|
|
638
|
-
useRef as
|
|
1171
|
+
useRef as useRef3,
|
|
639
1172
|
useSyncExternalStore
|
|
640
1173
|
} from "react";
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
var shouldLogThreadUpdates = process.env.NODE_ENV !== "production";
|
|
644
|
-
var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
645
|
-
if (!shouldLogThreadUpdates) return;
|
|
646
|
-
if (!prev && !next) return;
|
|
647
|
-
if (!prev || !next) {
|
|
648
|
-
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
if (prev.title !== next.title || prev.status !== next.status || prev.lastActiveAt !== next.lastActiveAt) {
|
|
652
|
-
console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
var ThreadStore = class {
|
|
656
|
-
constructor(options) {
|
|
657
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
658
|
-
this.subscribe = (listener) => {
|
|
659
|
-
this.listeners.add(listener);
|
|
660
|
-
return () => {
|
|
661
|
-
this.listeners.delete(listener);
|
|
662
|
-
};
|
|
663
|
-
};
|
|
664
|
-
this.getSnapshot = () => this.snapshot;
|
|
665
|
-
this.setCurrentThreadId = (threadId) => {
|
|
666
|
-
this.ensureThreadExists(threadId);
|
|
667
|
-
this.updateState({ currentThreadId: threadId });
|
|
668
|
-
};
|
|
669
|
-
this.bumpThreadViewKey = () => {
|
|
670
|
-
this.updateState({ threadViewKey: this.state.threadViewKey + 1 });
|
|
671
|
-
};
|
|
672
|
-
this.setThreadCnt = (updater) => {
|
|
673
|
-
const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);
|
|
674
|
-
this.updateState({ threadCnt: nextCnt });
|
|
675
|
-
};
|
|
676
|
-
this.setThreads = (updater) => {
|
|
677
|
-
const nextThreads = this.resolveStateAction(updater, this.state.threads);
|
|
678
|
-
this.updateState({ threads: new Map(nextThreads) });
|
|
679
|
-
};
|
|
680
|
-
this.setThreadMetadata = (updater) => {
|
|
681
|
-
const prevMetadata = this.state.threadMetadata;
|
|
682
|
-
const nextMetadata = this.resolveStateAction(updater, prevMetadata);
|
|
683
|
-
for (const [threadId, next] of nextMetadata.entries()) {
|
|
684
|
-
logThreadMetadataChange(
|
|
685
|
-
"setThreadMetadata",
|
|
686
|
-
threadId,
|
|
687
|
-
prevMetadata.get(threadId),
|
|
688
|
-
next
|
|
689
|
-
);
|
|
690
|
-
}
|
|
691
|
-
for (const [threadId, prev] of prevMetadata.entries()) {
|
|
692
|
-
if (!nextMetadata.has(threadId)) {
|
|
693
|
-
logThreadMetadataChange("setThreadMetadata", threadId, prev, void 0);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
this.updateState({ threadMetadata: new Map(nextMetadata) });
|
|
697
|
-
};
|
|
698
|
-
this.setThreadMessages = (threadId, messages) => {
|
|
699
|
-
this.ensureThreadExists(threadId);
|
|
700
|
-
const nextThreads = new Map(this.state.threads);
|
|
701
|
-
nextThreads.set(threadId, messages);
|
|
702
|
-
this.updateState({ threads: nextThreads });
|
|
703
|
-
};
|
|
704
|
-
this.getThreadMessages = (threadId) => {
|
|
705
|
-
var _a;
|
|
706
|
-
return (_a = this.state.threads.get(threadId)) != null ? _a : [];
|
|
707
|
-
};
|
|
708
|
-
this.getThreadMetadata = (threadId) => {
|
|
709
|
-
return this.state.threadMetadata.get(threadId);
|
|
710
|
-
};
|
|
711
|
-
this.updateThreadMetadata = (threadId, updates) => {
|
|
712
|
-
const existing = this.state.threadMetadata.get(threadId);
|
|
713
|
-
if (!existing) {
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
const next = __spreadValues(__spreadValues({}, existing), updates);
|
|
717
|
-
const nextMetadata = new Map(this.state.threadMetadata);
|
|
718
|
-
nextMetadata.set(threadId, next);
|
|
719
|
-
logThreadMetadataChange("updateThreadMetadata", threadId, existing, next);
|
|
720
|
-
this.updateState({ threadMetadata: nextMetadata });
|
|
721
|
-
};
|
|
722
|
-
var _a;
|
|
723
|
-
const initialThreadId = (_a = options == null ? void 0 : options.initialThreadId) != null ? _a : crypto.randomUUID();
|
|
724
|
-
this.state = {
|
|
725
|
-
currentThreadId: initialThreadId,
|
|
726
|
-
threadViewKey: 0,
|
|
727
|
-
threadCnt: 1,
|
|
728
|
-
threads: /* @__PURE__ */ new Map([[initialThreadId, []]]),
|
|
729
|
-
threadMetadata: /* @__PURE__ */ new Map([
|
|
730
|
-
[
|
|
731
|
-
initialThreadId,
|
|
732
|
-
{
|
|
733
|
-
title: "New Chat",
|
|
734
|
-
status: "pending",
|
|
735
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
736
|
-
}
|
|
737
|
-
]
|
|
738
|
-
])
|
|
739
|
-
};
|
|
740
|
-
this.snapshot = this.buildSnapshot();
|
|
741
|
-
}
|
|
742
|
-
emit() {
|
|
743
|
-
for (const listener of this.listeners) {
|
|
744
|
-
listener();
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
resolveStateAction(updater, current) {
|
|
748
|
-
return typeof updater === "function" ? updater(current) : updater;
|
|
749
|
-
}
|
|
750
|
-
ensureThreadExists(threadId) {
|
|
751
|
-
if (!this.state.threadMetadata.has(threadId)) {
|
|
752
|
-
const nextMetadata = new Map(this.state.threadMetadata);
|
|
753
|
-
nextMetadata.set(threadId, {
|
|
754
|
-
title: "New Chat",
|
|
755
|
-
status: "regular",
|
|
756
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
757
|
-
});
|
|
758
|
-
this.state = __spreadProps(__spreadValues({}, this.state), { threadMetadata: nextMetadata });
|
|
759
|
-
}
|
|
760
|
-
if (!this.state.threads.has(threadId)) {
|
|
761
|
-
const nextThreads = new Map(this.state.threads);
|
|
762
|
-
nextThreads.set(threadId, []);
|
|
763
|
-
this.state = __spreadProps(__spreadValues({}, this.state), { threads: nextThreads });
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
updateState(partial) {
|
|
767
|
-
this.state = __spreadValues(__spreadValues({}, this.state), partial);
|
|
768
|
-
this.snapshot = this.buildSnapshot();
|
|
769
|
-
this.emit();
|
|
770
|
-
}
|
|
771
|
-
buildSnapshot() {
|
|
772
|
-
return {
|
|
773
|
-
currentThreadId: this.state.currentThreadId,
|
|
774
|
-
setCurrentThreadId: this.setCurrentThreadId,
|
|
775
|
-
threadViewKey: this.state.threadViewKey,
|
|
776
|
-
bumpThreadViewKey: this.bumpThreadViewKey,
|
|
777
|
-
allThreads: this.state.threads,
|
|
778
|
-
setThreads: this.setThreads,
|
|
779
|
-
allThreadsMetadata: this.state.threadMetadata,
|
|
780
|
-
setThreadMetadata: this.setThreadMetadata,
|
|
781
|
-
threadCnt: this.state.threadCnt,
|
|
782
|
-
setThreadCnt: this.setThreadCnt,
|
|
783
|
-
getThreadMessages: this.getThreadMessages,
|
|
784
|
-
setThreadMessages: this.setThreadMessages,
|
|
785
|
-
getThreadMetadata: this.getThreadMetadata,
|
|
786
|
-
updateThreadMetadata: this.updateThreadMetadata
|
|
787
|
-
};
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
// src/contexts/thread-context.tsx
|
|
792
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
793
|
-
var ThreadContextState = createContext3(null);
|
|
1174
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1175
|
+
var ThreadContextState = createContext4(null);
|
|
794
1176
|
function useThreadContext() {
|
|
795
|
-
const context =
|
|
1177
|
+
const context = useContext4(ThreadContextState);
|
|
796
1178
|
if (!context) {
|
|
797
1179
|
throw new Error(
|
|
798
1180
|
"useThreadContext must be used within ThreadContextProvider. Wrap your app with <ThreadContextProvider>...</ThreadContextProvider>"
|
|
@@ -804,7 +1186,7 @@ function ThreadContextProvider({
|
|
|
804
1186
|
children,
|
|
805
1187
|
initialThreadId
|
|
806
1188
|
}) {
|
|
807
|
-
const storeRef =
|
|
1189
|
+
const storeRef = useRef3(null);
|
|
808
1190
|
if (!storeRef.current) {
|
|
809
1191
|
storeRef.current = new ThreadStore({ initialThreadId });
|
|
810
1192
|
}
|
|
@@ -814,7 +1196,7 @@ function ThreadContextProvider({
|
|
|
814
1196
|
store.getSnapshot,
|
|
815
1197
|
store.getSnapshot
|
|
816
1198
|
);
|
|
817
|
-
return /* @__PURE__ */
|
|
1199
|
+
return /* @__PURE__ */ jsx4(ThreadContextState.Provider, { value, children });
|
|
818
1200
|
}
|
|
819
1201
|
function useCurrentThreadMessages() {
|
|
820
1202
|
const { currentThreadId, getThreadMessages } = useThreadContext();
|
|
@@ -831,18 +1213,18 @@ function useCurrentThreadMetadata() {
|
|
|
831
1213
|
);
|
|
832
1214
|
}
|
|
833
1215
|
|
|
834
|
-
// src/contexts/user-context.tsx
|
|
1216
|
+
// packages/react/src/contexts/user-context.tsx
|
|
835
1217
|
import {
|
|
836
|
-
createContext as
|
|
837
|
-
useCallback as
|
|
838
|
-
useContext as
|
|
839
|
-
useRef as
|
|
840
|
-
useState as
|
|
1218
|
+
createContext as createContext5,
|
|
1219
|
+
useCallback as useCallback4,
|
|
1220
|
+
useContext as useContext5,
|
|
1221
|
+
useRef as useRef4,
|
|
1222
|
+
useState as useState4
|
|
841
1223
|
} from "react";
|
|
842
|
-
import { jsx as
|
|
843
|
-
var UserContext =
|
|
1224
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1225
|
+
var UserContext = createContext5(void 0);
|
|
844
1226
|
function useUser() {
|
|
845
|
-
const context =
|
|
1227
|
+
const context = useContext5(UserContext);
|
|
846
1228
|
if (!context) {
|
|
847
1229
|
throw new Error("useUser must be used within UserContextProvider");
|
|
848
1230
|
}
|
|
@@ -854,18 +1236,18 @@ function useUser() {
|
|
|
854
1236
|
};
|
|
855
1237
|
}
|
|
856
1238
|
function UserContextProvider({ children }) {
|
|
857
|
-
const [user, setUserState] =
|
|
1239
|
+
const [user, setUserState] = useState4({
|
|
858
1240
|
isConnected: false,
|
|
859
1241
|
address: void 0,
|
|
860
1242
|
chainId: void 0,
|
|
861
1243
|
ensName: void 0
|
|
862
1244
|
});
|
|
863
|
-
const userRef =
|
|
1245
|
+
const userRef = useRef4(user);
|
|
864
1246
|
userRef.current = user;
|
|
865
|
-
const StateChangeCallbacks =
|
|
1247
|
+
const StateChangeCallbacks = useRef4(
|
|
866
1248
|
/* @__PURE__ */ new Set()
|
|
867
1249
|
);
|
|
868
|
-
const setUser =
|
|
1250
|
+
const setUser = useCallback4((data) => {
|
|
869
1251
|
setUserState((prev) => {
|
|
870
1252
|
const next = __spreadValues(__spreadValues({}, prev), data);
|
|
871
1253
|
StateChangeCallbacks.current.forEach((callback) => {
|
|
@@ -874,8 +1256,8 @@ function UserContextProvider({ children }) {
|
|
|
874
1256
|
return next;
|
|
875
1257
|
});
|
|
876
1258
|
}, []);
|
|
877
|
-
const getUserState =
|
|
878
|
-
const onUserStateChange =
|
|
1259
|
+
const getUserState = useCallback4(() => userRef.current, []);
|
|
1260
|
+
const onUserStateChange = useCallback4(
|
|
879
1261
|
(callback) => {
|
|
880
1262
|
StateChangeCallbacks.current.add(callback);
|
|
881
1263
|
return () => {
|
|
@@ -884,7 +1266,7 @@ function UserContextProvider({ children }) {
|
|
|
884
1266
|
},
|
|
885
1267
|
[]
|
|
886
1268
|
);
|
|
887
|
-
return /* @__PURE__ */
|
|
1269
|
+
return /* @__PURE__ */ jsx5(
|
|
888
1270
|
UserContext.Provider,
|
|
889
1271
|
{
|
|
890
1272
|
value: {
|
|
@@ -898,17 +1280,17 @@ function UserContextProvider({ children }) {
|
|
|
898
1280
|
);
|
|
899
1281
|
}
|
|
900
1282
|
|
|
901
|
-
// src/runtime/core.tsx
|
|
902
|
-
import { useCallback as
|
|
1283
|
+
// packages/react/src/runtime/core.tsx
|
|
1284
|
+
import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef6 } from "react";
|
|
903
1285
|
import {
|
|
904
1286
|
AssistantRuntimeProvider,
|
|
905
1287
|
useExternalStoreRuntime
|
|
906
1288
|
} from "@assistant-ui/react";
|
|
907
1289
|
|
|
908
|
-
// src/runtime/orchestrator.ts
|
|
909
|
-
import { useCallback as
|
|
1290
|
+
// packages/react/src/runtime/orchestrator.ts
|
|
1291
|
+
import { useCallback as useCallback5, useRef as useRef5, useState as useState5 } from "react";
|
|
910
1292
|
|
|
911
|
-
// src/runtime/utils.ts
|
|
1293
|
+
// packages/react/src/runtime/utils.ts
|
|
912
1294
|
import { clsx } from "clsx";
|
|
913
1295
|
import { twMerge } from "tailwind-merge";
|
|
914
1296
|
function cn(...inputs) {
|
|
@@ -1001,7 +1383,7 @@ var getNetworkName = (chainId) => {
|
|
|
1001
1383
|
};
|
|
1002
1384
|
var formatAddress = (addr) => addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : "Connect Wallet";
|
|
1003
1385
|
|
|
1004
|
-
// src/state/backend-state.ts
|
|
1386
|
+
// packages/react/src/state/backend-state.ts
|
|
1005
1387
|
function createBackendState() {
|
|
1006
1388
|
return {
|
|
1007
1389
|
skipInitialFetch: /* @__PURE__ */ new Set(),
|
|
@@ -1052,7 +1434,7 @@ function hasPendingChat(state, threadId) {
|
|
|
1052
1434
|
return ((_b = (_a = state.pendingChat.get(threadId)) == null ? void 0 : _a.length) != null ? _b : 0) > 0;
|
|
1053
1435
|
}
|
|
1054
1436
|
|
|
1055
|
-
// src/runtime/message-controller.ts
|
|
1437
|
+
// packages/react/src/runtime/message-controller.ts
|
|
1056
1438
|
var MessageController = class {
|
|
1057
1439
|
constructor(config) {
|
|
1058
1440
|
this.config = config;
|
|
@@ -1073,7 +1455,7 @@ var MessageController = class {
|
|
|
1073
1455
|
this.getThreadContextApi().setThreadMessages(threadId, threadMessages);
|
|
1074
1456
|
}
|
|
1075
1457
|
async outbound(message, threadId) {
|
|
1076
|
-
var _a, _b, _c;
|
|
1458
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1077
1459
|
const backendState = this.config.backendStateRef.current;
|
|
1078
1460
|
const text = message.content.filter(
|
|
1079
1461
|
(part) => part.type === "text"
|
|
@@ -1098,21 +1480,22 @@ var MessageController = class {
|
|
|
1098
1480
|
return;
|
|
1099
1481
|
}
|
|
1100
1482
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1483
|
+
const namespace = this.config.getNamespace();
|
|
1101
1484
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1485
|
+
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1102
1486
|
try {
|
|
1103
1487
|
this.markRunning(threadId, true);
|
|
1104
|
-
const response =
|
|
1488
|
+
const response = await this.config.backendApiRef.current.postChatMessage(
|
|
1105
1489
|
backendThreadId,
|
|
1106
1490
|
text,
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
text
|
|
1491
|
+
namespace,
|
|
1492
|
+
publicKey,
|
|
1493
|
+
apiKey
|
|
1111
1494
|
);
|
|
1112
1495
|
if (response == null ? void 0 : response.messages) {
|
|
1113
1496
|
this.inbound(threadId, response.messages);
|
|
1114
1497
|
}
|
|
1115
|
-
if (((
|
|
1498
|
+
if (((_f = response == null ? void 0 : response.system_events) == null ? void 0 : _f.length) && this.config.onSyncEvents) {
|
|
1116
1499
|
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1117
1500
|
}
|
|
1118
1501
|
if (response == null ? void 0 : response.is_processing) {
|
|
@@ -1126,26 +1509,23 @@ var MessageController = class {
|
|
|
1126
1509
|
}
|
|
1127
1510
|
}
|
|
1128
1511
|
async flushPendingChat(threadId) {
|
|
1129
|
-
var _a, _b;
|
|
1512
|
+
var _a, _b, _c, _d, _e;
|
|
1130
1513
|
const backendState = this.config.backendStateRef.current;
|
|
1131
1514
|
const pending = dequeuePendingChat(backendState, threadId);
|
|
1132
1515
|
if (!pending.length) return;
|
|
1133
1516
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1517
|
+
const namespace = this.config.getNamespace();
|
|
1134
1518
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1519
|
+
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1135
1520
|
for (const text of pending) {
|
|
1136
1521
|
try {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
await this.config.backendApiRef.current.postChatMessage(
|
|
1145
|
-
backendThreadId,
|
|
1146
|
-
text
|
|
1147
|
-
);
|
|
1148
|
-
}
|
|
1522
|
+
await this.config.backendApiRef.current.postChatMessage(
|
|
1523
|
+
backendThreadId,
|
|
1524
|
+
text,
|
|
1525
|
+
namespace,
|
|
1526
|
+
publicKey,
|
|
1527
|
+
apiKey
|
|
1528
|
+
);
|
|
1149
1529
|
} catch (error) {
|
|
1150
1530
|
console.error("Failed to send queued message:", error);
|
|
1151
1531
|
}
|
|
@@ -1184,7 +1564,7 @@ var MessageController = class {
|
|
|
1184
1564
|
}
|
|
1185
1565
|
};
|
|
1186
1566
|
|
|
1187
|
-
// src/runtime/polling-controller.ts
|
|
1567
|
+
// packages/react/src/runtime/polling-controller.ts
|
|
1188
1568
|
var PollingController = class {
|
|
1189
1569
|
constructor(config) {
|
|
1190
1570
|
this.config = config;
|
|
@@ -1255,18 +1635,18 @@ var PollingController = class {
|
|
|
1255
1635
|
}
|
|
1256
1636
|
};
|
|
1257
1637
|
|
|
1258
|
-
// src/runtime/orchestrator.ts
|
|
1638
|
+
// packages/react/src/runtime/orchestrator.ts
|
|
1259
1639
|
function useRuntimeOrchestrator(backendApi, options) {
|
|
1260
1640
|
const threadContext = useThreadContext();
|
|
1261
|
-
const threadContextRef =
|
|
1641
|
+
const threadContextRef = useRef5(threadContext);
|
|
1262
1642
|
threadContextRef.current = threadContext;
|
|
1263
|
-
const backendApiRef =
|
|
1643
|
+
const backendApiRef = useRef5(backendApi);
|
|
1264
1644
|
backendApiRef.current = backendApi;
|
|
1265
|
-
const backendStateRef =
|
|
1266
|
-
const [isRunning, setIsRunning] =
|
|
1267
|
-
const messageControllerRef =
|
|
1268
|
-
const pollingRef =
|
|
1269
|
-
const pendingFetches =
|
|
1645
|
+
const backendStateRef = useRef5(createBackendState());
|
|
1646
|
+
const [isRunning, setIsRunning] = useState5(false);
|
|
1647
|
+
const messageControllerRef = useRef5(null);
|
|
1648
|
+
const pollingRef = useRef5(null);
|
|
1649
|
+
const pendingFetches = useRef5(/* @__PURE__ */ new Set());
|
|
1270
1650
|
if (!pollingRef.current) {
|
|
1271
1651
|
pollingRef.current = new PollingController({
|
|
1272
1652
|
backendApiRef,
|
|
@@ -1275,8 +1655,8 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1275
1655
|
var _a;
|
|
1276
1656
|
(_a = messageControllerRef.current) == null ? void 0 : _a.inbound(threadId, msgs);
|
|
1277
1657
|
},
|
|
1278
|
-
onSyncEvents: options
|
|
1279
|
-
getUserState: options
|
|
1658
|
+
onSyncEvents: options.onSyncEvents,
|
|
1659
|
+
getUserState: options.getUserState,
|
|
1280
1660
|
onStart: (threadId) => {
|
|
1281
1661
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1282
1662
|
setIsRunning(true);
|
|
@@ -1296,11 +1676,13 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1296
1676
|
threadContextRef,
|
|
1297
1677
|
polling: pollingRef.current,
|
|
1298
1678
|
setGlobalIsRunning: setIsRunning,
|
|
1299
|
-
getPublicKey: options
|
|
1300
|
-
|
|
1679
|
+
getPublicKey: options.getPublicKey,
|
|
1680
|
+
getNamespace: options.getNamespace,
|
|
1681
|
+
getApiKey: options.getApiKey,
|
|
1682
|
+
onSyncEvents: options.onSyncEvents
|
|
1301
1683
|
});
|
|
1302
1684
|
}
|
|
1303
|
-
const ensureInitialState =
|
|
1685
|
+
const ensureInitialState = useCallback5(async (threadId) => {
|
|
1304
1686
|
var _a, _b, _c, _d;
|
|
1305
1687
|
const backendState = backendStateRef.current;
|
|
1306
1688
|
if (shouldSkipInitialFetch(backendState, threadId)) {
|
|
@@ -1320,13 +1702,13 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1320
1702
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1321
1703
|
pendingFetches.current.add(threadId);
|
|
1322
1704
|
try {
|
|
1323
|
-
const userState = (_a = options
|
|
1705
|
+
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1324
1706
|
const state = await backendApiRef.current.fetchState(
|
|
1325
1707
|
backendThreadId,
|
|
1326
1708
|
userState
|
|
1327
1709
|
);
|
|
1328
1710
|
(_b = messageControllerRef.current) == null ? void 0 : _b.inbound(threadId, state.messages);
|
|
1329
|
-
if (((_c = state.system_events) == null ? void 0 : _c.length) &&
|
|
1711
|
+
if (((_c = state.system_events) == null ? void 0 : _c.length) && options.onSyncEvents) {
|
|
1330
1712
|
options.onSyncEvents(backendThreadId, state.system_events);
|
|
1331
1713
|
}
|
|
1332
1714
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
@@ -1357,7 +1739,7 @@ function useRuntimeOrchestrator(backendApi, options) {
|
|
|
1357
1739
|
};
|
|
1358
1740
|
}
|
|
1359
1741
|
|
|
1360
|
-
// src/runtime/threadlist-adapter.ts
|
|
1742
|
+
// packages/react/src/runtime/threadlist-adapter.ts
|
|
1361
1743
|
var sortByLastActiveDesc = ([, metaA], [, metaB]) => {
|
|
1362
1744
|
const tsA = parseTimestamp(metaA.lastActiveAt);
|
|
1363
1745
|
const tsB = parseTimestamp(metaB.lastActiveAt);
|
|
@@ -1390,7 +1772,9 @@ function buildThreadListAdapter({
|
|
|
1390
1772
|
currentThreadIdRef,
|
|
1391
1773
|
polling,
|
|
1392
1774
|
userAddress,
|
|
1393
|
-
setIsRunning
|
|
1775
|
+
setIsRunning,
|
|
1776
|
+
getNamespace,
|
|
1777
|
+
getApiKey
|
|
1394
1778
|
}) {
|
|
1395
1779
|
const backendState = backendStateRef.current;
|
|
1396
1780
|
const { regularThreads, archivedThreads } = buildThreadLists(
|
|
@@ -1418,7 +1802,8 @@ function buildThreadListAdapter({
|
|
|
1418
1802
|
(prev) => new Map(prev).set(threadId, {
|
|
1419
1803
|
title: "New Chat",
|
|
1420
1804
|
status: "pending",
|
|
1421
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1805
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1806
|
+
control: initThreadControl()
|
|
1422
1807
|
})
|
|
1423
1808
|
);
|
|
1424
1809
|
threadContext.setThreadMessages(threadId, []);
|
|
@@ -1445,15 +1830,13 @@ function buildThreadListAdapter({
|
|
|
1445
1830
|
return;
|
|
1446
1831
|
}
|
|
1447
1832
|
if (backendState.createThreadPromise) {
|
|
1448
|
-
preparePendingThread(
|
|
1449
|
-
(_a = backendState.creatingThreadId) != null ? _a : crypto.randomUUID()
|
|
1450
|
-
);
|
|
1833
|
+
preparePendingThread((_a = backendState.creatingThreadId) != null ? _a : generateUUID());
|
|
1451
1834
|
return;
|
|
1452
1835
|
}
|
|
1453
|
-
const threadId =
|
|
1836
|
+
const threadId = generateUUID();
|
|
1454
1837
|
preparePendingThread(threadId);
|
|
1455
1838
|
const createPromise = backendApiRef.current.createThread(threadId, userAddress).then(async (newThread) => {
|
|
1456
|
-
var _a2;
|
|
1839
|
+
var _a2, _b;
|
|
1457
1840
|
const uiThreadId = (_a2 = backendState.creatingThreadId) != null ? _a2 : threadId;
|
|
1458
1841
|
const backendId = newThread.session_id;
|
|
1459
1842
|
if (uiThreadId !== backendId) {
|
|
@@ -1464,14 +1847,15 @@ function buildThreadListAdapter({
|
|
|
1464
1847
|
}
|
|
1465
1848
|
markSkipInitialFetch(backendState, uiThreadId);
|
|
1466
1849
|
threadContext.setThreadMetadata((prev) => {
|
|
1467
|
-
var _a3,
|
|
1850
|
+
var _a3, _b2, _c;
|
|
1468
1851
|
const next = new Map(prev);
|
|
1469
1852
|
const existing = next.get(uiThreadId);
|
|
1470
1853
|
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1471
1854
|
next.set(uiThreadId, {
|
|
1472
1855
|
title: (_a3 = existing == null ? void 0 : existing.title) != null ? _a3 : "New Chat",
|
|
1473
1856
|
status: nextStatus,
|
|
1474
|
-
lastActiveAt: (
|
|
1857
|
+
lastActiveAt: (_b2 = existing == null ? void 0 : existing.lastActiveAt) != null ? _b2 : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1858
|
+
control: (_c = existing == null ? void 0 : existing.control) != null ? _c : initThreadControl()
|
|
1475
1859
|
});
|
|
1476
1860
|
return next;
|
|
1477
1861
|
});
|
|
@@ -1481,9 +1865,17 @@ function buildThreadListAdapter({
|
|
|
1481
1865
|
const pendingMessages = backendState.pendingChat.get(uiThreadId);
|
|
1482
1866
|
if (pendingMessages == null ? void 0 : pendingMessages.length) {
|
|
1483
1867
|
backendState.pendingChat.delete(uiThreadId);
|
|
1868
|
+
const namespace = getNamespace();
|
|
1869
|
+
const apiKey = (_b = getApiKey == null ? void 0 : getApiKey()) != null ? _b : void 0;
|
|
1484
1870
|
for (const text of pendingMessages) {
|
|
1485
1871
|
try {
|
|
1486
|
-
await backendApiRef.current.postChatMessage(
|
|
1872
|
+
await backendApiRef.current.postChatMessage(
|
|
1873
|
+
backendId,
|
|
1874
|
+
text,
|
|
1875
|
+
namespace,
|
|
1876
|
+
userAddress,
|
|
1877
|
+
apiKey
|
|
1878
|
+
);
|
|
1487
1879
|
} catch (error) {
|
|
1488
1880
|
console.error("Failed to send queued message:", error);
|
|
1489
1881
|
}
|
|
@@ -1582,7 +1974,8 @@ function buildThreadListAdapter({
|
|
|
1582
1974
|
(prev) => new Map(prev).set(defaultId, {
|
|
1583
1975
|
title: "New Chat",
|
|
1584
1976
|
status: "regular",
|
|
1585
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1977
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1978
|
+
control: initThreadControl()
|
|
1586
1979
|
})
|
|
1587
1980
|
);
|
|
1588
1981
|
threadContext.setThreadMessages(defaultId, []);
|
|
@@ -1597,12 +1990,12 @@ function buildThreadListAdapter({
|
|
|
1597
1990
|
};
|
|
1598
1991
|
}
|
|
1599
1992
|
|
|
1600
|
-
// src/interface.tsx
|
|
1601
|
-
import { createContext as
|
|
1602
|
-
var AomiRuntimeContext =
|
|
1993
|
+
// packages/react/src/interface.tsx
|
|
1994
|
+
import { createContext as createContext6, useContext as useContext6 } from "react";
|
|
1995
|
+
var AomiRuntimeContext = createContext6(null);
|
|
1603
1996
|
var AomiRuntimeApiProvider = AomiRuntimeContext.Provider;
|
|
1604
1997
|
function useAomiRuntime() {
|
|
1605
|
-
const context =
|
|
1998
|
+
const context = useContext6(AomiRuntimeContext);
|
|
1606
1999
|
if (!context) {
|
|
1607
2000
|
throw new Error(
|
|
1608
2001
|
"useAomiRuntime must be used within AomiRuntimeProvider. Wrap your app with <AomiRuntimeProvider>...</AomiRuntimeProvider>"
|
|
@@ -1611,8 +2004,8 @@ function useAomiRuntime() {
|
|
|
1611
2004
|
return context;
|
|
1612
2005
|
}
|
|
1613
2006
|
|
|
1614
|
-
// src/runtime/core.tsx
|
|
1615
|
-
import { jsx as
|
|
2007
|
+
// packages/react/src/runtime/core.tsx
|
|
2008
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1616
2009
|
function AomiRuntimeCore({
|
|
1617
2010
|
children,
|
|
1618
2011
|
backendApi
|
|
@@ -1622,6 +2015,7 @@ function AomiRuntimeCore({
|
|
|
1622
2015
|
const notificationContext = useNotification();
|
|
1623
2016
|
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1624
2017
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
2018
|
+
const { getControlState, getCurrentThreadControl } = useControl();
|
|
1625
2019
|
const {
|
|
1626
2020
|
backendStateRef,
|
|
1627
2021
|
polling,
|
|
@@ -1633,9 +2027,14 @@ function AomiRuntimeCore({
|
|
|
1633
2027
|
} = useRuntimeOrchestrator(backendApi, {
|
|
1634
2028
|
onSyncEvents: dispatchSystemEvents,
|
|
1635
2029
|
getPublicKey: () => getUserState().address,
|
|
1636
|
-
getUserState
|
|
2030
|
+
getUserState,
|
|
2031
|
+
getNamespace: () => {
|
|
2032
|
+
var _a, _b;
|
|
2033
|
+
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
2034
|
+
},
|
|
2035
|
+
getApiKey: () => getControlState().apiKey
|
|
1637
2036
|
});
|
|
1638
|
-
|
|
2037
|
+
useEffect3(() => {
|
|
1639
2038
|
const unsubscribe = onUserStateChange(async (newUser) => {
|
|
1640
2039
|
const sessionId = threadContext.currentThreadId;
|
|
1641
2040
|
const message = JSON.stringify({
|
|
@@ -1651,19 +2050,30 @@ function AomiRuntimeCore({
|
|
|
1651
2050
|
});
|
|
1652
2051
|
return unsubscribe;
|
|
1653
2052
|
}, [onUserStateChange, backendApiRef, threadContext.currentThreadId]);
|
|
1654
|
-
const threadContextRef =
|
|
2053
|
+
const threadContextRef = useRef6(threadContext);
|
|
1655
2054
|
threadContextRef.current = threadContext;
|
|
1656
|
-
const currentThreadIdRef =
|
|
1657
|
-
|
|
2055
|
+
const currentThreadIdRef = useRef6(threadContext.currentThreadId);
|
|
2056
|
+
useEffect3(() => {
|
|
1658
2057
|
currentThreadIdRef.current = threadContext.currentThreadId;
|
|
1659
2058
|
}, [threadContext.currentThreadId]);
|
|
1660
|
-
|
|
2059
|
+
useEffect3(() => {
|
|
1661
2060
|
void ensureInitialState(threadContext.currentThreadId);
|
|
1662
2061
|
}, [ensureInitialState, threadContext.currentThreadId]);
|
|
1663
|
-
|
|
2062
|
+
useEffect3(() => {
|
|
1664
2063
|
const threadId = threadContext.currentThreadId;
|
|
1665
2064
|
setIsRunning(isThreadRunning(backendStateRef.current, threadId));
|
|
1666
2065
|
}, [backendStateRef, setIsRunning, threadContext.currentThreadId]);
|
|
2066
|
+
useEffect3(() => {
|
|
2067
|
+
const threadId = threadContext.currentThreadId;
|
|
2068
|
+
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
2069
|
+
if (currentMeta && currentMeta.control.isProcessing !== isRunning) {
|
|
2070
|
+
threadContext.updateThreadMetadata(threadId, {
|
|
2071
|
+
control: __spreadProps(__spreadValues({}, currentMeta.control), {
|
|
2072
|
+
isProcessing: isRunning
|
|
2073
|
+
})
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
}, [isRunning, threadContext]);
|
|
1667
2077
|
const currentMessages = threadContext.getThreadMessages(
|
|
1668
2078
|
threadContext.currentThreadId
|
|
1669
2079
|
);
|
|
@@ -1675,11 +2085,11 @@ function AomiRuntimeCore({
|
|
|
1675
2085
|
threadContext.allThreadsMetadata
|
|
1676
2086
|
]
|
|
1677
2087
|
);
|
|
1678
|
-
|
|
2088
|
+
useEffect3(() => {
|
|
1679
2089
|
const userAddress = user.address;
|
|
1680
2090
|
if (!userAddress) return;
|
|
1681
2091
|
const fetchThreadList = async () => {
|
|
1682
|
-
var _a, _b;
|
|
2092
|
+
var _a, _b, _c;
|
|
1683
2093
|
try {
|
|
1684
2094
|
const threadList = await backendApiRef.current.fetchThreads(userAddress);
|
|
1685
2095
|
const currentContext = threadContextRef.current;
|
|
@@ -1689,10 +2099,12 @@ function AomiRuntimeCore({
|
|
|
1689
2099
|
const rawTitle = (_a = thread.title) != null ? _a : "";
|
|
1690
2100
|
const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
|
|
1691
2101
|
const lastActive = ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
|
|
2102
|
+
const existingControl = (_c = newMetadata.get(thread.session_id)) == null ? void 0 : _c.control;
|
|
1692
2103
|
newMetadata.set(thread.session_id, {
|
|
1693
2104
|
title,
|
|
1694
2105
|
status: thread.is_archived ? "archived" : "regular",
|
|
1695
|
-
lastActiveAt: lastActive
|
|
2106
|
+
lastActiveAt: lastActive,
|
|
2107
|
+
control: existingControl != null ? existingControl : initThreadControl()
|
|
1696
2108
|
});
|
|
1697
2109
|
const match = title.match(/^Chat (\d+)$/);
|
|
1698
2110
|
if (match) {
|
|
@@ -1720,7 +2132,12 @@ function AomiRuntimeCore({
|
|
|
1720
2132
|
currentThreadIdRef,
|
|
1721
2133
|
polling,
|
|
1722
2134
|
userAddress: user.address,
|
|
1723
|
-
setIsRunning
|
|
2135
|
+
setIsRunning,
|
|
2136
|
+
getNamespace: () => {
|
|
2137
|
+
var _a, _b;
|
|
2138
|
+
return (_b = (_a = getCurrentThreadControl().namespace) != null ? _a : getControlState().defaultNamespace) != null ? _b : "default";
|
|
2139
|
+
},
|
|
2140
|
+
getApiKey: () => getControlState().apiKey
|
|
1724
2141
|
}),
|
|
1725
2142
|
[
|
|
1726
2143
|
backendApiRef,
|
|
@@ -1730,10 +2147,11 @@ function AomiRuntimeCore({
|
|
|
1730
2147
|
setIsRunning,
|
|
1731
2148
|
threadContext,
|
|
1732
2149
|
threadContext.currentThreadId,
|
|
1733
|
-
threadContext.allThreadsMetadata
|
|
2150
|
+
threadContext.allThreadsMetadata,
|
|
2151
|
+
getControlState
|
|
1734
2152
|
]
|
|
1735
2153
|
);
|
|
1736
|
-
|
|
2154
|
+
useEffect3(() => {
|
|
1737
2155
|
const backendState = backendStateRef.current;
|
|
1738
2156
|
const currentSessionId = threadContext.currentThreadId;
|
|
1739
2157
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -1764,14 +2182,15 @@ function AomiRuntimeCore({
|
|
|
1764
2182
|
});
|
|
1765
2183
|
}
|
|
1766
2184
|
threadContextRef.current.setThreadMetadata((prev) => {
|
|
1767
|
-
var _a;
|
|
2185
|
+
var _a, _b;
|
|
1768
2186
|
const next = new Map(prev);
|
|
1769
2187
|
const existing = next.get(targetThreadId);
|
|
1770
2188
|
const nextStatus = (existing == null ? void 0 : existing.status) === "archived" ? "archived" : "regular";
|
|
1771
2189
|
next.set(targetThreadId, {
|
|
1772
2190
|
title: normalizedTitle,
|
|
1773
2191
|
status: nextStatus,
|
|
1774
|
-
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString()
|
|
2192
|
+
lastActiveAt: (_a = existing == null ? void 0 : existing.lastActiveAt) != null ? _a : (/* @__PURE__ */ new Date()).toISOString(),
|
|
2193
|
+
control: (_b = existing == null ? void 0 : existing.control) != null ? _b : initThreadControl()
|
|
1775
2194
|
});
|
|
1776
2195
|
return next;
|
|
1777
2196
|
});
|
|
@@ -1790,12 +2209,12 @@ function AomiRuntimeCore({
|
|
|
1790
2209
|
threadContext.currentThreadId,
|
|
1791
2210
|
resolvedSessionId
|
|
1792
2211
|
]);
|
|
1793
|
-
|
|
2212
|
+
useEffect3(() => {
|
|
1794
2213
|
const threadId = threadContext.currentThreadId;
|
|
1795
2214
|
if (!isThreadReady(backendStateRef.current, threadId)) return;
|
|
1796
2215
|
void messageController.flushPendingChat(threadId);
|
|
1797
2216
|
}, [messageController, backendStateRef, threadContext.currentThreadId]);
|
|
1798
|
-
|
|
2217
|
+
useEffect3(() => {
|
|
1799
2218
|
const showToolNotification = (eventType) => (event) => {
|
|
1800
2219
|
const payload = event.payload;
|
|
1801
2220
|
const toolName = typeof (payload == null ? void 0 : payload.tool_name) === "string" ? payload.tool_name : void 0;
|
|
@@ -1820,15 +2239,10 @@ function AomiRuntimeCore({
|
|
|
1820
2239
|
unsubscribeComplete();
|
|
1821
2240
|
};
|
|
1822
2241
|
}, [eventContext, notificationContext]);
|
|
1823
|
-
|
|
2242
|
+
useEffect3(() => {
|
|
1824
2243
|
const unsubscribe = eventContext.subscribe("system_notice", (event) => {
|
|
1825
2244
|
const payload = event.payload;
|
|
1826
2245
|
const message = payload == null ? void 0 : payload.message;
|
|
1827
|
-
notificationContext.showNotification({
|
|
1828
|
-
type: "notice",
|
|
1829
|
-
title: "System notice",
|
|
1830
|
-
message
|
|
1831
|
-
});
|
|
1832
2246
|
});
|
|
1833
2247
|
return unsubscribe;
|
|
1834
2248
|
}, [eventContext, notificationContext]);
|
|
@@ -1841,13 +2255,13 @@ function AomiRuntimeCore({
|
|
|
1841
2255
|
convertMessage: (msg) => msg,
|
|
1842
2256
|
adapters: { threadList: threadListAdapter }
|
|
1843
2257
|
});
|
|
1844
|
-
|
|
2258
|
+
useEffect3(() => {
|
|
1845
2259
|
return () => {
|
|
1846
2260
|
polling.stopAll();
|
|
1847
2261
|
};
|
|
1848
2262
|
}, [polling]);
|
|
1849
2263
|
const userContext = useUser();
|
|
1850
|
-
const sendMessage =
|
|
2264
|
+
const sendMessage = useCallback6(
|
|
1851
2265
|
async (text) => {
|
|
1852
2266
|
const appendMessage = {
|
|
1853
2267
|
role: "user",
|
|
@@ -1860,39 +2274,39 @@ function AomiRuntimeCore({
|
|
|
1860
2274
|
},
|
|
1861
2275
|
[messageController, threadContext.currentThreadId]
|
|
1862
2276
|
);
|
|
1863
|
-
const cancelGeneration =
|
|
2277
|
+
const cancelGeneration = useCallback6(() => {
|
|
1864
2278
|
messageController.cancel(threadContext.currentThreadId);
|
|
1865
2279
|
}, [messageController, threadContext.currentThreadId]);
|
|
1866
|
-
const getMessages =
|
|
2280
|
+
const getMessages = useCallback6(
|
|
1867
2281
|
(threadId) => {
|
|
1868
2282
|
const id = threadId != null ? threadId : threadContext.currentThreadId;
|
|
1869
2283
|
return threadContext.getThreadMessages(id);
|
|
1870
2284
|
},
|
|
1871
2285
|
[threadContext]
|
|
1872
2286
|
);
|
|
1873
|
-
const createThread =
|
|
2287
|
+
const createThread = useCallback6(async () => {
|
|
1874
2288
|
await threadListAdapter.onSwitchToNewThread();
|
|
1875
2289
|
return threadContextRef.current.currentThreadId;
|
|
1876
2290
|
}, [threadListAdapter]);
|
|
1877
|
-
const deleteThread =
|
|
2291
|
+
const deleteThread = useCallback6(
|
|
1878
2292
|
async (threadId) => {
|
|
1879
2293
|
await threadListAdapter.onDelete(threadId);
|
|
1880
2294
|
},
|
|
1881
2295
|
[threadListAdapter]
|
|
1882
2296
|
);
|
|
1883
|
-
const renameThread =
|
|
2297
|
+
const renameThread = useCallback6(
|
|
1884
2298
|
async (threadId, title) => {
|
|
1885
2299
|
await threadListAdapter.onRename(threadId, title);
|
|
1886
2300
|
},
|
|
1887
2301
|
[threadListAdapter]
|
|
1888
2302
|
);
|
|
1889
|
-
const archiveThread =
|
|
2303
|
+
const archiveThread = useCallback6(
|
|
1890
2304
|
async (threadId) => {
|
|
1891
2305
|
await threadListAdapter.onArchive(threadId);
|
|
1892
2306
|
},
|
|
1893
2307
|
[threadListAdapter]
|
|
1894
2308
|
);
|
|
1895
|
-
const selectThread =
|
|
2309
|
+
const selectThread = useCallback6(
|
|
1896
2310
|
(threadId) => {
|
|
1897
2311
|
if (threadContext.allThreadsMetadata.has(threadId)) {
|
|
1898
2312
|
threadListAdapter.onSwitchToThread(threadId);
|
|
@@ -1953,45 +2367,57 @@ function AomiRuntimeCore({
|
|
|
1953
2367
|
eventContext
|
|
1954
2368
|
]
|
|
1955
2369
|
);
|
|
1956
|
-
return /* @__PURE__ */
|
|
2370
|
+
return /* @__PURE__ */ jsx6(AomiRuntimeApiProvider, { value: aomiRuntimeApi, children: /* @__PURE__ */ jsx6(AssistantRuntimeProvider, { runtime, children }) });
|
|
1957
2371
|
}
|
|
1958
2372
|
|
|
1959
|
-
// src/runtime/aomi-runtime.tsx
|
|
1960
|
-
import { jsx as
|
|
2373
|
+
// packages/react/src/runtime/aomi-runtime.tsx
|
|
2374
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1961
2375
|
function AomiRuntimeProvider({
|
|
1962
2376
|
children,
|
|
1963
2377
|
backendUrl = "http://localhost:8080"
|
|
1964
2378
|
}) {
|
|
1965
2379
|
const backendApi = useMemo3(() => new BackendApi(backendUrl), [backendUrl]);
|
|
1966
|
-
return /* @__PURE__ */
|
|
2380
|
+
return /* @__PURE__ */ jsx7(ThreadContextProvider, { children: /* @__PURE__ */ jsx7(NotificationContextProvider, { children: /* @__PURE__ */ jsx7(UserContextProvider, { children: /* @__PURE__ */ jsx7(AomiRuntimeInner, { backendApi, children }) }) }) });
|
|
1967
2381
|
}
|
|
1968
2382
|
function AomiRuntimeInner({
|
|
1969
2383
|
children,
|
|
1970
2384
|
backendApi
|
|
1971
2385
|
}) {
|
|
2386
|
+
var _a;
|
|
1972
2387
|
const threadContext = useThreadContext();
|
|
1973
|
-
|
|
1974
|
-
|
|
2388
|
+
const { user } = useUser();
|
|
2389
|
+
return /* @__PURE__ */ jsx7(
|
|
2390
|
+
ControlContextProvider,
|
|
1975
2391
|
{
|
|
1976
2392
|
backendApi,
|
|
1977
2393
|
sessionId: threadContext.currentThreadId,
|
|
1978
|
-
|
|
2394
|
+
publicKey: (_a = user.address) != null ? _a : void 0,
|
|
2395
|
+
getThreadMetadata: threadContext.getThreadMetadata,
|
|
2396
|
+
updateThreadMetadata: threadContext.updateThreadMetadata,
|
|
2397
|
+
children: /* @__PURE__ */ jsx7(
|
|
2398
|
+
EventContextProvider,
|
|
2399
|
+
{
|
|
2400
|
+
backendApi,
|
|
2401
|
+
sessionId: threadContext.currentThreadId,
|
|
2402
|
+
children: /* @__PURE__ */ jsx7(AomiRuntimeCore, { backendApi, children })
|
|
2403
|
+
}
|
|
2404
|
+
)
|
|
1979
2405
|
}
|
|
1980
2406
|
);
|
|
1981
2407
|
}
|
|
1982
2408
|
|
|
1983
|
-
// src/handlers/wallet-handler.ts
|
|
1984
|
-
import { useCallback as
|
|
2409
|
+
// packages/react/src/handlers/wallet-handler.ts
|
|
2410
|
+
import { useCallback as useCallback7, useEffect as useEffect4, useState as useState6 } from "react";
|
|
1985
2411
|
function useWalletHandler({
|
|
1986
2412
|
sessionId,
|
|
1987
2413
|
onTxRequest
|
|
1988
2414
|
}) {
|
|
1989
2415
|
const { subscribe: subscribe2, sendOutboundSystem: sendOutbound } = useEventContext();
|
|
1990
2416
|
const { setUser, getUserState } = useUser();
|
|
1991
|
-
const [pendingTxRequests, setPendingTxRequests] =
|
|
2417
|
+
const [pendingTxRequests, setPendingTxRequests] = useState6(
|
|
1992
2418
|
[]
|
|
1993
2419
|
);
|
|
1994
|
-
|
|
2420
|
+
useEffect4(() => {
|
|
1995
2421
|
const unsubscribe = subscribe2(
|
|
1996
2422
|
"wallet_tx_request",
|
|
1997
2423
|
(event) => {
|
|
@@ -2002,7 +2428,7 @@ function useWalletHandler({
|
|
|
2002
2428
|
);
|
|
2003
2429
|
return unsubscribe;
|
|
2004
2430
|
}, [subscribe2, onTxRequest]);
|
|
2005
|
-
|
|
2431
|
+
useEffect4(() => {
|
|
2006
2432
|
const unsubscribe = subscribe2(
|
|
2007
2433
|
"user_state_request",
|
|
2008
2434
|
(event) => {
|
|
@@ -2015,7 +2441,7 @@ function useWalletHandler({
|
|
|
2015
2441
|
);
|
|
2016
2442
|
return unsubscribe;
|
|
2017
2443
|
}, [subscribe2, onTxRequest]);
|
|
2018
|
-
const sendTxComplete =
|
|
2444
|
+
const sendTxComplete = useCallback7(
|
|
2019
2445
|
(tx) => {
|
|
2020
2446
|
sendOutbound({
|
|
2021
2447
|
type: "wallet:tx_complete",
|
|
@@ -2025,7 +2451,7 @@ function useWalletHandler({
|
|
|
2025
2451
|
},
|
|
2026
2452
|
[sendOutbound, sessionId]
|
|
2027
2453
|
);
|
|
2028
|
-
const sendConnectionChange =
|
|
2454
|
+
const sendConnectionChange = useCallback7(
|
|
2029
2455
|
(status, address, chainId) => {
|
|
2030
2456
|
if (status === "connected") {
|
|
2031
2457
|
setUser({
|
|
@@ -2048,7 +2474,7 @@ function useWalletHandler({
|
|
|
2048
2474
|
},
|
|
2049
2475
|
[setUser, sendOutbound, sessionId]
|
|
2050
2476
|
);
|
|
2051
|
-
const clearTxRequest =
|
|
2477
|
+
const clearTxRequest = useCallback7((index) => {
|
|
2052
2478
|
setPendingTxRequests((prev) => prev.filter((_, i) => i !== index));
|
|
2053
2479
|
}, []);
|
|
2054
2480
|
return {
|
|
@@ -2059,8 +2485,8 @@ function useWalletHandler({
|
|
|
2059
2485
|
};
|
|
2060
2486
|
}
|
|
2061
2487
|
|
|
2062
|
-
// src/handlers/notification-handler.ts
|
|
2063
|
-
import { useCallback as
|
|
2488
|
+
// packages/react/src/handlers/notification-handler.ts
|
|
2489
|
+
import { useCallback as useCallback8, useEffect as useEffect5, useState as useState7 } from "react";
|
|
2064
2490
|
var notificationIdCounter2 = 0;
|
|
2065
2491
|
function generateNotificationId() {
|
|
2066
2492
|
return `notif-${Date.now()}-${++notificationIdCounter2}`;
|
|
@@ -2069,8 +2495,8 @@ function useNotificationHandler({
|
|
|
2069
2495
|
onNotification
|
|
2070
2496
|
} = {}) {
|
|
2071
2497
|
const { subscribe: subscribe2 } = useEventContext();
|
|
2072
|
-
const [notifications, setNotifications] =
|
|
2073
|
-
|
|
2498
|
+
const [notifications, setNotifications] = useState7([]);
|
|
2499
|
+
useEffect5(() => {
|
|
2074
2500
|
const unsubscribe = subscribe2("notification", (event) => {
|
|
2075
2501
|
var _a, _b;
|
|
2076
2502
|
const payload = event.payload;
|
|
@@ -2089,7 +2515,7 @@ function useNotificationHandler({
|
|
|
2089
2515
|
return unsubscribe;
|
|
2090
2516
|
}, [subscribe2, onNotification]);
|
|
2091
2517
|
const unhandledCount = notifications.filter((n) => !n.handled).length;
|
|
2092
|
-
const markHandled =
|
|
2518
|
+
const markHandled = useCallback8((id) => {
|
|
2093
2519
|
setNotifications(
|
|
2094
2520
|
(prev) => prev.map((n) => n.id === id ? __spreadProps(__spreadValues({}, n), { handled: true }) : n)
|
|
2095
2521
|
);
|
|
@@ -2103,6 +2529,7 @@ function useNotificationHandler({
|
|
|
2103
2529
|
export {
|
|
2104
2530
|
AomiRuntimeProvider,
|
|
2105
2531
|
BackendApi,
|
|
2532
|
+
ControlContextProvider,
|
|
2106
2533
|
EventContextProvider,
|
|
2107
2534
|
NotificationContextProvider,
|
|
2108
2535
|
ThreadContextProvider,
|
|
@@ -2110,7 +2537,9 @@ export {
|
|
|
2110
2537
|
cn,
|
|
2111
2538
|
formatAddress,
|
|
2112
2539
|
getNetworkName,
|
|
2540
|
+
initThreadControl,
|
|
2113
2541
|
useAomiRuntime,
|
|
2542
|
+
useControl,
|
|
2114
2543
|
useCurrentThreadMessages,
|
|
2115
2544
|
useCurrentThreadMetadata,
|
|
2116
2545
|
useEventContext,
|