@personaai/react 0.9.0 → 0.10.0

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 CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ARCHITECT_AGENT_ID: () => ARCHITECT_AGENT_ID,
23
24
  PersonaProvider: () => PersonaProvider,
24
25
  VERSION: () => VERSION,
25
26
  createLogger: () => import_logger2.createLogger,
@@ -30,6 +31,7 @@ __export(index_exports, {
30
31
  setLogLevel: () => import_logger2.setLogLevel,
31
32
  supportsStreamingFetch: () => supportsStreamingFetch,
32
33
  useAgents: () => useAgents,
34
+ useArchitectChat: () => useArchitectChat,
33
35
  useChat: () => useChat,
34
36
  useConnection: () => useConnection,
35
37
  useFiles: () => useFiles,
@@ -334,7 +336,7 @@ async function openSSEStream(opts) {
334
336
  };
335
337
  }
336
338
 
337
- // src/hooks/useChat.ts
339
+ // src/hooks/streamEventHelpers.ts
338
340
  function isErrorToolContent(content) {
339
341
  if (typeof content !== "string" || !content.trim().startsWith("{"))
340
342
  return false;
@@ -380,6 +382,38 @@ function parsePresentedFile(content) {
380
382
  return null;
381
383
  }
382
384
  }
385
+ function normalizeWorkspaceFiles(raw) {
386
+ const normalized = {};
387
+ for (const [path, file] of Object.entries(raw || {})) {
388
+ normalized[path] = {
389
+ content: file.content,
390
+ size: file.size,
391
+ createdAt: file.created_at,
392
+ modifiedAt: file.modified_at
393
+ };
394
+ }
395
+ return normalized;
396
+ }
397
+ function normalizePendingInterrupt(pending) {
398
+ if (!pending || typeof pending !== "object") return null;
399
+ const p = pending;
400
+ if (p.kind === "hitl") {
401
+ return {
402
+ kind: "hitl",
403
+ actionRequests: p.value?.actionRequests ?? [],
404
+ reviewConfigs: p.value?.reviewConfigs ?? []
405
+ };
406
+ }
407
+ if (p.kind === "clarification") {
408
+ return {
409
+ kind: "clarification",
410
+ questions: p.value?.questions ?? []
411
+ };
412
+ }
413
+ return null;
414
+ }
415
+
416
+ // src/hooks/useChat.ts
383
417
  function parseSandboxCommand(tc) {
384
418
  let command = tc.args ?? "";
385
419
  try {
@@ -411,36 +445,6 @@ function parseSandboxCommand(tc) {
411
445
  seq: tc.seq
412
446
  };
413
447
  }
414
- function normalizeWorkspaceFiles(raw) {
415
- const normalized = {};
416
- for (const [path, file] of Object.entries(raw || {})) {
417
- normalized[path] = {
418
- content: file.content,
419
- size: file.size,
420
- createdAt: file.created_at,
421
- modifiedAt: file.modified_at
422
- };
423
- }
424
- return normalized;
425
- }
426
- function normalizePendingInterrupt(pending) {
427
- if (!pending || typeof pending !== "object") return null;
428
- const p = pending;
429
- if (p.kind === "hitl") {
430
- return {
431
- kind: "hitl",
432
- actionRequests: p.value?.actionRequests ?? [],
433
- reviewConfigs: p.value?.reviewConfigs ?? []
434
- };
435
- }
436
- if (p.kind === "clarification") {
437
- return {
438
- kind: "clarification",
439
- questions: p.value?.questions ?? []
440
- };
441
- }
442
- return null;
443
- }
444
448
  function useChat(options = {}) {
445
449
  const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken, logger } = usePersonaContext();
446
450
  const chatLogger = (0, import_react2.useMemo)(() => logger.child("chat"), [logger]);
@@ -505,7 +509,707 @@ function useChat(options = {}) {
505
509
  chatLogger.trace("stop called \u2014 no active stream");
506
510
  }
507
511
  }, [chatLogger]);
508
- const clear = (0, import_react2.useCallback)(() => {
512
+ const clear = (0, import_react2.useCallback)(() => {
513
+ chatLogger.info("clear chat", { messageCount: messages.length });
514
+ chatLogger.debug("clear", { messageCount: messages.length });
515
+ stop();
516
+ setMessages([]);
517
+ setError(null);
518
+ setInterrupt(null);
519
+ setFiles({});
520
+ setTodos([]);
521
+ setPresentedFile(null);
522
+ loadedThreadIdRef.current = void 0;
523
+ }, [stop, chatLogger, messages.length]);
524
+ const startNewChat = (0, import_react2.useCallback)(() => {
525
+ chatLogger.info("startNewChat \u2014 entering ephemeral mode");
526
+ stop();
527
+ setMessages([]);
528
+ setError(null);
529
+ setInterrupt(null);
530
+ setFiles({});
531
+ setTodos([]);
532
+ setPresentedFile(null);
533
+ setInput("");
534
+ loadedThreadIdRef.current = void 0;
535
+ voiceThreadRef.current = void 0;
536
+ voicePrevLenRef.current = 0;
537
+ voiceStreamingIdRef.current = null;
538
+ voiceUserPartialIdRef.current = null;
539
+ setInternalThreadId(void 0);
540
+ }, [stop, chatLogger]);
541
+ const loadThreadMessages = (0, import_react2.useCallback)(
542
+ async (id) => {
543
+ chatLogger.debug("loadThreadMessages start", { threadId: id });
544
+ chatLogger.trace("loadThreadMessages", { threadId: id });
545
+ setIsLoadingHistory(true);
546
+ setError(null);
547
+ try {
548
+ const res = await fetchWithAuth(`/threads/${id}/messages`);
549
+ if (!res.ok)
550
+ throw new Error(`Failed to load thread history: ${res.statusText}`);
551
+ const body = await res.json();
552
+ const data = body?.data ?? body;
553
+ const raw = data?.messages ?? [];
554
+ const subagentTraces = data?.subagentTraces ?? {};
555
+ const loaded = raw.map((m, i) => ({
556
+ id: m.id || `history-${id}-${i}`,
557
+ role: m.role,
558
+ content: m.content,
559
+ createdAt: /* @__PURE__ */ new Date(),
560
+ toolCalls: m.toolCalls?.map((tc) => {
561
+ const trace = subagentTraces[tc.toolCallId];
562
+ return Array.isArray(trace) && trace.length > 0 ? {
563
+ ...tc,
564
+ subagentActivity: persistedTraceToActivityEntries(trace)
565
+ } : tc;
566
+ })
567
+ }));
568
+ setMessages(loaded);
569
+ setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));
570
+ setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));
571
+ setTodos(data?.state?.todos ?? []);
572
+ loadedThreadIdRef.current = id;
573
+ chatLogger.info("loadThreadMessages succeeded", {
574
+ threadId: id,
575
+ messageCount: loaded.length
576
+ });
577
+ chatLogger.debug("loadThreadMessages completed", {
578
+ threadId: id,
579
+ messageCount: loaded.length
580
+ });
581
+ return loaded;
582
+ } catch (err) {
583
+ const errorObj = err instanceof Error ? err : new Error(String(err));
584
+ chatLogger.warn("loadThreadMessages failed", {
585
+ threadId: id,
586
+ error: errorObj.message
587
+ });
588
+ chatLogger.error("loadThreadMessages error", {
589
+ threadId: id,
590
+ error: errorObj.message
591
+ });
592
+ setError(errorObj);
593
+ if (loadedThreadIdRef.current === id) loadedThreadIdRef.current = void 0;
594
+ return [];
595
+ } finally {
596
+ setIsLoadingHistory(false);
597
+ chatLogger.trace("loadThreadMessages end", { threadId: id });
598
+ }
599
+ },
600
+ [fetchWithAuth, chatLogger]
601
+ );
602
+ (0, import_react2.useEffect)(() => {
603
+ if (!effectiveThreadId || isStreaming) {
604
+ chatLogger.trace("auto-load skipped", { threadId: effectiveThreadId, isStreaming });
605
+ return;
606
+ }
607
+ if (loadedThreadIdRef.current === effectiveThreadId) {
608
+ chatLogger.trace("auto-load already loaded", { threadId: effectiveThreadId });
609
+ return;
610
+ }
611
+ if (messages.length > 0) {
612
+ chatLogger.trace("auto-load has messages", {
613
+ threadId: effectiveThreadId,
614
+ count: messages.length
615
+ });
616
+ return;
617
+ }
618
+ chatLogger.info("auto-load thread history", { threadId: effectiveThreadId });
619
+ chatLogger.debug("loadThreadMessages trigger", { threadId: effectiveThreadId });
620
+ void loadThreadMessages(effectiveThreadId);
621
+ }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);
622
+ const voice = options.voice;
623
+ (0, import_react2.useEffect)(() => {
624
+ if (!voice) return;
625
+ if (voiceThreadRef.current !== effectiveThreadId) {
626
+ voiceThreadRef.current = effectiveThreadId;
627
+ voicePrevLenRef.current = voice.transcript.length;
628
+ voiceStreamingIdRef.current = null;
629
+ voiceUserPartialIdRef.current = null;
630
+ return;
631
+ }
632
+ const isVoiceActive = voice.state !== "idle" && voice.state !== "ended" && voice.state !== "error";
633
+ const curLen = voice.transcript.length;
634
+ if (curLen < voicePrevLenRef.current) {
635
+ voicePrevLenRef.current = 0;
636
+ voiceStreamingIdRef.current = null;
637
+ voiceUserPartialIdRef.current = null;
638
+ }
639
+ if (!isVoiceActive) {
640
+ if (curLen > voicePrevLenRef.current) {
641
+ const pendingLines = voice.transcript.slice(voicePrevLenRef.current);
642
+ voicePrevLenRef.current = curLen;
643
+ for (const line of pendingLines) {
644
+ const text = (line.text || "").trim();
645
+ if (!text) continue;
646
+ const role = line.speaker === "user" ? "user" : "assistant";
647
+ const voiceId = `voice-${line.id}`;
648
+ setMessages((prev) => {
649
+ if (prev.some((m) => m.id === voiceId)) return prev;
650
+ if (prev.some((m) => !m.id.startsWith("voice-") && m.role === role && m.content.trim() === text)) return prev;
651
+ const last = prev[prev.length - 1];
652
+ if (last?.id.startsWith("voice-") && last.role === "assistant" && role === "assistant") {
653
+ const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();
654
+ return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];
655
+ }
656
+ return [...prev, { id: voiceId, role, content: text, createdAt: /* @__PURE__ */ new Date() }];
657
+ });
658
+ }
659
+ } else {
660
+ voicePrevLenRef.current = voice.transcript.length;
661
+ }
662
+ if (voiceStreamingIdRef.current) {
663
+ const doneId = voiceStreamingIdRef.current;
664
+ voiceStreamingIdRef.current = null;
665
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
666
+ }
667
+ if (voiceUserPartialIdRef.current) {
668
+ const doneId = voiceUserPartialIdRef.current;
669
+ voiceUserPartialIdRef.current = null;
670
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
671
+ }
672
+ return;
673
+ }
674
+ if (curLen > voicePrevLenRef.current) {
675
+ const newLines = voice.transcript.slice(voicePrevLenRef.current);
676
+ voicePrevLenRef.current = curLen;
677
+ for (const line of newLines) {
678
+ const text = (line.text || "").trim();
679
+ if (!text) continue;
680
+ const role = line.speaker === "user" ? "user" : "assistant";
681
+ const voiceId = `voice-${line.id}`;
682
+ setMessages((prev) => {
683
+ if (prev.some((m) => m.id === voiceId)) return prev;
684
+ if (prev.some(
685
+ (m) => !m.id.startsWith("voice-") && m.role === role && m.content.trim() === text
686
+ ))
687
+ return prev;
688
+ const last = prev[prev.length - 1];
689
+ if (last?.id.startsWith("voice-") && last.role === "assistant" && role === "assistant") {
690
+ const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();
691
+ return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];
692
+ }
693
+ return [...prev, { id: voiceId, role, content: text, createdAt: /* @__PURE__ */ new Date() }];
694
+ });
695
+ }
696
+ }
697
+ const agentPartialText = voice.partial?.speaker === "agent" ? voice.partial.text.trim() : "";
698
+ const userPartialText = voice.partial?.speaker === "user" ? voice.partial.text.trim() : "";
699
+ if (agentPartialText) {
700
+ if (voiceUserPartialIdRef.current) {
701
+ const doneId = voiceUserPartialIdRef.current;
702
+ voiceUserPartialIdRef.current = null;
703
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
704
+ }
705
+ setMessages((prev) => {
706
+ const last = prev[prev.length - 1];
707
+ if (last?.id.startsWith("voice-") && last.role === "assistant") {
708
+ voiceStreamingIdRef.current = last.id;
709
+ return [...prev.slice(0, -1), { ...last, content: agentPartialText, isStreaming: true }];
710
+ }
711
+ const id = voiceStreamingIdRef.current || `voice-partial-${Date.now()}`;
712
+ voiceStreamingIdRef.current = id;
713
+ return [...prev, { id, role: "assistant", content: agentPartialText, isStreaming: true, createdAt: /* @__PURE__ */ new Date() }];
714
+ });
715
+ } else if (userPartialText) {
716
+ if (voiceStreamingIdRef.current) {
717
+ const doneId = voiceStreamingIdRef.current;
718
+ voiceStreamingIdRef.current = null;
719
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
720
+ }
721
+ setMessages((prev) => {
722
+ const last = prev[prev.length - 1];
723
+ if (last?.id.startsWith("voice-") && last.role === "user" && last.isStreaming) {
724
+ voiceUserPartialIdRef.current = last.id;
725
+ return [...prev.slice(0, -1), { ...last, content: userPartialText, isStreaming: true }];
726
+ }
727
+ const id = voiceUserPartialIdRef.current || `voice-partial-user-${Date.now()}`;
728
+ voiceUserPartialIdRef.current = id;
729
+ return [...prev, { id, role: "user", content: userPartialText, isStreaming: true, createdAt: /* @__PURE__ */ new Date() }];
730
+ });
731
+ } else {
732
+ if (voiceStreamingIdRef.current && voice.state !== "speaking") {
733
+ const doneId = voiceStreamingIdRef.current;
734
+ voiceStreamingIdRef.current = null;
735
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
736
+ }
737
+ if (voiceUserPartialIdRef.current) {
738
+ const doneId = voiceUserPartialIdRef.current;
739
+ voiceUserPartialIdRef.current = null;
740
+ setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
741
+ }
742
+ }
743
+ }, [voice?.transcript, voice?.partial, voice?.state, effectiveThreadId]);
744
+ const doSend = (0, import_react2.useCallback)(
745
+ async (prompt, baseMessages, overrideOptions) => {
746
+ const targetAgentId = overrideOptions?.agentId || agentId;
747
+ if (!targetAgentId) {
748
+ const err = new Error("No Agent ID specified for useChat.");
749
+ chatLogger.warn("sendMessage no agentId", {});
750
+ chatLogger.error("sendMessage failed \u2014 no agent", { error: err.message });
751
+ setError(err);
752
+ options.onError?.(err);
753
+ return false;
754
+ }
755
+ chatLogger.debug("sendMessage start", {
756
+ promptPreview: prompt.slice(0, 100),
757
+ agentId: targetAgentId,
758
+ threadId: effectiveThreadId ?? overrideOptions?.threadId,
759
+ hasResume: !!overrideOptions?.resume,
760
+ hasContextOverride: !!overrideOptions?.contextOverride,
761
+ messageCount: baseMessages.length
762
+ });
763
+ chatLogger.trace("sendMessage details", {
764
+ agentId: targetAgentId,
765
+ promptPreview: prompt.slice(0, 200),
766
+ hasResume: !!overrideOptions?.resume,
767
+ hasContextOverride: !!overrideOptions?.contextOverride
768
+ });
769
+ const userMessage = {
770
+ id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
771
+ role: "user",
772
+ content: prompt,
773
+ createdAt: /* @__PURE__ */ new Date()
774
+ };
775
+ const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
776
+ const placeholderAssistant = {
777
+ id: assistantMessageId,
778
+ role: "assistant",
779
+ content: "",
780
+ createdAt: /* @__PURE__ */ new Date(),
781
+ isStreaming: true,
782
+ toolCalls: []
783
+ };
784
+ const nextMessages = [...baseMessages, userMessage];
785
+ setMessages([...nextMessages, placeholderAssistant]);
786
+ setInput("");
787
+ setIsStreaming(true);
788
+ setError(null);
789
+ setInterrupt(null);
790
+ const controller = new AbortController();
791
+ abortControllerRef.current = controller;
792
+ const finalizeReasoning = () => {
793
+ setMessages(
794
+ (prev) => prev.map((m) => m.role === "reasoning" && m.isStreaming ? { ...m, isStreaming: false } : m)
795
+ );
796
+ };
797
+ try {
798
+ const payloadMessages = nextMessages.filter((m) => m.role !== "reasoning").map((m) => ({
799
+ role: m.role === "assistant" ? "assistant" : "user",
800
+ content: m.content
801
+ }));
802
+ let resolvedThreadId = await overrideOptions?.threadId ?? effectiveThreadId;
803
+ if (!resolvedThreadId) {
804
+ chatLogger.info("minting real thread for ephemeral chat", { agentId: targetAgentId });
805
+ const createRes = await fetchWithAuth("/threads", {
806
+ method: "POST",
807
+ headers: { "Content-Type": "application/json" },
808
+ body: JSON.stringify({ agentId: targetAgentId })
809
+ });
810
+ if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);
811
+ const createBody = await createRes.json();
812
+ const created = createBody?.data ?? createBody;
813
+ resolvedThreadId = created._id ?? created.id;
814
+ if (!resolvedThreadId) throw new Error("Thread creation returned no id");
815
+ setInternalThreadId(resolvedThreadId);
816
+ loadedThreadIdRef.current = resolvedThreadId;
817
+ options.onThreadCreated?.(resolvedThreadId);
818
+ chatLogger.info("ephemeral chat minted", { threadId: resolvedThreadId });
819
+ }
820
+ chatLogger.trace("resolved threadId", { threadId: resolvedThreadId });
821
+ const token = getAuthToken ? await getAuthToken() : null;
822
+ const resolvedHookContext = typeof options.context === "function" ? options.context() : options.context;
823
+ const mergedContext = { ...resolvedHookContext, ...overrideOptions?.context };
824
+ const hasContext = Object.keys(mergedContext).length > 0;
825
+ chatLogger.debug("opening SSE stream", {
826
+ agentId: targetAgentId,
827
+ hasToken: !!token,
828
+ hasThreadId: !!resolvedThreadId,
829
+ hasContext
830
+ });
831
+ const stream = await openSSEStream({
832
+ url: `${baseUrl}/chat`,
833
+ headers: {
834
+ "Content-Type": "application/json",
835
+ ...token ? { Authorization: `Bearer ${token}` } : {}
836
+ },
837
+ body: JSON.stringify({
838
+ agentId: targetAgentId,
839
+ messages: payloadMessages,
840
+ threadId: resolvedThreadId,
841
+ resume: overrideOptions?.resume,
842
+ contextOverride: overrideOptions?.contextOverride,
843
+ ...hasContext ? { context: mergedContext } : {}
844
+ }),
845
+ signal: controller.signal
846
+ });
847
+ if (!stream.ok) {
848
+ chatLogger.warn("SSE stream not ok", { status: stream.status, errorText: stream.errorText });
849
+ chatLogger.error("chat stream failed", { agentId: targetAgentId, status: stream.status, error: stream.errorText });
850
+ throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? "Stream failed"}`);
851
+ }
852
+ chatLogger.debug("SSE stream opened", { agentId: targetAgentId, status: stream.status });
853
+ chatLogger.info("chat stream started", { agentId: targetAgentId, threadId: resolvedThreadId });
854
+ const reader = stream.reader;
855
+ let buffer = "";
856
+ let accumulatedText = "";
857
+ const toolCallsMap = /* @__PURE__ */ new Map();
858
+ let streamSeq = 0;
859
+ let activeReasoningId = null;
860
+ const reasoningById = /* @__PURE__ */ new Map();
861
+ const patchAssistant = (patch) => {
862
+ setMessages(
863
+ (prev) => prev.map(
864
+ (msg) => msg.id === assistantMessageId ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch } : msg
865
+ )
866
+ );
867
+ };
868
+ const insertReasoningMessage = (id, seq) => {
869
+ const msg = { id, role: "reasoning", content: "", createdAt: /* @__PURE__ */ new Date(), isStreaming: true, seq };
870
+ setMessages((prev) => {
871
+ const idx = prev.findIndex((m) => m.id === assistantMessageId);
872
+ if (idx === -1) return [...prev, msg];
873
+ const next = [...prev];
874
+ next.splice(idx, 0, msg);
875
+ return next;
876
+ });
877
+ };
878
+ while (true) {
879
+ const { done, value } = await reader.read();
880
+ if (done) break;
881
+ buffer += value ?? "";
882
+ const lines = buffer.split("\n");
883
+ buffer = lines.pop() ?? "";
884
+ for (const line of lines) {
885
+ const trimmed = line.trim();
886
+ if (!trimmed || !trimmed.startsWith("data:")) continue;
887
+ const raw = trimmed.replace(/^data:\s*/, "");
888
+ if (raw === "[DONE]") break;
889
+ try {
890
+ const event = JSON.parse(raw);
891
+ chatLogger.trace("stream event", { type: event.type, event });
892
+ options.onEvent?.(event);
893
+ if (event.type === "TEXT_MESSAGE_CHUNK" && event.delta) {
894
+ chatLogger.debug("text chunk", { deltaLength: event.delta.length });
895
+ accumulatedText += event.delta;
896
+ patchAssistant({ content: accumulatedText, isStreaming: true });
897
+ } else if (event.type === "TOOL_CALL_CHUNK" && event.toolCallId) {
898
+ chatLogger.debug("tool call chunk", { toolCallId: event.toolCallId, toolCallName: event.toolCallName });
899
+ const existing = toolCallsMap.get(event.toolCallId);
900
+ if (existing) {
901
+ existing.args = (existing.args || "") + (event.delta || "");
902
+ } else {
903
+ toolCallsMap.set(event.toolCallId, {
904
+ toolCallId: event.toolCallId,
905
+ toolName: event.toolCallName || "",
906
+ args: event.delta || "",
907
+ seq: streamSeq++
908
+ });
909
+ }
910
+ patchAssistant({});
911
+ } else if (event.type === "TOOL_CALL_RESULT") {
912
+ chatLogger.debug("tool call result", { toolCallId: event.toolCallId });
913
+ const existing = toolCallsMap.get(event.toolCallId);
914
+ if (existing) {
915
+ existing.result = event.content;
916
+ existing.isError = isErrorToolContent(event.content);
917
+ if (existing.isError) chatLogger.warn("tool call error", { toolCallId: event.toolCallId });
918
+ if (existing.toolName === "present_file" && !existing.isError) {
919
+ const presented = parsePresentedFile(event.content);
920
+ if (presented) {
921
+ chatLogger.info("present_file", { path: presented.path });
922
+ setPresentedFile(presented);
923
+ }
924
+ }
925
+ patchAssistant({});
926
+ }
927
+ } else if (event.type === "STATE_SNAPSHOT") {
928
+ chatLogger.debug("state snapshot", {
929
+ fileCount: Object.keys(event.snapshot.files ?? {}).length,
930
+ todoCount: event.snapshot.todos?.length ?? 0
931
+ });
932
+ setFiles(normalizeWorkspaceFiles(event.snapshot.files ?? {}));
933
+ setTodos(event.snapshot.todos ?? []);
934
+ } else if (event.type === "REASONING_MESSAGE_START" && event.messageId) {
935
+ chatLogger.debug("reasoning start", { messageId: event.messageId });
936
+ activeReasoningId = event.messageId;
937
+ reasoningById.set(event.messageId, { content: "" });
938
+ insertReasoningMessage(event.messageId, streamSeq++);
939
+ } else if (event.type === "REASONING_MESSAGE_CONTENT") {
940
+ let rid = event.messageId || activeReasoningId || "";
941
+ if (!rid || !reasoningById.has(rid)) {
942
+ rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
943
+ activeReasoningId = rid;
944
+ reasoningById.set(rid, { content: "" });
945
+ insertReasoningMessage(rid, streamSeq++);
946
+ chatLogger.debug("reasoning lazy start", { messageId: rid });
947
+ }
948
+ const entry = reasoningById.get(rid);
949
+ entry.content += event.delta;
950
+ chatLogger.trace("reasoning content", { messageId: rid, deltaLength: event.delta?.length ?? 0 });
951
+ setMessages((prev) => prev.map((m) => m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m));
952
+ } else if (event.type === "REASONING_END") {
953
+ chatLogger.debug("reasoning end", { messageId: activeReasoningId });
954
+ const rid = activeReasoningId;
955
+ activeReasoningId = null;
956
+ if (rid) {
957
+ setMessages((prev) => prev.map((m) => m.id === rid ? { ...m, isStreaming: false } : m));
958
+ }
959
+ } else if (event.type === "CUSTOM") {
960
+ chatLogger.debug("custom event", { name: event.name });
961
+ if (event.name === "hitl_request") {
962
+ const value2 = event.value;
963
+ chatLogger.info("hitl interrupt", { actionCount: value2.actionRequests?.length ?? 0 });
964
+ setInterrupt({ kind: "hitl", actionRequests: value2.actionRequests, reviewConfigs: value2.reviewConfigs });
965
+ } else if (event.name === "clarification_request") {
966
+ const value2 = event.value;
967
+ chatLogger.info("clarification interrupt", { questionCount: value2.questions?.length ?? 0 });
968
+ setInterrupt({ kind: "clarification", questions: value2.questions });
969
+ } else if (event.name === "subagent_activity") {
970
+ const { toolCallId, ...entry } = event.value;
971
+ chatLogger.trace("subagent activity", { toolCallId, kind: entry.kind });
972
+ const existing = toolCallsMap.get(toolCallId);
973
+ if (existing) {
974
+ existing.subagentActivity = [...existing.subagentActivity || [], entry];
975
+ patchAssistant({});
976
+ }
977
+ } else if (event.name === "mcp_app") {
978
+ const val = event.value;
979
+ if (val?.toolCallId && val?.resourceUri && val?.mcpId) {
980
+ const existing = toolCallsMap.get(val.toolCallId);
981
+ if (existing) {
982
+ existing.mcpApp = { resourceUri: val.resourceUri, mcpId: val.mcpId };
983
+ patchAssistant({});
984
+ }
985
+ }
986
+ }
987
+ } else if (event.type === "title") {
988
+ const title = event.title;
989
+ if (typeof title === "string" && title.trim()) {
990
+ chatLogger.info("auto title", { title });
991
+ options.onTitle?.(title);
992
+ }
993
+ } else if (event.type === "RUN_ERROR") {
994
+ chatLogger.warn("run error", { message: event.message, code: event.code });
995
+ chatLogger.error("stream run error", { code: event.code, message: event.message });
996
+ throw new Error(event.message || "Stream error from agent");
997
+ } else {
998
+ chatLogger.trace("unhandled event", { type: event.type });
999
+ }
1000
+ } catch (e) {
1001
+ if (e instanceof Error && e.message.startsWith("Stream error")) throw e;
1002
+ chatLogger.warn("event parse error", { raw: raw.slice(0, 200), error: e instanceof Error ? e.message : String(e) });
1003
+ }
1004
+ }
1005
+ }
1006
+ const finalMessage = {
1007
+ id: assistantMessageId,
1008
+ role: "assistant",
1009
+ content: accumulatedText,
1010
+ createdAt: /* @__PURE__ */ new Date(),
1011
+ isStreaming: false,
1012
+ toolCalls: Array.from(toolCallsMap.values())
1013
+ };
1014
+ setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? finalMessage : msg));
1015
+ chatLogger.info("sendMessage succeeded", { agentId: targetAgentId, textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });
1016
+ chatLogger.debug("sendMessage completed", { agentId: targetAgentId, textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });
1017
+ options.onFinish?.(finalMessage);
1018
+ return true;
1019
+ } catch (err) {
1020
+ if (controller.signal.aborted) {
1021
+ chatLogger.info("sendMessage aborted", { agentId: targetAgentId });
1022
+ chatLogger.debug("stream aborted", { agentId: targetAgentId });
1023
+ setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg));
1024
+ return false;
1025
+ }
1026
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1027
+ chatLogger.warn("sendMessage failed", { agentId: targetAgentId, error: errorObj.message });
1028
+ chatLogger.error("sendMessage error", { agentId: targetAgentId, error: errorObj.message });
1029
+ setError(errorObj);
1030
+ options.onError?.(errorObj);
1031
+ setMessages(
1032
+ (prev) => prev.map(
1033
+ (msg) => msg.id === assistantMessageId ? { ...msg, content: msg.content || `\u26A0\uFE0F Error: ${errorObj.message || "Failed to get response."}`, isStreaming: false } : msg
1034
+ )
1035
+ );
1036
+ return false;
1037
+ } finally {
1038
+ setIsStreaming(false);
1039
+ abortControllerRef.current = null;
1040
+ finalizeReasoning();
1041
+ chatLogger.debug("sendMessage finally", { agentId: targetAgentId, isStreaming: false });
1042
+ chatLogger.trace("sendMessage end", { agentId: targetAgentId });
1043
+ }
1044
+ },
1045
+ [agentId, baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId]
1046
+ );
1047
+ const sendMessage = (0, import_react2.useCallback)(
1048
+ async (contentToSend, overrideOptions) => {
1049
+ const prompt = (contentToSend ?? input).trim();
1050
+ if (!prompt || isStreaming) {
1051
+ chatLogger.trace("sendMessage skipped", {
1052
+ hasPrompt: !!prompt,
1053
+ isStreaming
1054
+ });
1055
+ if (isStreaming) {
1056
+ chatLogger.warn("sendMessage dropped while streaming \u2014 caller should queue or disable send", {});
1057
+ }
1058
+ return false;
1059
+ }
1060
+ return doSend(prompt, messages, overrideOptions);
1061
+ },
1062
+ [input, isStreaming, messages, doSend, chatLogger]
1063
+ );
1064
+ const handleInputChange = (0, import_react2.useCallback)(
1065
+ (e) => {
1066
+ chatLogger.trace("handleInputChange", { length: e.target.value.length });
1067
+ setInput(e.target.value);
1068
+ },
1069
+ [chatLogger]
1070
+ );
1071
+ const handleSubmit = (0, import_react2.useCallback)(
1072
+ (e) => {
1073
+ if (e) e.preventDefault();
1074
+ chatLogger.debug("handleSubmit", {});
1075
+ void sendMessage();
1076
+ },
1077
+ [sendMessage, chatLogger]
1078
+ );
1079
+ const reload = (0, import_react2.useCallback)(async () => {
1080
+ if (messages.length === 0 || isStreaming) {
1081
+ chatLogger.trace("reload skipped", {
1082
+ messageCount: messages.length,
1083
+ isStreaming
1084
+ });
1085
+ return false;
1086
+ }
1087
+ let lastUserIndex = -1;
1088
+ for (let i = messages.length - 1; i >= 0; i--) {
1089
+ if (messages[i].role === "user") {
1090
+ lastUserIndex = i;
1091
+ break;
1092
+ }
1093
+ }
1094
+ if (lastUserIndex === -1) {
1095
+ chatLogger.warn("reload no user message", {});
1096
+ return false;
1097
+ }
1098
+ const lastUserMessage = messages[lastUserIndex];
1099
+ const truncated = messages.slice(0, lastUserIndex);
1100
+ chatLogger.info("reload", { messageId: lastUserMessage.id });
1101
+ chatLogger.debug("reload last user", {
1102
+ preview: lastUserMessage.content.slice(0, 100)
1103
+ });
1104
+ return doSend(lastUserMessage.content, truncated);
1105
+ }, [isStreaming, messages, doSend, chatLogger]);
1106
+ const resumeInterrupt = (0, import_react2.useCallback)(
1107
+ (resume, displayContent) => {
1108
+ chatLogger.info("resumeInterrupt", {
1109
+ kind: resume.decisions ? "hitl" : "clarification",
1110
+ preview: displayContent.slice(0, 50)
1111
+ });
1112
+ return sendMessage(displayContent, { resume });
1113
+ },
1114
+ [sendMessage, chatLogger]
1115
+ );
1116
+ const dismissPresentedFile = (0, import_react2.useCallback)(() => {
1117
+ chatLogger.debug("dismissPresentedFile", {});
1118
+ setPresentedFile(null);
1119
+ }, [chatLogger]);
1120
+ const openWorkspaceFile = (0, import_react2.useCallback)(
1121
+ (path) => {
1122
+ chatLogger.debug("openWorkspaceFile", { path });
1123
+ setPresentedFile({
1124
+ path,
1125
+ title: path.split("/").pop() || path,
1126
+ description: ""
1127
+ });
1128
+ },
1129
+ [chatLogger]
1130
+ );
1131
+ return {
1132
+ messages,
1133
+ input,
1134
+ setInput,
1135
+ handleInputChange,
1136
+ handleSubmit,
1137
+ sendMessage,
1138
+ isStreaming,
1139
+ isLoading: isStreaming,
1140
+ isLoadingHistory,
1141
+ error,
1142
+ interrupt,
1143
+ resumeInterrupt,
1144
+ files,
1145
+ todos,
1146
+ presentedFile,
1147
+ dismissPresentedFile,
1148
+ openWorkspaceFile,
1149
+ sandboxCommands,
1150
+ stop,
1151
+ reload,
1152
+ clear,
1153
+ startNewChat,
1154
+ currentThreadId: effectiveThreadId,
1155
+ isEphemeral: !effectiveThreadId,
1156
+ setMessages,
1157
+ loadThreadMessages
1158
+ };
1159
+ }
1160
+
1161
+ // src/hooks/useArchitectChat.ts
1162
+ var import_react3 = require("react");
1163
+ var ARCHITECT_AGENT_ID = "000000000000000000000002";
1164
+ function useArchitectChat(options = {}) {
1165
+ const { fetchWithAuth, baseUrl, getAuthToken, logger } = usePersonaContext();
1166
+ const chatLogger = (0, import_react3.useMemo)(() => logger.child("architect"), [logger]);
1167
+ const threadId = options.threadId;
1168
+ const [internalThreadId, setInternalThreadId] = (0, import_react3.useState)(void 0);
1169
+ const effectiveThreadId = threadId ?? internalThreadId;
1170
+ (0, import_react3.useEffect)(() => {
1171
+ if (threadId !== void 0) setInternalThreadId(threadId);
1172
+ }, [threadId]);
1173
+ const didLogInitRef = (0, import_react3.useRef)(false);
1174
+ if (!didLogInitRef.current) {
1175
+ didLogInitRef.current = true;
1176
+ chatLogger.debug("useArchitectChat init", {
1177
+ threadId,
1178
+ hasInitialMessages: !!options.initialMessages?.length
1179
+ });
1180
+ chatLogger.trace("useArchitectChat options", {
1181
+ threadId,
1182
+ initialMessageCount: options.initialMessages?.length ?? 0
1183
+ });
1184
+ }
1185
+ const [messages, setMessages] = (0, import_react3.useState)(
1186
+ options.initialMessages || []
1187
+ );
1188
+ const [input, setInput] = (0, import_react3.useState)("");
1189
+ const [isStreaming, setIsStreaming] = (0, import_react3.useState)(false);
1190
+ const [isLoadingHistory, setIsLoadingHistory] = (0, import_react3.useState)(false);
1191
+ const [error, setError] = (0, import_react3.useState)(null);
1192
+ const [interrupt, setInterrupt] = (0, import_react3.useState)(null);
1193
+ const [files, setFiles] = (0, import_react3.useState)({});
1194
+ const [todos, setTodos] = (0, import_react3.useState)([]);
1195
+ const [presentedFile, setPresentedFile] = (0, import_react3.useState)(null);
1196
+ const abortControllerRef = (0, import_react3.useRef)(null);
1197
+ const loadedThreadIdRef = (0, import_react3.useRef)(void 0);
1198
+ const stop = (0, import_react3.useCallback)(() => {
1199
+ if (abortControllerRef.current) {
1200
+ chatLogger.info("stop streaming", {});
1201
+ chatLogger.debug("abort controller", {
1202
+ hasController: !!abortControllerRef.current
1203
+ });
1204
+ abortControllerRef.current.abort();
1205
+ abortControllerRef.current = null;
1206
+ setIsStreaming(false);
1207
+ chatLogger.debug("streaming stopped");
1208
+ } else {
1209
+ chatLogger.trace("stop called \u2014 no active stream");
1210
+ }
1211
+ }, [chatLogger]);
1212
+ const clear = (0, import_react3.useCallback)(() => {
509
1213
  chatLogger.info("clear chat", { messageCount: messages.length });
510
1214
  chatLogger.debug("clear", { messageCount: messages.length });
511
1215
  stop();
@@ -517,7 +1221,7 @@ function useChat(options = {}) {
517
1221
  setPresentedFile(null);
518
1222
  loadedThreadIdRef.current = void 0;
519
1223
  }, [stop, chatLogger, messages.length]);
520
- const startNewChat = (0, import_react2.useCallback)(() => {
1224
+ const startNewChat = (0, import_react3.useCallback)(() => {
521
1225
  chatLogger.info("startNewChat \u2014 entering ephemeral mode");
522
1226
  stop();
523
1227
  setMessages([]);
@@ -528,13 +1232,9 @@ function useChat(options = {}) {
528
1232
  setPresentedFile(null);
529
1233
  setInput("");
530
1234
  loadedThreadIdRef.current = void 0;
531
- voiceThreadRef.current = void 0;
532
- voicePrevLenRef.current = 0;
533
- voiceStreamingIdRef.current = null;
534
- voiceUserPartialIdRef.current = null;
535
1235
  setInternalThreadId(void 0);
536
1236
  }, [stop, chatLogger]);
537
- const loadThreadMessages = (0, import_react2.useCallback)(
1237
+ const loadThreadMessages = (0, import_react3.useCallback)(
538
1238
  async (id) => {
539
1239
  chatLogger.debug("loadThreadMessages start", { threadId: id });
540
1240
  chatLogger.trace("loadThreadMessages", { threadId: id });
@@ -595,7 +1295,7 @@ function useChat(options = {}) {
595
1295
  },
596
1296
  [fetchWithAuth, chatLogger]
597
1297
  );
598
- (0, import_react2.useEffect)(() => {
1298
+ (0, import_react3.useEffect)(() => {
599
1299
  if (!effectiveThreadId || isStreaming) {
600
1300
  chatLogger.trace("auto-load skipped", { threadId: effectiveThreadId, isStreaming });
601
1301
  return;
@@ -615,152 +1315,17 @@ function useChat(options = {}) {
615
1315
  chatLogger.debug("loadThreadMessages trigger", { threadId: effectiveThreadId });
616
1316
  void loadThreadMessages(effectiveThreadId);
617
1317
  }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);
618
- const voice = options.voice;
619
- (0, import_react2.useEffect)(() => {
620
- if (!voice) return;
621
- if (voiceThreadRef.current !== effectiveThreadId) {
622
- voiceThreadRef.current = effectiveThreadId;
623
- voicePrevLenRef.current = voice.transcript.length;
624
- voiceStreamingIdRef.current = null;
625
- voiceUserPartialIdRef.current = null;
626
- return;
627
- }
628
- const isVoiceActive = voice.state !== "idle" && voice.state !== "ended" && voice.state !== "error";
629
- const curLen = voice.transcript.length;
630
- if (curLen < voicePrevLenRef.current) {
631
- voicePrevLenRef.current = 0;
632
- voiceStreamingIdRef.current = null;
633
- voiceUserPartialIdRef.current = null;
634
- }
635
- if (!isVoiceActive) {
636
- if (curLen > voicePrevLenRef.current) {
637
- const pendingLines = voice.transcript.slice(voicePrevLenRef.current);
638
- voicePrevLenRef.current = curLen;
639
- for (const line of pendingLines) {
640
- const text = (line.text || "").trim();
641
- if (!text) continue;
642
- const role = line.speaker === "user" ? "user" : "assistant";
643
- const voiceId = `voice-${line.id}`;
644
- setMessages((prev) => {
645
- if (prev.some((m) => m.id === voiceId)) return prev;
646
- if (prev.some((m) => !m.id.startsWith("voice-") && m.role === role && m.content.trim() === text)) return prev;
647
- const last = prev[prev.length - 1];
648
- if (last?.id.startsWith("voice-") && last.role === "assistant" && role === "assistant") {
649
- const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();
650
- return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];
651
- }
652
- return [...prev, { id: voiceId, role, content: text, createdAt: /* @__PURE__ */ new Date() }];
653
- });
654
- }
655
- } else {
656
- voicePrevLenRef.current = voice.transcript.length;
657
- }
658
- if (voiceStreamingIdRef.current) {
659
- const doneId = voiceStreamingIdRef.current;
660
- voiceStreamingIdRef.current = null;
661
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
662
- }
663
- if (voiceUserPartialIdRef.current) {
664
- const doneId = voiceUserPartialIdRef.current;
665
- voiceUserPartialIdRef.current = null;
666
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
667
- }
668
- return;
669
- }
670
- if (curLen > voicePrevLenRef.current) {
671
- const newLines = voice.transcript.slice(voicePrevLenRef.current);
672
- voicePrevLenRef.current = curLen;
673
- for (const line of newLines) {
674
- const text = (line.text || "").trim();
675
- if (!text) continue;
676
- const role = line.speaker === "user" ? "user" : "assistant";
677
- const voiceId = `voice-${line.id}`;
678
- setMessages((prev) => {
679
- if (prev.some((m) => m.id === voiceId)) return prev;
680
- if (prev.some(
681
- (m) => !m.id.startsWith("voice-") && m.role === role && m.content.trim() === text
682
- ))
683
- return prev;
684
- const last = prev[prev.length - 1];
685
- if (last?.id.startsWith("voice-") && last.role === "assistant" && role === "assistant") {
686
- const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();
687
- return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];
688
- }
689
- return [...prev, { id: voiceId, role, content: text, createdAt: /* @__PURE__ */ new Date() }];
690
- });
691
- }
692
- }
693
- const agentPartialText = voice.partial?.speaker === "agent" ? voice.partial.text.trim() : "";
694
- const userPartialText = voice.partial?.speaker === "user" ? voice.partial.text.trim() : "";
695
- if (agentPartialText) {
696
- if (voiceUserPartialIdRef.current) {
697
- const doneId = voiceUserPartialIdRef.current;
698
- voiceUserPartialIdRef.current = null;
699
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
700
- }
701
- setMessages((prev) => {
702
- const last = prev[prev.length - 1];
703
- if (last?.id.startsWith("voice-") && last.role === "assistant") {
704
- voiceStreamingIdRef.current = last.id;
705
- return [...prev.slice(0, -1), { ...last, content: agentPartialText, isStreaming: true }];
706
- }
707
- const id = voiceStreamingIdRef.current || `voice-partial-${Date.now()}`;
708
- voiceStreamingIdRef.current = id;
709
- return [...prev, { id, role: "assistant", content: agentPartialText, isStreaming: true, createdAt: /* @__PURE__ */ new Date() }];
710
- });
711
- } else if (userPartialText) {
712
- if (voiceStreamingIdRef.current) {
713
- const doneId = voiceStreamingIdRef.current;
714
- voiceStreamingIdRef.current = null;
715
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
716
- }
717
- setMessages((prev) => {
718
- const last = prev[prev.length - 1];
719
- if (last?.id.startsWith("voice-") && last.role === "user" && last.isStreaming) {
720
- voiceUserPartialIdRef.current = last.id;
721
- return [...prev.slice(0, -1), { ...last, content: userPartialText, isStreaming: true }];
722
- }
723
- const id = voiceUserPartialIdRef.current || `voice-partial-user-${Date.now()}`;
724
- voiceUserPartialIdRef.current = id;
725
- return [...prev, { id, role: "user", content: userPartialText, isStreaming: true, createdAt: /* @__PURE__ */ new Date() }];
726
- });
727
- } else {
728
- if (voiceStreamingIdRef.current && voice.state !== "speaking") {
729
- const doneId = voiceStreamingIdRef.current;
730
- voiceStreamingIdRef.current = null;
731
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
732
- }
733
- if (voiceUserPartialIdRef.current) {
734
- const doneId = voiceUserPartialIdRef.current;
735
- voiceUserPartialIdRef.current = null;
736
- setMessages((prev) => prev.map((m) => m.id === doneId ? { ...m, isStreaming: false } : m));
737
- }
738
- }
739
- }, [voice?.transcript, voice?.partial, voice?.state, effectiveThreadId]);
740
- const doSend = (0, import_react2.useCallback)(
1318
+ const doSend = (0, import_react3.useCallback)(
741
1319
  async (prompt, baseMessages, overrideOptions) => {
742
- const targetAgentId = overrideOptions?.agentId || agentId;
743
- if (!targetAgentId) {
744
- const err = new Error("No Agent ID specified for useChat.");
745
- chatLogger.warn("sendMessage no agentId", {});
746
- chatLogger.error("sendMessage failed \u2014 no agent", { error: err.message });
747
- setError(err);
748
- options.onError?.(err);
749
- return false;
750
- }
751
1320
  chatLogger.debug("sendMessage start", {
752
1321
  promptPreview: prompt.slice(0, 100),
753
- agentId: targetAgentId,
754
1322
  threadId: effectiveThreadId ?? overrideOptions?.threadId,
755
1323
  hasResume: !!overrideOptions?.resume,
756
- hasContextOverride: !!overrideOptions?.contextOverride,
757
1324
  messageCount: baseMessages.length
758
1325
  });
759
1326
  chatLogger.trace("sendMessage details", {
760
- agentId: targetAgentId,
761
1327
  promptPreview: prompt.slice(0, 200),
762
- hasResume: !!overrideOptions?.resume,
763
- hasContextOverride: !!overrideOptions?.contextOverride
1328
+ hasResume: !!overrideOptions?.resume
764
1329
  });
765
1330
  const userMessage = {
766
1331
  id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
@@ -797,11 +1362,11 @@ function useChat(options = {}) {
797
1362
  }));
798
1363
  let resolvedThreadId = await overrideOptions?.threadId ?? effectiveThreadId;
799
1364
  if (!resolvedThreadId) {
800
- chatLogger.info("minting real thread for ephemeral chat", { agentId: targetAgentId });
1365
+ chatLogger.info("minting real thread for ephemeral architect chat", {});
801
1366
  const createRes = await fetchWithAuth("/threads", {
802
1367
  method: "POST",
803
1368
  headers: { "Content-Type": "application/json" },
804
- body: JSON.stringify({ agentId: targetAgentId })
1369
+ body: JSON.stringify({ agentId: ARCHITECT_AGENT_ID })
805
1370
  });
806
1371
  if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);
807
1372
  const createBody = await createRes.json();
@@ -811,42 +1376,34 @@ function useChat(options = {}) {
811
1376
  setInternalThreadId(resolvedThreadId);
812
1377
  loadedThreadIdRef.current = resolvedThreadId;
813
1378
  options.onThreadCreated?.(resolvedThreadId);
814
- chatLogger.info("ephemeral chat minted", { threadId: resolvedThreadId });
1379
+ chatLogger.info("ephemeral architect chat minted", { threadId: resolvedThreadId });
815
1380
  }
816
1381
  chatLogger.trace("resolved threadId", { threadId: resolvedThreadId });
817
1382
  const token = getAuthToken ? await getAuthToken() : null;
818
- const resolvedHookContext = typeof options.context === "function" ? options.context() : options.context;
819
- const mergedContext = { ...resolvedHookContext, ...overrideOptions?.context };
820
- const hasContext = Object.keys(mergedContext).length > 0;
821
1383
  chatLogger.debug("opening SSE stream", {
822
- agentId: targetAgentId,
823
1384
  hasToken: !!token,
824
- hasThreadId: !!resolvedThreadId,
825
- hasContext
1385
+ hasThreadId: !!resolvedThreadId
826
1386
  });
827
1387
  const stream = await openSSEStream({
828
- url: `${baseUrl}/chat`,
1388
+ url: `${baseUrl}/architect`,
829
1389
  headers: {
830
1390
  "Content-Type": "application/json",
831
1391
  ...token ? { Authorization: `Bearer ${token}` } : {}
832
1392
  },
833
1393
  body: JSON.stringify({
834
- agentId: targetAgentId,
835
1394
  messages: payloadMessages,
836
1395
  threadId: resolvedThreadId,
837
- resume: overrideOptions?.resume,
838
- contextOverride: overrideOptions?.contextOverride,
839
- ...hasContext ? { context: mergedContext } : {}
1396
+ resume: overrideOptions?.resume
840
1397
  }),
841
1398
  signal: controller.signal
842
1399
  });
843
1400
  if (!stream.ok) {
844
1401
  chatLogger.warn("SSE stream not ok", { status: stream.status, errorText: stream.errorText });
845
- chatLogger.error("chat stream failed", { agentId: targetAgentId, status: stream.status, error: stream.errorText });
846
- throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? "Stream failed"}`);
1402
+ chatLogger.error("architect stream failed", { status: stream.status, error: stream.errorText });
1403
+ throw new Error(`Architect error (${stream.status}): ${stream.errorText ?? "Stream failed"}`);
847
1404
  }
848
- chatLogger.debug("SSE stream opened", { agentId: targetAgentId, status: stream.status });
849
- chatLogger.info("chat stream started", { agentId: targetAgentId, threadId: resolvedThreadId });
1405
+ chatLogger.debug("SSE stream opened", { status: stream.status });
1406
+ chatLogger.info("architect stream started", { threadId: resolvedThreadId });
850
1407
  const reader = stream.reader;
851
1408
  let buffer = "";
852
1409
  let accumulatedText = "";
@@ -1008,20 +1565,20 @@ function useChat(options = {}) {
1008
1565
  toolCalls: Array.from(toolCallsMap.values())
1009
1566
  };
1010
1567
  setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? finalMessage : msg));
1011
- chatLogger.info("sendMessage succeeded", { agentId: targetAgentId, textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });
1012
- chatLogger.debug("sendMessage completed", { agentId: targetAgentId, textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });
1568
+ chatLogger.info("sendMessage succeeded", { textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });
1569
+ chatLogger.debug("sendMessage completed", { textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });
1013
1570
  options.onFinish?.(finalMessage);
1014
1571
  return true;
1015
1572
  } catch (err) {
1016
1573
  if (controller.signal.aborted) {
1017
- chatLogger.info("sendMessage aborted", { agentId: targetAgentId });
1018
- chatLogger.debug("stream aborted", { agentId: targetAgentId });
1574
+ chatLogger.info("sendMessage aborted", {});
1575
+ chatLogger.debug("stream aborted", {});
1019
1576
  setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg));
1020
1577
  return false;
1021
1578
  }
1022
1579
  const errorObj = err instanceof Error ? err : new Error(String(err));
1023
- chatLogger.warn("sendMessage failed", { agentId: targetAgentId, error: errorObj.message });
1024
- chatLogger.error("sendMessage error", { agentId: targetAgentId, error: errorObj.message });
1580
+ chatLogger.warn("sendMessage failed", { error: errorObj.message });
1581
+ chatLogger.error("sendMessage error", { error: errorObj.message });
1025
1582
  setError(errorObj);
1026
1583
  options.onError?.(errorObj);
1027
1584
  setMessages(
@@ -1034,13 +1591,13 @@ function useChat(options = {}) {
1034
1591
  setIsStreaming(false);
1035
1592
  abortControllerRef.current = null;
1036
1593
  finalizeReasoning();
1037
- chatLogger.debug("sendMessage finally", { agentId: targetAgentId, isStreaming: false });
1038
- chatLogger.trace("sendMessage end", { agentId: targetAgentId });
1594
+ chatLogger.debug("sendMessage finally", { isStreaming: false });
1595
+ chatLogger.trace("sendMessage end", {});
1039
1596
  }
1040
1597
  },
1041
- [agentId, baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId]
1598
+ [baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId]
1042
1599
  );
1043
- const sendMessage = (0, import_react2.useCallback)(
1600
+ const sendMessage = (0, import_react3.useCallback)(
1044
1601
  async (contentToSend, overrideOptions) => {
1045
1602
  const prompt = (contentToSend ?? input).trim();
1046
1603
  if (!prompt || isStreaming) {
@@ -1057,14 +1614,14 @@ function useChat(options = {}) {
1057
1614
  },
1058
1615
  [input, isStreaming, messages, doSend, chatLogger]
1059
1616
  );
1060
- const handleInputChange = (0, import_react2.useCallback)(
1617
+ const handleInputChange = (0, import_react3.useCallback)(
1061
1618
  (e) => {
1062
1619
  chatLogger.trace("handleInputChange", { length: e.target.value.length });
1063
1620
  setInput(e.target.value);
1064
1621
  },
1065
1622
  [chatLogger]
1066
1623
  );
1067
- const handleSubmit = (0, import_react2.useCallback)(
1624
+ const handleSubmit = (0, import_react3.useCallback)(
1068
1625
  (e) => {
1069
1626
  if (e) e.preventDefault();
1070
1627
  chatLogger.debug("handleSubmit", {});
@@ -1072,7 +1629,7 @@ function useChat(options = {}) {
1072
1629
  },
1073
1630
  [sendMessage, chatLogger]
1074
1631
  );
1075
- const reload = (0, import_react2.useCallback)(async () => {
1632
+ const reload = (0, import_react3.useCallback)(async () => {
1076
1633
  if (messages.length === 0 || isStreaming) {
1077
1634
  chatLogger.trace("reload skipped", {
1078
1635
  messageCount: messages.length,
@@ -1099,7 +1656,7 @@ function useChat(options = {}) {
1099
1656
  });
1100
1657
  return doSend(lastUserMessage.content, truncated);
1101
1658
  }, [isStreaming, messages, doSend, chatLogger]);
1102
- const resumeInterrupt = (0, import_react2.useCallback)(
1659
+ const resumeInterrupt = (0, import_react3.useCallback)(
1103
1660
  (resume, displayContent) => {
1104
1661
  chatLogger.info("resumeInterrupt", {
1105
1662
  kind: resume.decisions ? "hitl" : "clarification",
@@ -1109,11 +1666,11 @@ function useChat(options = {}) {
1109
1666
  },
1110
1667
  [sendMessage, chatLogger]
1111
1668
  );
1112
- const dismissPresentedFile = (0, import_react2.useCallback)(() => {
1669
+ const dismissPresentedFile = (0, import_react3.useCallback)(() => {
1113
1670
  chatLogger.debug("dismissPresentedFile", {});
1114
1671
  setPresentedFile(null);
1115
1672
  }, [chatLogger]);
1116
- const openWorkspaceFile = (0, import_react2.useCallback)(
1673
+ const openWorkspaceFile = (0, import_react3.useCallback)(
1117
1674
  (path) => {
1118
1675
  chatLogger.debug("openWorkspaceFile", { path });
1119
1676
  setPresentedFile({
@@ -1142,7 +1699,6 @@ function useChat(options = {}) {
1142
1699
  presentedFile,
1143
1700
  dismissPresentedFile,
1144
1701
  openWorkspaceFile,
1145
- sandboxCommands,
1146
1702
  stop,
1147
1703
  reload,
1148
1704
  clear,
@@ -1155,16 +1711,16 @@ function useChat(options = {}) {
1155
1711
  }
1156
1712
 
1157
1713
  // src/hooks/useMemory.ts
1158
- var import_react3 = require("react");
1714
+ var import_react4 = require("react");
1159
1715
  function useMemory(autoFetch = true) {
1160
1716
  const { fetchWithAuth } = usePersonaContext();
1161
- const [memory, setMemory] = (0, import_react3.useState)({
1717
+ const [memory, setMemory] = (0, import_react4.useState)({
1162
1718
  userFiles: [],
1163
1719
  agentMemories: []
1164
1720
  });
1165
- const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
1166
- const [error, setError] = (0, import_react3.useState)(null);
1167
- const fetchMemory = (0, import_react3.useCallback)(async () => {
1721
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
1722
+ const [error, setError] = (0, import_react4.useState)(null);
1723
+ const fetchMemory = (0, import_react4.useCallback)(async () => {
1168
1724
  setIsLoading(true);
1169
1725
  setError(null);
1170
1726
  try {
@@ -1183,7 +1739,7 @@ function useMemory(autoFetch = true) {
1183
1739
  setIsLoading(false);
1184
1740
  }
1185
1741
  }, [fetchWithAuth]);
1186
- const getFile = (0, import_react3.useCallback)(
1742
+ const getFile = (0, import_react4.useCallback)(
1187
1743
  async (params) => {
1188
1744
  const query = new URLSearchParams({ path: params.path });
1189
1745
  if (params.scope) query.set("scope", params.scope);
@@ -1195,7 +1751,7 @@ function useMemory(autoFetch = true) {
1195
1751
  },
1196
1752
  [fetchWithAuth]
1197
1753
  );
1198
- const writeFile = (0, import_react3.useCallback)(
1754
+ const writeFile = (0, import_react4.useCallback)(
1199
1755
  async (params) => {
1200
1756
  const res = await fetchWithAuth("/memory/file", {
1201
1757
  method: "PUT",
@@ -1210,7 +1766,7 @@ function useMemory(autoFetch = true) {
1210
1766
  },
1211
1767
  [fetchWithAuth, fetchMemory]
1212
1768
  );
1213
- const deleteFile = (0, import_react3.useCallback)(
1769
+ const deleteFile = (0, import_react4.useCallback)(
1214
1770
  async (params) => {
1215
1771
  const query = new URLSearchParams({ path: params.path });
1216
1772
  if (params.scope) query.set("scope", params.scope);
@@ -1224,7 +1780,7 @@ function useMemory(autoFetch = true) {
1224
1780
  },
1225
1781
  [fetchWithAuth, fetchMemory]
1226
1782
  );
1227
- (0, import_react3.useEffect)(() => {
1783
+ (0, import_react4.useEffect)(() => {
1228
1784
  if (autoFetch) {
1229
1785
  void fetchMemory();
1230
1786
  }
@@ -1241,13 +1797,13 @@ function useMemory(autoFetch = true) {
1241
1797
  }
1242
1798
 
1243
1799
  // src/hooks/useThreads.ts
1244
- var import_react4 = require("react");
1800
+ var import_react5 = require("react");
1245
1801
  function useThreads(autoFetch = true) {
1246
1802
  const { fetchWithAuth, defaultAgentId } = usePersonaContext();
1247
- const [threads, setThreads] = (0, import_react4.useState)([]);
1248
- const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
1249
- const [error, setError] = (0, import_react4.useState)(null);
1250
- const fetchThreads = (0, import_react4.useCallback)(async () => {
1803
+ const [threads, setThreads] = (0, import_react5.useState)([]);
1804
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
1805
+ const [error, setError] = (0, import_react5.useState)(null);
1806
+ const fetchThreads = (0, import_react5.useCallback)(async () => {
1251
1807
  setIsLoading(true);
1252
1808
  setError(null);
1253
1809
  try {
@@ -1265,7 +1821,7 @@ function useThreads(autoFetch = true) {
1265
1821
  setIsLoading(false);
1266
1822
  }
1267
1823
  }, [fetchWithAuth]);
1268
- const createThread = (0, import_react4.useCallback)(
1824
+ const createThread = (0, import_react5.useCallback)(
1269
1825
  async (agentId) => {
1270
1826
  const targetAgentId = agentId || defaultAgentId;
1271
1827
  const res = await fetchWithAuth("/threads", {
@@ -1282,7 +1838,7 @@ function useThreads(autoFetch = true) {
1282
1838
  },
1283
1839
  [fetchWithAuth, defaultAgentId, fetchThreads]
1284
1840
  );
1285
- const deleteThread = (0, import_react4.useCallback)(
1841
+ const deleteThread = (0, import_react5.useCallback)(
1286
1842
  async (threadId) => {
1287
1843
  const res = await fetchWithAuth(`/threads/${threadId}`, {
1288
1844
  method: "DELETE"
@@ -1293,7 +1849,7 @@ function useThreads(autoFetch = true) {
1293
1849
  },
1294
1850
  [fetchWithAuth]
1295
1851
  );
1296
- const bulkDeleteThreads = (0, import_react4.useCallback)(
1852
+ const bulkDeleteThreads = (0, import_react5.useCallback)(
1297
1853
  async (threadIds) => {
1298
1854
  const res = await fetchWithAuth("/threads/bulk-delete", {
1299
1855
  method: "POST",
@@ -1310,13 +1866,13 @@ function useThreads(autoFetch = true) {
1310
1866
  },
1311
1867
  [fetchWithAuth]
1312
1868
  );
1313
- const deleteAllThreads = (0, import_react4.useCallback)(async () => {
1869
+ const deleteAllThreads = (0, import_react5.useCallback)(async () => {
1314
1870
  const ids = threads.map((t) => t._id);
1315
1871
  for (let i = 0; i < ids.length; i += 100) {
1316
1872
  await bulkDeleteThreads(ids.slice(i, i + 100));
1317
1873
  }
1318
1874
  }, [threads, bulkDeleteThreads]);
1319
- const updateThread = (0, import_react4.useCallback)(
1875
+ const updateThread = (0, import_react5.useCallback)(
1320
1876
  async (threadId, input) => {
1321
1877
  const res = await fetchWithAuth(`/threads/${threadId}`, {
1322
1878
  method: "PATCH",
@@ -1334,11 +1890,11 @@ function useThreads(autoFetch = true) {
1334
1890
  },
1335
1891
  [fetchWithAuth]
1336
1892
  );
1337
- const renameThread = (0, import_react4.useCallback)(
1893
+ const renameThread = (0, import_react5.useCallback)(
1338
1894
  (threadId, title) => updateThread(threadId, { title }),
1339
1895
  [updateThread]
1340
1896
  );
1341
- const resetThread = (0, import_react4.useCallback)(
1897
+ const resetThread = (0, import_react5.useCallback)(
1342
1898
  async (threadId) => {
1343
1899
  const res = await fetchWithAuth(`/threads/${threadId}/reset`, {
1344
1900
  method: "POST"
@@ -1353,7 +1909,7 @@ function useThreads(autoFetch = true) {
1353
1909
  },
1354
1910
  [fetchWithAuth]
1355
1911
  );
1356
- const getThread = (0, import_react4.useCallback)(
1912
+ const getThread = (0, import_react5.useCallback)(
1357
1913
  async (threadId) => {
1358
1914
  const res = await fetchWithAuth(`/threads/${threadId}`);
1359
1915
  if (!res.ok) throw new Error(`Failed to fetch thread: ${res.statusText}`);
@@ -1362,7 +1918,7 @@ function useThreads(autoFetch = true) {
1362
1918
  },
1363
1919
  [fetchWithAuth]
1364
1920
  );
1365
- (0, import_react4.useEffect)(() => {
1921
+ (0, import_react5.useEffect)(() => {
1366
1922
  if (autoFetch) {
1367
1923
  void fetchThreads();
1368
1924
  }
@@ -1384,7 +1940,7 @@ function useThreads(autoFetch = true) {
1384
1940
  }
1385
1941
 
1386
1942
  // src/hooks/useVoice.ts
1387
- var import_react5 = require("react");
1943
+ var import_react6 = require("react");
1388
1944
 
1389
1945
  // src/hooks/voiceWorklets.ts
1390
1946
  var RECORDER_WORKLET_SOURCE = `
@@ -1487,42 +2043,42 @@ function mergeTranscriptText(prev, next) {
1487
2043
  }
1488
2044
  function useVoice(options = {}) {
1489
2045
  const { defaultAgentId, fetchWithAuth, logger } = usePersonaContext();
1490
- const voiceLogger = (0, import_react5.useMemo)(() => logger.child("voice"), [logger]);
2046
+ const voiceLogger = (0, import_react6.useMemo)(() => logger.child("voice"), [logger]);
1491
2047
  const agentId = options.agentId || defaultAgentId;
1492
2048
  const threadId = options.threadId;
1493
2049
  const contextOverride = options.contextOverride;
1494
2050
  const context = options.context;
1495
- const [state, setState] = (0, import_react5.useState)("idle");
1496
- const [isMuted, setIsMuted] = (0, import_react5.useState)(false);
1497
- const [transcript, setTranscript] = (0, import_react5.useState)(
2051
+ const [state, setState] = (0, import_react6.useState)("idle");
2052
+ const [isMuted, setIsMuted] = (0, import_react6.useState)(false);
2053
+ const [transcript, setTranscript] = (0, import_react6.useState)(
1498
2054
  []
1499
2055
  );
1500
- const [partial, setPartial] = (0, import_react5.useState)(
2056
+ const [partial, setPartial] = (0, import_react6.useState)(
1501
2057
  null
1502
2058
  );
1503
- const [toolCalls, setToolCalls] = (0, import_react5.useState)([]);
1504
- const [error, setError] = (0, import_react5.useState)(null);
1505
- const [endReason, setEndReason] = (0, import_react5.useState)(
2059
+ const [toolCalls, setToolCalls] = (0, import_react6.useState)([]);
2060
+ const [error, setError] = (0, import_react6.useState)(null);
2061
+ const [endReason, setEndReason] = (0, import_react6.useState)(
1506
2062
  null
1507
2063
  );
1508
- const wsRef = (0, import_react5.useRef)(null);
1509
- const streamRef = (0, import_react5.useRef)(null);
1510
- const inputCtxRef = (0, import_react5.useRef)(null);
1511
- const outputCtxRef = (0, import_react5.useRef)(null);
1512
- const recorderNodeRef = (0, import_react5.useRef)(null);
1513
- const playerNodeRef = (0, import_react5.useRef)(null);
1514
- const acceptedTurnSeqRef = (0, import_react5.useRef)(0);
1515
- const mountedRef = (0, import_react5.useRef)(true);
1516
- const lastFinalTurnRef = (0, import_react5.useRef)(
2064
+ const wsRef = (0, import_react6.useRef)(null);
2065
+ const streamRef = (0, import_react6.useRef)(null);
2066
+ const inputCtxRef = (0, import_react6.useRef)(null);
2067
+ const outputCtxRef = (0, import_react6.useRef)(null);
2068
+ const recorderNodeRef = (0, import_react6.useRef)(null);
2069
+ const playerNodeRef = (0, import_react6.useRef)(null);
2070
+ const acceptedTurnSeqRef = (0, import_react6.useRef)(0);
2071
+ const mountedRef = (0, import_react6.useRef)(true);
2072
+ const lastFinalTurnRef = (0, import_react6.useRef)(
1517
2073
  null
1518
2074
  );
1519
- (0, import_react5.useEffect)(() => {
2075
+ (0, import_react6.useEffect)(() => {
1520
2076
  mountedRef.current = true;
1521
2077
  return () => {
1522
2078
  mountedRef.current = false;
1523
2079
  };
1524
2080
  }, []);
1525
- const teardownAudio = (0, import_react5.useCallback)(() => {
2081
+ const teardownAudio = (0, import_react6.useCallback)(() => {
1526
2082
  try {
1527
2083
  streamRef.current?.getTracks().forEach((track) => track.stop());
1528
2084
  } catch {
@@ -1549,7 +2105,7 @@ function useVoice(options = {}) {
1549
2105
  }
1550
2106
  outputCtxRef.current = null;
1551
2107
  }, []);
1552
- const stop = (0, import_react5.useCallback)(() => {
2108
+ const stop = (0, import_react6.useCallback)(() => {
1553
2109
  voiceLogger.debug("stop() called");
1554
2110
  try {
1555
2111
  wsRef.current?.close(1e3, "client_stop");
@@ -1559,8 +2115,8 @@ function useVoice(options = {}) {
1559
2115
  teardownAudio();
1560
2116
  if (mountedRef.current) setState("idle");
1561
2117
  }, [teardownAudio, voiceLogger]);
1562
- (0, import_react5.useEffect)(() => stop, [stop]);
1563
- const startCapture = (0, import_react5.useCallback)(async (inputSampleRate) => {
2118
+ (0, import_react6.useEffect)(() => stop, [stop]);
2119
+ const startCapture = (0, import_react6.useCallback)(async (inputSampleRate) => {
1564
2120
  const stream = await navigator.mediaDevices.getUserMedia({
1565
2121
  audio: {
1566
2122
  echoCancellation: true,
@@ -1586,7 +2142,7 @@ function useVoice(options = {}) {
1586
2142
  recorderNodeRef.current = recorderNode;
1587
2143
  source.connect(recorderNode);
1588
2144
  }, []);
1589
- const setupPlayback = (0, import_react5.useCallback)(async (outputSampleRate) => {
2145
+ const setupPlayback = (0, import_react6.useCallback)(async (outputSampleRate) => {
1590
2146
  const outputCtx = new AudioContext({ sampleRate: outputSampleRate });
1591
2147
  outputCtxRef.current = outputCtx;
1592
2148
  await outputCtx.audioWorklet.addModule(playerWorkletUrl());
@@ -1594,7 +2150,7 @@ function useVoice(options = {}) {
1594
2150
  playerNode.connect(outputCtx.destination);
1595
2151
  playerNodeRef.current = playerNode;
1596
2152
  }, []);
1597
- const upsertToolCall = (0, import_react5.useCallback)(
2153
+ const upsertToolCall = (0, import_react6.useCallback)(
1598
2154
  (id, patch) => {
1599
2155
  setToolCalls((prev) => {
1600
2156
  const idx = prev.findIndex((t) => t.id === id);
@@ -1606,7 +2162,7 @@ function useVoice(options = {}) {
1606
2162
  },
1607
2163
  []
1608
2164
  );
1609
- const handleTranscript = (0, import_react5.useCallback)((value) => {
2165
+ const handleTranscript = (0, import_react6.useCallback)((value) => {
1610
2166
  const { speaker, text, isFinal, turnSeq } = value;
1611
2167
  if (!isFinal) {
1612
2168
  setPartial({ id: "partial", speaker, text });
@@ -1629,7 +2185,7 @@ function useVoice(options = {}) {
1629
2185
  });
1630
2186
  lastFinalTurnRef.current = { speaker, turnSeq };
1631
2187
  }, []);
1632
- const handleCustomEvent = (0, import_react5.useCallback)(
2188
+ const handleCustomEvent = (0, import_react6.useCallback)(
1633
2189
  (name, value) => {
1634
2190
  switch (name) {
1635
2191
  case "voice_session_ready":
@@ -1687,7 +2243,7 @@ function useVoice(options = {}) {
1687
2243
  },
1688
2244
  [handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger]
1689
2245
  );
1690
- const handleMessage = (0, import_react5.useCallback)(
2246
+ const handleMessage = (0, import_react6.useCallback)(
1691
2247
  (event) => {
1692
2248
  if (typeof event.data !== "string") {
1693
2249
  const buf = event.data;
@@ -1745,7 +2301,7 @@ function useVoice(options = {}) {
1745
2301
  },
1746
2302
  [handleCustomEvent, upsertToolCall, voiceLogger]
1747
2303
  );
1748
- const start = (0, import_react5.useCallback)(async () => {
2304
+ const start = (0, import_react6.useCallback)(async () => {
1749
2305
  if (!agentId) {
1750
2306
  const err = new Error(
1751
2307
  "useVoice: no agentId provided and no defaultAgentId set on PersonaProvider"
@@ -1812,17 +2368,17 @@ function useVoice(options = {}) {
1812
2368
  teardownAudio();
1813
2369
  }
1814
2370
  }, [agentId, threadId, contextOverride, context, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);
1815
- const mute = (0, import_react5.useCallback)((muted) => {
2371
+ const mute = (0, import_react6.useCallback)((muted) => {
1816
2372
  setIsMuted(muted);
1817
2373
  streamRef.current?.getAudioTracks().forEach((track) => {
1818
2374
  track.enabled = !muted;
1819
2375
  });
1820
2376
  }, []);
1821
- const sendText = (0, import_react5.useCallback)((text) => {
2377
+ const sendText = (0, import_react6.useCallback)((text) => {
1822
2378
  if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;
1823
2379
  wsRef.current.send(JSON.stringify({ type: "voice.text", text }));
1824
2380
  }, []);
1825
- const updateContext = (0, import_react5.useCallback)((newContext) => {
2381
+ const updateContext = (0, import_react6.useCallback)((newContext) => {
1826
2382
  if (wsRef.current?.readyState !== WebSocket.OPEN) return;
1827
2383
  wsRef.current.send(JSON.stringify({ type: "voice.context", context: newContext }));
1828
2384
  }, []);
@@ -1843,14 +2399,14 @@ function useVoice(options = {}) {
1843
2399
  }
1844
2400
 
1845
2401
  // src/hooks/useFiles.ts
1846
- var import_react6 = require("react");
2402
+ var import_react7 = require("react");
1847
2403
  function useFiles(autoFetch = true) {
1848
2404
  const { fetchWithAuth } = usePersonaContext();
1849
- const [files, setFiles] = (0, import_react6.useState)([]);
1850
- const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
1851
- const [isUploading, setIsUploading] = (0, import_react6.useState)(false);
1852
- const [error, setError] = (0, import_react6.useState)(null);
1853
- const fetchFiles = (0, import_react6.useCallback)(async () => {
2405
+ const [files, setFiles] = (0, import_react7.useState)([]);
2406
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
2407
+ const [isUploading, setIsUploading] = (0, import_react7.useState)(false);
2408
+ const [error, setError] = (0, import_react7.useState)(null);
2409
+ const fetchFiles = (0, import_react7.useCallback)(async () => {
1854
2410
  setIsLoading(true);
1855
2411
  setError(null);
1856
2412
  try {
@@ -1868,7 +2424,7 @@ function useFiles(autoFetch = true) {
1868
2424
  setIsLoading(false);
1869
2425
  }
1870
2426
  }, [fetchWithAuth]);
1871
- const uploadFile = (0, import_react6.useCallback)(
2427
+ const uploadFile = (0, import_react7.useCallback)(
1872
2428
  async (fileOrFormData) => {
1873
2429
  setIsUploading(true);
1874
2430
  setError(null);
@@ -1901,7 +2457,7 @@ function useFiles(autoFetch = true) {
1901
2457
  },
1902
2458
  [fetchWithAuth, fetchFiles]
1903
2459
  );
1904
- const deleteFile = (0, import_react6.useCallback)(
2460
+ const deleteFile = (0, import_react7.useCallback)(
1905
2461
  async (fileId) => {
1906
2462
  const res = await fetchWithAuth(`/files/${fileId}`, { method: "DELETE" });
1907
2463
  if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);
@@ -1909,7 +2465,7 @@ function useFiles(autoFetch = true) {
1909
2465
  },
1910
2466
  [fetchWithAuth]
1911
2467
  );
1912
- const bulkDeleteFiles = (0, import_react6.useCallback)(
2468
+ const bulkDeleteFiles = (0, import_react7.useCallback)(
1913
2469
  async (fileIds) => {
1914
2470
  const res = await fetchWithAuth("/files/bulk-delete", {
1915
2471
  method: "POST",
@@ -1924,10 +2480,10 @@ function useFiles(autoFetch = true) {
1924
2480
  },
1925
2481
  [fetchWithAuth]
1926
2482
  );
1927
- const getDownloadUrl = (0, import_react6.useCallback)((fileId) => {
2483
+ const getDownloadUrl = (0, import_react7.useCallback)((fileId) => {
1928
2484
  return `/files/${fileId}`;
1929
2485
  }, []);
1930
- (0, import_react6.useEffect)(() => {
2486
+ (0, import_react7.useEffect)(() => {
1931
2487
  if (autoFetch) {
1932
2488
  void fetchFiles();
1933
2489
  }
@@ -1946,13 +2502,13 @@ function useFiles(autoFetch = true) {
1946
2502
  }
1947
2503
 
1948
2504
  // src/hooks/useAgents.ts
1949
- var import_react7 = require("react");
2505
+ var import_react8 = require("react");
1950
2506
  function useAgents(autoFetch = true) {
1951
2507
  const { fetchWithAuth } = usePersonaContext();
1952
- const [agents, setAgents] = (0, import_react7.useState)([]);
1953
- const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
1954
- const [error, setError] = (0, import_react7.useState)(null);
1955
- const fetchAgents = (0, import_react7.useCallback)(async () => {
2508
+ const [agents, setAgents] = (0, import_react8.useState)([]);
2509
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
2510
+ const [error, setError] = (0, import_react8.useState)(null);
2511
+ const fetchAgents = (0, import_react8.useCallback)(async () => {
1956
2512
  setIsLoading(true);
1957
2513
  setError(null);
1958
2514
  try {
@@ -1970,7 +2526,7 @@ function useAgents(autoFetch = true) {
1970
2526
  setIsLoading(false);
1971
2527
  }
1972
2528
  }, [fetchWithAuth]);
1973
- (0, import_react7.useEffect)(() => {
2529
+ (0, import_react8.useEffect)(() => {
1974
2530
  if (autoFetch) {
1975
2531
  void fetchAgents();
1976
2532
  }
@@ -1984,13 +2540,13 @@ function useAgents(autoFetch = true) {
1984
2540
  }
1985
2541
 
1986
2542
  // src/hooks/useConnection.ts
1987
- var import_react8 = require("react");
2543
+ var import_react9 = require("react");
1988
2544
  function useConnection(autoCheck = true) {
1989
2545
  const { fetchWithAuth } = usePersonaContext();
1990
- const [health, setHealth] = (0, import_react8.useState)(null);
1991
- const [isConnected, setIsConnected] = (0, import_react8.useState)(false);
1992
- const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
1993
- const checkHealth = (0, import_react8.useCallback)(async () => {
2546
+ const [health, setHealth] = (0, import_react9.useState)(null);
2547
+ const [isConnected, setIsConnected] = (0, import_react9.useState)(false);
2548
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
2549
+ const checkHealth = (0, import_react9.useCallback)(async () => {
1994
2550
  setIsLoading(true);
1995
2551
  try {
1996
2552
  const res = await fetchWithAuth("/health");
@@ -2009,7 +2565,7 @@ function useConnection(autoCheck = true) {
2009
2565
  setIsLoading(false);
2010
2566
  }
2011
2567
  }, [fetchWithAuth]);
2012
- (0, import_react8.useEffect)(() => {
2568
+ (0, import_react9.useEffect)(() => {
2013
2569
  if (autoCheck) {
2014
2570
  void checkHealth();
2015
2571
  }
@@ -2023,15 +2579,15 @@ function useConnection(autoCheck = true) {
2023
2579
  }
2024
2580
 
2025
2581
  // src/hooks/useMcpConnections.ts
2026
- var import_react9 = require("react");
2582
+ var import_react10 = require("react");
2027
2583
  function useMcpConnections(options = {}) {
2028
2584
  const { defaultAgentId, fetchWithAuth } = usePersonaContext();
2029
2585
  const agentId = options.agentId ?? defaultAgentId;
2030
2586
  const autoFetch = options.autoFetch ?? true;
2031
- const [connections, setConnections] = (0, import_react9.useState)([]);
2032
- const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
2033
- const [error, setError] = (0, import_react9.useState)(null);
2034
- const fetchConnections = (0, import_react9.useCallback)(async () => {
2587
+ const [connections, setConnections] = (0, import_react10.useState)([]);
2588
+ const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
2589
+ const [error, setError] = (0, import_react10.useState)(null);
2590
+ const fetchConnections = (0, import_react10.useCallback)(async () => {
2035
2591
  if (!agentId) return [];
2036
2592
  setIsLoading(true);
2037
2593
  setError(null);
@@ -2055,7 +2611,7 @@ function useMcpConnections(options = {}) {
2055
2611
  setIsLoading(false);
2056
2612
  }
2057
2613
  }, [agentId, fetchWithAuth, options.returnTo]);
2058
- (0, import_react9.useEffect)(() => {
2614
+ (0, import_react10.useEffect)(() => {
2059
2615
  if (autoFetch) void fetchConnections();
2060
2616
  }, [autoFetch, fetchConnections]);
2061
2617
  return {
@@ -2069,11 +2625,11 @@ function useMcpConnections(options = {}) {
2069
2625
  }
2070
2626
 
2071
2627
  // src/hooks/useMcp.ts
2072
- var import_react10 = require("react");
2628
+ var import_react11 = require("react");
2073
2629
  function useMcp(options = {}) {
2074
2630
  const { fetchWithAuth } = usePersonaContext();
2075
2631
  const defaultMcpId = options.mcpId;
2076
- const readResource = (0, import_react10.useCallback)(
2632
+ const readResource = (0, import_react11.useCallback)(
2077
2633
  async (uri, mcpId) => {
2078
2634
  const id = mcpId ?? defaultMcpId;
2079
2635
  if (!id) throw new Error("MCP server ID is required to read resource");
@@ -2087,7 +2643,7 @@ function useMcp(options = {}) {
2087
2643
  },
2088
2644
  [fetchWithAuth, defaultMcpId]
2089
2645
  );
2090
- const callTool = (0, import_react10.useCallback)(
2646
+ const callTool = (0, import_react11.useCallback)(
2091
2647
  async (name, args, mcpId) => {
2092
2648
  const id = mcpId ?? defaultMcpId;
2093
2649
  if (!id) throw new Error("MCP server ID is required to call tool");
@@ -2110,21 +2666,21 @@ function useMcp(options = {}) {
2110
2666
  }
2111
2667
 
2112
2668
  // src/hooks/useWorkflows.ts
2113
- var import_react11 = require("react");
2669
+ var import_react12 = require("react");
2114
2670
  function useWorkflows(options) {
2115
2671
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2116
2672
  const { autoFetch = true, search, status, page, limit } = opts;
2117
2673
  const { fetchWithAuth } = usePersonaContext();
2118
- const [workflows, setWorkflows] = (0, import_react11.useState)([]);
2119
- const [pagination, setPagination] = (0, import_react11.useState)({
2674
+ const [workflows, setWorkflows] = (0, import_react12.useState)([]);
2675
+ const [pagination, setPagination] = (0, import_react12.useState)({
2120
2676
  page: page ?? 1,
2121
2677
  limit: limit ?? 20,
2122
2678
  total: 0,
2123
2679
  totalPages: 0
2124
2680
  });
2125
- const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
2126
- const [error, setError] = (0, import_react11.useState)(null);
2127
- const fetchWorkflows = (0, import_react11.useCallback)(async () => {
2681
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
2682
+ const [error, setError] = (0, import_react12.useState)(null);
2683
+ const fetchWorkflows = (0, import_react12.useCallback)(async () => {
2128
2684
  setIsLoading(true);
2129
2685
  setError(null);
2130
2686
  try {
@@ -2165,7 +2721,7 @@ function useWorkflows(options) {
2165
2721
  setIsLoading(false);
2166
2722
  }
2167
2723
  }, [fetchWithAuth, search, status, page, limit]);
2168
- const createWorkflow = (0, import_react11.useCallback)(
2724
+ const createWorkflow = (0, import_react12.useCallback)(
2169
2725
  async (input) => {
2170
2726
  setError(null);
2171
2727
  try {
@@ -2189,7 +2745,7 @@ function useWorkflows(options) {
2189
2745
  },
2190
2746
  [fetchWithAuth]
2191
2747
  );
2192
- (0, import_react11.useEffect)(() => {
2748
+ (0, import_react12.useEffect)(() => {
2193
2749
  if (autoFetch) {
2194
2750
  void fetchWorkflows();
2195
2751
  }
@@ -2205,17 +2761,17 @@ function useWorkflows(options) {
2205
2761
  }
2206
2762
 
2207
2763
  // src/hooks/useWorkflow.ts
2208
- var import_react12 = require("react");
2764
+ var import_react13 = require("react");
2209
2765
  function useWorkflow(workflowId, options) {
2210
2766
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2211
2767
  const { autoFetch = true } = opts;
2212
2768
  const { fetchWithAuth } = usePersonaContext();
2213
- const [workflow, setWorkflow] = (0, import_react12.useState)(null);
2214
- const [versions, setVersions] = (0, import_react12.useState)([]);
2215
- const [mermaid, setMermaid] = (0, import_react12.useState)(null);
2216
- const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
2217
- const [error, setError] = (0, import_react12.useState)(null);
2218
- const fetchWorkflow = (0, import_react12.useCallback)(async () => {
2769
+ const [workflow, setWorkflow] = (0, import_react13.useState)(null);
2770
+ const [versions, setVersions] = (0, import_react13.useState)([]);
2771
+ const [mermaid, setMermaid] = (0, import_react13.useState)(null);
2772
+ const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
2773
+ const [error, setError] = (0, import_react13.useState)(null);
2774
+ const fetchWorkflow = (0, import_react13.useCallback)(async () => {
2219
2775
  if (!workflowId) return null;
2220
2776
  setIsLoading(true);
2221
2777
  setError(null);
@@ -2235,7 +2791,7 @@ function useWorkflow(workflowId, options) {
2235
2791
  setIsLoading(false);
2236
2792
  }
2237
2793
  }, [fetchWithAuth, workflowId]);
2238
- const fetchVersions = (0, import_react12.useCallback)(async () => {
2794
+ const fetchVersions = (0, import_react13.useCallback)(async () => {
2239
2795
  if (!workflowId) return [];
2240
2796
  try {
2241
2797
  const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);
@@ -2248,7 +2804,7 @@ function useWorkflow(workflowId, options) {
2248
2804
  return [];
2249
2805
  }
2250
2806
  }, [fetchWithAuth, workflowId]);
2251
- const fetchMermaid = (0, import_react12.useCallback)(async () => {
2807
+ const fetchMermaid = (0, import_react13.useCallback)(async () => {
2252
2808
  if (!workflowId) return "";
2253
2809
  try {
2254
2810
  const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);
@@ -2261,7 +2817,7 @@ function useWorkflow(workflowId, options) {
2261
2817
  return "";
2262
2818
  }
2263
2819
  }, [fetchWithAuth, workflowId]);
2264
- const saveDraft = (0, import_react12.useCallback)(
2820
+ const saveDraft = (0, import_react13.useCallback)(
2265
2821
  async (draft) => {
2266
2822
  if (!workflowId) throw new Error("Workflow ID is required");
2267
2823
  setError(null);
@@ -2280,7 +2836,7 @@ function useWorkflow(workflowId, options) {
2280
2836
  },
2281
2837
  [fetchWithAuth, workflowId]
2282
2838
  );
2283
- const publish = (0, import_react12.useCallback)(
2839
+ const publish = (0, import_react13.useCallback)(
2284
2840
  async (summary) => {
2285
2841
  if (!workflowId) throw new Error("Workflow ID is required");
2286
2842
  setError(null);
@@ -2300,7 +2856,7 @@ function useWorkflow(workflowId, options) {
2300
2856
  },
2301
2857
  [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]
2302
2858
  );
2303
- const deleteWorkflow = (0, import_react12.useCallback)(async () => {
2859
+ const deleteWorkflow = (0, import_react13.useCallback)(async () => {
2304
2860
  if (!workflowId) throw new Error("Workflow ID is required");
2305
2861
  setError(null);
2306
2862
  const res = await fetchWithAuth(`/workflows/${workflowId}`, {
@@ -2311,7 +2867,7 @@ function useWorkflow(workflowId, options) {
2311
2867
  }
2312
2868
  setWorkflow(null);
2313
2869
  }, [fetchWithAuth, workflowId]);
2314
- (0, import_react12.useEffect)(() => {
2870
+ (0, import_react13.useEffect)(() => {
2315
2871
  if (autoFetch && workflowId) {
2316
2872
  void fetchWorkflow();
2317
2873
  }
@@ -2332,25 +2888,25 @@ function useWorkflow(workflowId, options) {
2332
2888
  }
2333
2889
 
2334
2890
  // src/hooks/useWorkflowStream.ts
2335
- var import_react13 = require("react");
2891
+ var import_react14 = require("react");
2336
2892
  function useWorkflowStream(workflowId, options) {
2337
2893
  const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();
2338
- const [status, setStatus] = (0, import_react13.useState)("idle");
2339
- const [runId, setRunId] = (0, import_react13.useState)(null);
2340
- const [activeNodeId, setActiveNodeId] = (0, import_react13.useState)(null);
2341
- const [nodeRuns, setNodeRuns] = (0, import_react13.useState)(
2894
+ const [status, setStatus] = (0, import_react14.useState)("idle");
2895
+ const [runId, setRunId] = (0, import_react14.useState)(null);
2896
+ const [activeNodeId, setActiveNodeId] = (0, import_react14.useState)(null);
2897
+ const [nodeRuns, setNodeRuns] = (0, import_react14.useState)(
2342
2898
  {}
2343
2899
  );
2344
- const [text, setText] = (0, import_react13.useState)("");
2345
- const [output, setOutput] = (0, import_react13.useState)(null);
2346
- const [error, setError] = (0, import_react13.useState)(null);
2347
- const [events, setEvents] = (0, import_react13.useState)([]);
2348
- const abortControllerRef = (0, import_react13.useRef)(null);
2349
- const currentRunIdRef = (0, import_react13.useRef)(null);
2900
+ const [text, setText] = (0, import_react14.useState)("");
2901
+ const [output, setOutput] = (0, import_react14.useState)(null);
2902
+ const [error, setError] = (0, import_react14.useState)(null);
2903
+ const [events, setEvents] = (0, import_react14.useState)([]);
2904
+ const abortControllerRef = (0, import_react14.useRef)(null);
2905
+ const currentRunIdRef = (0, import_react14.useRef)(null);
2350
2906
  currentRunIdRef.current = runId;
2351
- const optionsRef = (0, import_react13.useRef)(options);
2907
+ const optionsRef = (0, import_react14.useRef)(options);
2352
2908
  optionsRef.current = options;
2353
- const cancel = (0, import_react13.useCallback)(async () => {
2909
+ const cancel = (0, import_react14.useCallback)(async () => {
2354
2910
  if (abortControllerRef.current) {
2355
2911
  abortControllerRef.current.abort();
2356
2912
  abortControllerRef.current = null;
@@ -2371,7 +2927,7 @@ function useWorkflowStream(workflowId, options) {
2371
2927
  setStatus("cancelled");
2372
2928
  setActiveNodeId(null);
2373
2929
  }, [fetchWithAuth, logger]);
2374
- const reset = (0, import_react13.useCallback)(() => {
2930
+ const reset = (0, import_react14.useCallback)(() => {
2375
2931
  if (abortControllerRef.current) {
2376
2932
  abortControllerRef.current.abort();
2377
2933
  abortControllerRef.current = null;
@@ -2385,7 +2941,7 @@ function useWorkflowStream(workflowId, options) {
2385
2941
  setError(null);
2386
2942
  setEvents([]);
2387
2943
  }, []);
2388
- const processStream = (0, import_react13.useCallback)(
2944
+ const processStream = (0, import_react14.useCallback)(
2389
2945
  async (url, method, body, targetRunId) => {
2390
2946
  if (abortControllerRef.current) {
2391
2947
  abortControllerRef.current.abort();
@@ -2550,7 +3106,7 @@ function useWorkflowStream(workflowId, options) {
2550
3106
  },
2551
3107
  [getAuthToken]
2552
3108
  );
2553
- const start = (0, import_react13.useCallback)(
3109
+ const start = (0, import_react14.useCallback)(
2554
3110
  async (input, opts) => {
2555
3111
  const targetWfId = opts?.workflowId || workflowId;
2556
3112
  if (!targetWfId) {
@@ -2571,7 +3127,7 @@ function useWorkflowStream(workflowId, options) {
2571
3127
  },
2572
3128
  [workflowId, baseUrl, processStream]
2573
3129
  );
2574
- const resume = (0, import_react13.useCallback)(
3130
+ const resume = (0, import_react14.useCallback)(
2575
3131
  async (targetRunId, sinceSeq) => {
2576
3132
  if (!targetRunId) {
2577
3133
  throw new Error("Run ID is required to resume stream");
@@ -2584,7 +3140,7 @@ function useWorkflowStream(workflowId, options) {
2584
3140
  },
2585
3141
  [baseUrl, processStream]
2586
3142
  );
2587
- (0, import_react13.useEffect)(() => {
3143
+ (0, import_react14.useEffect)(() => {
2588
3144
  return () => {
2589
3145
  if (abortControllerRef.current) {
2590
3146
  abortControllerRef.current.abort();
@@ -2609,21 +3165,21 @@ function useWorkflowStream(workflowId, options) {
2609
3165
  }
2610
3166
 
2611
3167
  // src/hooks/useWorkflowRuns.ts
2612
- var import_react14 = require("react");
3168
+ var import_react15 = require("react");
2613
3169
  function useWorkflowRuns(workflowId, options) {
2614
3170
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2615
3171
  const { autoFetch = true, page = 1, limit = 20 } = opts;
2616
3172
  const { fetchWithAuth } = usePersonaContext();
2617
- const [runs, setRuns] = (0, import_react14.useState)([]);
2618
- const [pagination, setPagination] = (0, import_react14.useState)({
3173
+ const [runs, setRuns] = (0, import_react15.useState)([]);
3174
+ const [pagination, setPagination] = (0, import_react15.useState)({
2619
3175
  page,
2620
3176
  limit,
2621
3177
  total: 0,
2622
3178
  totalPages: 0
2623
3179
  });
2624
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
2625
- const [error, setError] = (0, import_react14.useState)(null);
2626
- const fetchRuns = (0, import_react14.useCallback)(async () => {
3180
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
3181
+ const [error, setError] = (0, import_react15.useState)(null);
3182
+ const fetchRuns = (0, import_react15.useCallback)(async () => {
2627
3183
  if (!workflowId) return [];
2628
3184
  setIsLoading(true);
2629
3185
  setError(null);
@@ -2653,7 +3209,7 @@ function useWorkflowRuns(workflowId, options) {
2653
3209
  setIsLoading(false);
2654
3210
  }
2655
3211
  }, [fetchWithAuth, workflowId, page, limit]);
2656
- const getRun = (0, import_react14.useCallback)(
3212
+ const getRun = (0, import_react15.useCallback)(
2657
3213
  async (runId) => {
2658
3214
  if (!runId) throw new Error("Run ID is required");
2659
3215
  const res = await fetchWithAuth(`/workflows/runs/${runId}`);
@@ -2664,7 +3220,7 @@ function useWorkflowRuns(workflowId, options) {
2664
3220
  },
2665
3221
  [fetchWithAuth]
2666
3222
  );
2667
- const cancelRun = (0, import_react14.useCallback)(
3223
+ const cancelRun = (0, import_react15.useCallback)(
2668
3224
  async (runId) => {
2669
3225
  if (!runId) throw new Error("Run ID is required");
2670
3226
  const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {
@@ -2679,7 +3235,7 @@ function useWorkflowRuns(workflowId, options) {
2679
3235
  },
2680
3236
  [fetchWithAuth]
2681
3237
  );
2682
- (0, import_react14.useEffect)(() => {
3238
+ (0, import_react15.useEffect)(() => {
2683
3239
  if (autoFetch && workflowId) {
2684
3240
  void fetchRuns();
2685
3241
  }
@@ -2697,9 +3253,10 @@ function useWorkflowRuns(workflowId, options) {
2697
3253
 
2698
3254
  // src/index.ts
2699
3255
  var import_logger2 = require("@personaai/logger");
2700
- var VERSION = "0.9.0";
3256
+ var VERSION = "0.10.0";
2701
3257
  // Annotate the CommonJS export names for ESM import in node:
2702
3258
  0 && (module.exports = {
3259
+ ARCHITECT_AGENT_ID,
2703
3260
  PersonaProvider,
2704
3261
  VERSION,
2705
3262
  createLogger,
@@ -2710,6 +3267,7 @@ var VERSION = "0.9.0";
2710
3267
  setLogLevel,
2711
3268
  supportsStreamingFetch,
2712
3269
  useAgents,
3270
+ useArchitectChat,
2713
3271
  useChat,
2714
3272
  useConnection,
2715
3273
  useFiles,