@personaai/react 0.8.1 → 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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useVoice.ts","../src/hooks/voiceWorklets.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts","../src/hooks/useMcp.ts","../src/index.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { createContext, useContext, useMemo } from \"react\";\r\nimport type { PersonaProviderProps } from \"../types.js\";\r\nimport { createLogger, type Logger } from \"@personaai/logger\";\r\n\r\ninterface PersonaContextValue {\r\n baseUrl: string;\r\n getAuthToken?: () =>\r\n Promise<string | null | undefined> | string | null | undefined;\r\n defaultAgentId?: string;\r\n fetchWithAuth: (path: string, init?: RequestInit) => Promise<Response>;\r\n logger: Logger;\r\n}\r\n\r\nconst PersonaContext = createContext<PersonaContextValue | null>(null);\r\n\r\nexport function PersonaProvider({\r\n baseUrl,\r\n getAuthToken,\r\n defaultAgentId,\r\n logLevel,\r\n logger: loggerProp,\r\n children,\r\n}: PersonaProviderProps) {\r\n const normalizedBaseUrl = useMemo(\r\n () => baseUrl.replace(/\\/+$/, \"\"),\r\n [baseUrl],\r\n );\r\n\r\n const logger = useMemo<Logger>(() => {\r\n const l =\r\n loggerProp ??\r\n createLogger(\r\n \"react\",\r\n logLevel !== undefined ? { level: logLevel } : undefined,\r\n );\r\n l.debug(\"PersonaProvider created\", {\r\n baseUrl: normalizedBaseUrl,\r\n hasDefaultAgentId: !!defaultAgentId,\r\n });\r\n l.info(\"PersonaProvider mounted\", { baseUrl: normalizedBaseUrl });\r\n l.trace(\"PersonaProvider config\", {\r\n baseUrl: normalizedBaseUrl,\r\n hasGetAuthToken: !!getAuthToken,\r\n });\r\n return l;\r\n }, [loggerProp, logLevel, normalizedBaseUrl, defaultAgentId, getAuthToken]);\r\n\r\n const value = useMemo<PersonaContextValue>(() => {\r\n async function fetchWithAuth(\r\n path: string,\r\n init: RequestInit = {},\r\n ): Promise<Response> {\r\n const token = getAuthToken ? await getAuthToken() : null;\r\n const headers = new Headers(init.headers || {});\r\n if (token) {\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n logger.trace(\"fetchWithAuth with token\", { path });\r\n } else {\r\n logger.trace(\"fetchWithAuth without token\", { path });\r\n logger.debug(\"fetchWithAuth no token\", { path });\r\n }\r\n\r\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n const url = `${normalizedBaseUrl}${cleanPath}`;\r\n logger.debug(\"fetchWithAuth request\", {\r\n path: cleanPath,\r\n url,\r\n hasToken: !!token,\r\n });\r\n logger.trace(\"fetchWithAuth details\", {\r\n url,\r\n path: cleanPath,\r\n hasToken: !!token,\r\n });\r\n\r\n try {\r\n const res = await fetch(url, {\r\n ...init,\r\n headers,\r\n });\r\n logger.debug(\"fetchWithAuth response\", {\r\n path: cleanPath,\r\n status: res.status,\r\n ok: res.ok,\r\n });\r\n if (!res.ok) {\r\n logger.warn(\"fetchWithAuth non-ok\", {\r\n path: cleanPath,\r\n status: res.status,\r\n });\r\n } else {\r\n logger.info(\"fetchWithAuth succeeded\", {\r\n path: cleanPath,\r\n status: res.status,\r\n });\r\n }\r\n return res;\r\n } catch (err) {\r\n logger.error(\"fetchWithAuth failed\", {\r\n path: cleanPath,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n throw err;\r\n }\r\n }\r\n\r\n return {\r\n baseUrl: normalizedBaseUrl,\r\n getAuthToken,\r\n defaultAgentId,\r\n fetchWithAuth,\r\n logger,\r\n };\r\n }, [normalizedBaseUrl, getAuthToken, defaultAgentId, logger]);\r\n\r\n return (\r\n <PersonaContext.Provider value={value}>{children}</PersonaContext.Provider>\r\n );\r\n}\r\n\r\nexport function usePersonaContext(): PersonaContextValue {\r\n const context = useContext(PersonaContext);\r\n if (!context) {\r\n throw new Error(\r\n \"usePersonaContext must be used within a <PersonaProvider>\",\r\n );\r\n }\r\n return context;\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport { openSSEStream } from \"../streaming.js\";\r\nimport type {\r\n PersonaInterrupt,\r\n PersonaMessage,\r\n PersonaPresentedFile,\r\n PersonaResumeValue,\r\n PersonaRole,\r\n PersonaSandboxCommand,\r\n PersonaStreamingEvent,\r\n PersonaSubagentActivityEntry,\r\n PersonaTodo,\r\n PersonaToolCall,\r\n PersonaWorkspaceFile,\r\n SendMessageOverride,\r\n UseChatOptions,\r\n} from \"../types.js\";\r\n\r\n// A failed tool call's TOOL_CALL_RESULT content is a JSON envelope\r\n// (`{status:'error',message}`, see aguiTranslator.js's buildToolErrorContent)\r\n// rather than a separate boolean field on the event itself.\r\nfunction isErrorToolContent(content: string): boolean {\r\n if (typeof content !== \"string\" || !content.trim().startsWith(\"{\"))\r\n return false;\r\n try {\r\n return JSON.parse(content)?.status === \"error\";\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n// Persisted subagent trace item shape (agent-backend's foldSubagentEvent/\r\n// subagentTrace.js) — already folded/paired server-side for compact storage,\r\n// DIFFERENT from the raw per-event `PersonaSubagentActivityEntry` shape the\r\n// live SSE stream sends (kind: 'text'|'tool_start'|'tool_result'). Reloading\r\n// a thread previously never read `data.subagentTraces` at all — a completed\r\n// subagent's activity (its own text/tool timeline) was silently dropped on\r\n// reload even though the backend already persists and returns it, keyed by\r\n// the owning `task` tool call's toolCallId (see agui.controller.js's\r\n// `subagentTraces[callId]`, matching `PersonaToolCall.toolCallId` exactly).\r\ntype PersistedSubagentTraceItem =\r\n | { type: \"text\"; text: string }\r\n | {\r\n type: \"tool\";\r\n name: string;\r\n argsText: string;\r\n resultText: string;\r\n status: \"running\" | \"completed\";\r\n };\r\n\r\n// Re-expands the folded/paired persisted shape back into the raw kind-based\r\n// entries `PersonaSubagentActivityEntry` (and everything downstream that\r\n// consumes it — buildSubagentTimeline, the live-preview row, the activity\r\n// dialog) already knows how to render, so no sdk/ui changes are needed.\r\nfunction persistedTraceToActivityEntries(\r\n items: PersistedSubagentTraceItem[],\r\n): PersonaSubagentActivityEntry[] {\r\n const entries: PersonaSubagentActivityEntry[] = [];\r\n for (const item of items) {\r\n if (item.type === \"text\") {\r\n if (item.text) entries.push({ kind: \"text\", delta: item.text });\r\n } else {\r\n entries.push({\r\n kind: \"tool_start\",\r\n toolName: item.name,\r\n args: item.argsText,\r\n });\r\n if (item.status === \"completed\") {\r\n entries.push({\r\n kind: \"tool_result\",\r\n toolName: item.name,\r\n result: item.resultText,\r\n });\r\n }\r\n }\r\n }\r\n return entries;\r\n}\r\n\r\n// present_file's result is `{status:'success', filePath, title, description}`\r\n// (see present.tool.js) — a signal to highlight that path in the workspace\r\n// files panel, not something meant to render as a generic tool-result blob.\r\nfunction parsePresentedFile(content: string): PersonaPresentedFile | null {\r\n try {\r\n const parsed = JSON.parse(content);\r\n if (parsed?.status !== \"success\" || typeof parsed.filePath !== \"string\")\r\n return null;\r\n return {\r\n path: parsed.filePath,\r\n title: typeof parsed.title === \"string\" ? parsed.title : parsed.filePath,\r\n description:\r\n typeof parsed.description === \"string\" ? parsed.description : \"\",\r\n };\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n// execute's args are `{ command }` and result `{ output, exitCode }` (see\r\n// CodeSandboxBackend.execute, agent-backend/src/modules/sandbox) — both\r\n// arrive here as opaque JSON strings, so this stays defensive rather than\r\n// assuming either parses cleanly (args in particular is still-accumulating\r\n// JSON while the call streams in).\r\nfunction parseSandboxCommand(tc: PersonaToolCall): PersonaSandboxCommand {\r\n let command = tc.args ?? \"\";\r\n try {\r\n const parsedArgs = JSON.parse(tc.args || \"{}\");\r\n if (typeof parsedArgs.command === \"string\") command = parsedArgs.command;\r\n } catch {\r\n // incomplete/still-streaming args — show the raw partial string\r\n }\r\n\r\n let output: string | undefined;\r\n let exitCode: number | null | undefined;\r\n if (tc.result) {\r\n try {\r\n const parsedResult = JSON.parse(tc.result);\r\n if (typeof parsedResult.output === \"string\") {\r\n output = parsedResult.output;\r\n exitCode =\r\n typeof parsedResult.exitCode === \"number\"\r\n ? parsedResult.exitCode\r\n : null;\r\n } else {\r\n output = tc.result;\r\n }\r\n } catch {\r\n output = tc.result;\r\n }\r\n }\r\n\r\n return {\r\n toolCallId: tc.toolCallId,\r\n command,\r\n output,\r\n exitCode,\r\n status: tc.isError ? \"error\" : tc.result ? \"done\" : \"running\",\r\n seq: tc.seq,\r\n };\r\n}\r\n\r\n// buildFilesTodosSnapshot (aguiTranslator.js) emits snake_case\r\n// created_at/modified_at on the wire — both from the live STATE_SNAPSHOT\r\n// event and from a reloaded thread's persisted state (checkpoint.service.js\r\n// runs the same function). Normalize to the SDK's usual camelCase shape.\r\nfunction normalizeWorkspaceFiles(\r\n raw: Record<\r\n string,\r\n {\r\n content: string;\r\n size: number;\r\n created_at: string | null;\r\n modified_at: string | null;\r\n }\r\n >,\r\n): Record<string, PersonaWorkspaceFile> {\r\n const normalized: Record<string, PersonaWorkspaceFile> = {};\r\n for (const [path, file] of Object.entries(raw || {})) {\r\n normalized[path] = {\r\n content: file.content,\r\n size: file.size,\r\n createdAt: file.created_at,\r\n modifiedAt: file.modified_at,\r\n };\r\n }\r\n return normalized;\r\n}\r\n\r\n// checkpointService.getMessages() wraps a paused thread's interrupt as\r\n// `{ kind, value }` (see checkpoint.service.js) — the same envelope shape\r\n// the live hitl_request/clarification_request CUSTOM events carry, just\r\n// nested one level deeper. Flatten both into the same PersonaInterrupt shape.\r\nfunction normalizePendingInterrupt(pending: unknown): PersonaInterrupt | null {\r\n if (!pending || typeof pending !== \"object\") return null;\r\n const p = pending as { kind?: string; value?: Record<string, unknown> };\r\n if (p.kind === \"hitl\") {\r\n return {\r\n kind: \"hitl\",\r\n actionRequests: (p.value?.actionRequests ?? []) as Extract<\r\n PersonaInterrupt,\r\n { kind: \"hitl\" }\r\n >[\"actionRequests\"],\r\n reviewConfigs: (p.value?.reviewConfigs ?? []) as unknown[],\r\n };\r\n }\r\n if (p.kind === \"clarification\") {\r\n return {\r\n kind: \"clarification\",\r\n questions: (p.value?.questions ?? []) as Extract<\r\n PersonaInterrupt,\r\n { kind: \"clarification\" }\r\n >[\"questions\"],\r\n };\r\n }\r\n return null;\r\n}\r\n\r\nexport function useChat(options: UseChatOptions = {}) {\r\n const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken, logger } =\r\n usePersonaContext();\r\n const chatLogger = useMemo(() => logger.child(\"chat\"), [logger]);\r\n const agentId = options.agentId || defaultAgentId;\r\n const threadId = options.threadId;\r\n // Ephemeral/fake thread support: when threadId is null/undefined the chat is\r\n // in \"new chat\" mode — no history fetch, no thread creation until first send.\r\n // The real id is minted lazily inside doSend and surfaced via\r\n // options.onThreadCreated so the host can sync its sidebar state.\r\n const [internalThreadId, setInternalThreadId] = useState<string | undefined>(undefined);\r\n const effectiveThreadId = threadId ?? internalThreadId;\r\n // Keep internal in sync when host drives threadId (e.g. after mint)\r\n useEffect(() => {\r\n if (threadId !== undefined) setInternalThreadId(threadId);\r\n }, [threadId]);\r\n\r\n // Log hook initialization at most once per mount (debug/info visible, trace for details)\r\n // This runs during render, so guard with a ref to avoid spam on every re-render\r\n const didLogInitRef = useRef(false);\r\n if (!didLogInitRef.current) {\r\n didLogInitRef.current = true;\r\n chatLogger.debug(\"useChat init\", {\r\n agentId,\r\n threadId,\r\n hasInitialMessages: !!options.initialMessages?.length,\r\n });\r\n chatLogger.trace(\"useChat options\", {\r\n agentId,\r\n threadId,\r\n initialMessageCount: options.initialMessages?.length ?? 0,\r\n });\r\n }\r\n\r\n const [messages, setMessages] = useState<PersonaMessage[]>(\r\n options.initialMessages || [],\r\n );\r\n const [input, setInput] = useState(\"\");\r\n const [isStreaming, setIsStreaming] = useState(false);\r\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [interrupt, setInterrupt] = useState<PersonaInterrupt | null>(null);\r\n const [files, setFiles] = useState<Record<string, PersonaWorkspaceFile>>({});\r\n const [todos, setTodos] = useState<PersonaTodo[]>([]);\r\n const [presentedFile, setPresentedFile] =\r\n useState<PersonaPresentedFile | null>(null);\r\n\r\n // Derived (not separately tracked) from `messages` — every `execute` tool\r\n // call already lives there, both live-streamed and loaded from history, so\r\n // this stays correct for free instead of needing its own reset/restore\r\n // logic the way `presentedFile` (a single most-recent value, not a list)\r\n // does.\r\n const sandboxCommands = useMemo<PersonaSandboxCommand[]>(() => {\r\n const commands: PersonaSandboxCommand[] = [];\r\n for (const message of messages) {\r\n for (const tc of message.toolCalls ?? []) {\r\n if (tc.toolName === \"execute\") commands.push(parseSandboxCommand(tc));\r\n }\r\n }\r\n return commands;\r\n }, [messages]);\r\n\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\r\n\r\n // Voice sync bookkeeping — see the effect below. Kept as refs (not state)\r\n // because they're pure injection-cursor plumbing, never rendered.\r\n const voiceThreadRef = useRef<string | undefined>(effectiveThreadId);\r\n const voicePrevLenRef = useRef(0);\r\n const voiceStreamingIdRef = useRef<string | null>(null);\r\n const voiceUserPartialIdRef = useRef<string | null>(null);\r\n\r\n const stop = useCallback(() => {\r\n if (abortControllerRef.current) {\r\n chatLogger.info(\"stop streaming\", {});\r\n chatLogger.debug(\"abort controller\", {\r\n hasController: !!abortControllerRef.current,\r\n });\r\n abortControllerRef.current.abort();\r\n abortControllerRef.current = null;\r\n setIsStreaming(false);\r\n chatLogger.debug(\"streaming stopped\");\r\n } else {\r\n chatLogger.trace(\"stop called — no active stream\");\r\n }\r\n }, [chatLogger]);\r\n\r\n const clear = useCallback(() => {\r\n chatLogger.info(\"clear chat\", { messageCount: messages.length });\r\n chatLogger.debug(\"clear\", { messageCount: messages.length });\r\n stop();\r\n setMessages([]);\r\n setError(null);\r\n setInterrupt(null);\r\n setFiles({});\r\n setTodos([]);\r\n setPresentedFile(null);\r\n loadedThreadIdRef.current = undefined;\r\n }, [stop, chatLogger, messages.length]);\r\n\r\n const startNewChat = useCallback(() => {\r\n chatLogger.info(\"startNewChat — entering ephemeral mode\");\r\n stop();\r\n setMessages([]);\r\n setError(null);\r\n setInterrupt(null);\r\n setFiles({});\r\n setTodos([]);\r\n setPresentedFile(null);\r\n setInput(\"\");\r\n loadedThreadIdRef.current = undefined;\r\n voiceThreadRef.current = undefined;\r\n voicePrevLenRef.current = 0;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n setInternalThreadId(undefined);\r\n }, [stop, chatLogger]);\r\n\r\n const loadThreadMessages = useCallback(\r\n async (id: string) => {\r\n chatLogger.debug(\"loadThreadMessages start\", { threadId: id });\r\n chatLogger.trace(\"loadThreadMessages\", { threadId: id });\r\n setIsLoadingHistory(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(`/threads/${id}/messages`);\r\n if (!res.ok)\r\n throw new Error(`Failed to load thread history: ${res.statusText}`);\r\n const body = await res.json();\r\n const data = body?.data ?? body;\r\n const raw = (data?.messages ?? []) as Array<{\r\n id?: string;\r\n role: PersonaMessage[\"role\"];\r\n content: string;\r\n toolCalls?: PersonaToolCall[];\r\n }>;\r\n const subagentTraces = (data?.subagentTraces ?? {}) as Record<\r\n string,\r\n PersistedSubagentTraceItem[]\r\n >;\r\n const loaded: PersonaMessage[] = raw.map((m, i) => ({\r\n id: m.id || `history-${id}-${i}`,\r\n role: m.role,\r\n content: m.content,\r\n createdAt: new Date(),\r\n toolCalls: m.toolCalls?.map((tc) => {\r\n const trace = subagentTraces[tc.toolCallId];\r\n return Array.isArray(trace) && trace.length > 0\r\n ? {\r\n ...tc,\r\n subagentActivity: persistedTraceToActivityEntries(trace),\r\n }\r\n : tc;\r\n }),\r\n }));\r\n setMessages(loaded);\r\n // Re-show the approval/clarification card on reload if this thread\r\n // is currently paused — otherwise it wouldn't reappear until the\r\n // next live stream re-surfaces it.\r\n setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));\r\n // Restore the workspace files/todos this thread already had (same\r\n // cleaned shape checkpoint.service.js now derives via\r\n // buildFilesTodosSnapshot, matching the live STATE_SNAPSHOT event).\r\n setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));\r\n setTodos((data?.state?.todos ?? []) as PersonaTodo[]);\r\n loadedThreadIdRef.current = id;\r\n chatLogger.info(\"loadThreadMessages succeeded\", {\r\n threadId: id,\r\n messageCount: loaded.length,\r\n });\r\n chatLogger.debug(\"loadThreadMessages completed\", {\r\n threadId: id,\r\n messageCount: loaded.length,\r\n });\r\n return loaded;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n chatLogger.warn(\"loadThreadMessages failed\", {\r\n threadId: id,\r\n error: errorObj.message,\r\n });\r\n chatLogger.error(\"loadThreadMessages error\", {\r\n threadId: id,\r\n error: errorObj.message,\r\n });\r\n setError(errorObj);\r\n if (loadedThreadIdRef.current === id) loadedThreadIdRef.current = undefined;\r\n return [];\r\n } finally {\r\n setIsLoadingHistory(false);\r\n chatLogger.trace(\"loadThreadMessages end\", { threadId: id });\r\n }\r\n },\r\n [fetchWithAuth, chatLogger],\r\n );\r\n\r\n // Auto-load history the first time a thread with no in-memory messages is\r\n // selected (switching threads in the sidebar). Skipped for a thread whose\r\n // messages already live in state — e.g. one just created by handleSend,\r\n // which sets its placeholder messages in the same render batch as the\r\n // threadId change, so `messages` there is never empty at effect time.\r\n useEffect(() => {\r\n if (!effectiveThreadId || isStreaming) {\r\n chatLogger.trace(\"auto-load skipped\", { threadId: effectiveThreadId, isStreaming });\r\n return;\r\n }\r\n if (loadedThreadIdRef.current === effectiveThreadId) {\r\n chatLogger.trace(\"auto-load already loaded\", { threadId: effectiveThreadId });\r\n return;\r\n }\r\n if (messages.length > 0) {\r\n chatLogger.trace(\"auto-load has messages\", {\r\n threadId: effectiveThreadId,\r\n count: messages.length,\r\n });\r\n return;\r\n }\r\n chatLogger.info(\"auto-load thread history\", { threadId: effectiveThreadId });\r\n chatLogger.debug(\"loadThreadMessages trigger\", { threadId: effectiveThreadId });\r\n void loadThreadMessages(effectiveThreadId);\r\n }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);\r\n\r\n // Merge a `useVoice()` session's live transcript into `messages` — see\r\n // `UseChatOptions.voice`. This replaces the hand-rolled sync effects the\r\n // README used to tell every consumer to write themselves (dedup against\r\n // thread history, merge same-speaker fragments into one bubble, update the\r\n // in-progress agent line in place, and not replay a call's old transcript\r\n // after a threadId switch under the same `useVoice()` instance).\r\n const voice = options.voice;\r\n useEffect(() => {\r\n if (!voice) return;\r\n\r\n // The passed useVoice() instance now targets a different thread (e.g. the\r\n // host app switched conversations without remounting either hook) — its\r\n // transcript belongs to a call that's over as far as this feed is\r\n // concerned. Stop injecting and don't let anything already spoken bleed\r\n // into the new thread's feed once a new call starts.\r\n if (voiceThreadRef.current !== effectiveThreadId) {\r\n voiceThreadRef.current = effectiveThreadId;\r\n voicePrevLenRef.current = voice.transcript.length;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n return;\r\n }\r\n\r\n const isVoiceActive =\r\n voice.state !== \"idle\" && voice.state !== \"ended\" && voice.state !== \"error\";\r\n const curLen = voice.transcript.length;\r\n\r\n // start() resets transcript to [] for a fresh call — realign the cursor.\r\n if (curLen < voicePrevLenRef.current) {\r\n voicePrevLenRef.current = 0;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n }\r\n\r\n if (!isVoiceActive) {\r\n // Flush any unseen transcript lines that arrived just before stop()\r\n // set state to idle (A1). Previously this block only advanced the\r\n // pointer, permanently discarding the final user utterance.\r\n if (curLen > voicePrevLenRef.current) {\r\n const pendingLines = voice.transcript.slice(voicePrevLenRef.current);\r\n voicePrevLenRef.current = curLen;\r\n for (const line of pendingLines) {\r\n const text = (line.text || \"\").trim();\r\n if (!text) continue;\r\n const role: PersonaRole = line.speaker === \"user\" ? \"user\" : \"assistant\";\r\n const voiceId = `voice-${line.id}`;\r\n setMessages((prev) => {\r\n if (prev.some((m) => m.id === voiceId)) return prev;\r\n if (prev.some((m) => !m.id.startsWith(\"voice-\") && m.role === role && m.content.trim() === text)) return prev;\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\" && role === \"assistant\") {\r\n const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();\r\n return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];\r\n }\r\n return [...prev, { id: voiceId, role, content: text, createdAt: new Date() }];\r\n });\r\n }\r\n } else {\r\n voicePrevLenRef.current = voice.transcript.length;\r\n }\r\n if (voiceStreamingIdRef.current) {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n return;\r\n }\r\n\r\n if (curLen > voicePrevLenRef.current) {\r\n const newLines = voice.transcript.slice(voicePrevLenRef.current);\r\n voicePrevLenRef.current = curLen;\r\n for (const line of newLines) {\r\n const text = (line.text || \"\").trim();\r\n if (!text) continue;\r\n const role: PersonaRole = line.speaker === \"user\" ? \"user\" : \"assistant\";\r\n const voiceId = `voice-${line.id}`;\r\n setMessages((prev) => {\r\n // Already injected this exact line.\r\n if (prev.some((m) => m.id === voiceId)) return prev;\r\n // Already on the thread as a persisted turn (voice shares the\r\n // thread, so a refresh/reload can already hold it).\r\n if (\r\n prev.some(\r\n (m) =>\r\n !m.id.startsWith(\"voice-\") &&\r\n m.role === role &&\r\n m.content.trim() === text,\r\n )\r\n )\r\n return prev;\r\n const last = prev[prev.length - 1];\r\n // Consecutive agent finals of one spoken answer merge into the\r\n // bubble they opened, same as useVoice() does for `transcript`\r\n // itself — mirrors how the thread coalesces them on reload.\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\" && role === \"assistant\") {\r\n const merged = text.startsWith(last.content)\r\n ? text\r\n : `${last.content} ${text}`.trim();\r\n return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];\r\n }\r\n return [...prev, { id: voiceId, role, content: text, createdAt: new Date() }];\r\n });\r\n }\r\n }\r\n\r\n const agentPartialText = voice.partial?.speaker === \"agent\" ? voice.partial.text.trim() : \"\";\r\n const userPartialText = voice.partial?.speaker === \"user\" ? voice.partial.text.trim() : \"\";\r\n\r\n if (agentPartialText) {\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n setMessages((prev) => {\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\") {\r\n voiceStreamingIdRef.current = last.id;\r\n return [...prev.slice(0, -1), { ...last, content: agentPartialText, isStreaming: true }];\r\n }\r\n const id = voiceStreamingIdRef.current || `voice-partial-${Date.now()}`;\r\n voiceStreamingIdRef.current = id;\r\n return [...prev, { id, role: \"assistant\", content: agentPartialText, isStreaming: true, createdAt: new Date() }];\r\n });\r\n } else if (userPartialText) {\r\n if (voiceStreamingIdRef.current) {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n setMessages((prev) => {\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"user\" && last.isStreaming) {\r\n voiceUserPartialIdRef.current = last.id;\r\n return [...prev.slice(0, -1), { ...last, content: userPartialText, isStreaming: true }];\r\n }\r\n const id = voiceUserPartialIdRef.current || `voice-partial-user-${Date.now()}`;\r\n voiceUserPartialIdRef.current = id;\r\n return [...prev, { id, role: \"user\", content: userPartialText, isStreaming: true, createdAt: new Date() }];\r\n });\r\n } else {\r\n if (voiceStreamingIdRef.current && voice.state !== \"speaking\") {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n }\r\n // `voice` itself isn't a dep — useVoice() returns a fresh object every\r\n // render, so keying off it would re-run this every render regardless of\r\n // whether the transcript actually changed.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [voice?.transcript, voice?.partial, voice?.state, effectiveThreadId]);\r\n\r\n // Internal stream executor — shared by sendMessage and reload so reload can\r\n // supply a truncated base (B1: reload must not build nextMessages from the\r\n // stale full closure). Caller has already validated prompt/isStreaming.\r\n const doSend = useCallback(\r\n async (prompt: string, baseMessages: PersonaMessage[], overrideOptions?: SendMessageOverride): Promise<boolean> => {\r\n const targetAgentId = overrideOptions?.agentId || agentId;\r\n if (!targetAgentId) {\r\n const err = new Error(\"No Agent ID specified for useChat.\");\r\n chatLogger.warn(\"sendMessage no agentId\", {});\r\n chatLogger.error(\"sendMessage failed — no agent\", { error: err.message });\r\n setError(err);\r\n options.onError?.(err);\r\n return false;\r\n }\r\n\r\n chatLogger.debug(\"sendMessage start\", {\r\n promptPreview: prompt.slice(0, 100),\r\n agentId: targetAgentId,\r\n threadId: effectiveThreadId ?? (overrideOptions?.threadId as string | undefined),\r\n hasResume: !!overrideOptions?.resume,\r\n hasContextOverride: !!overrideOptions?.contextOverride,\r\n messageCount: baseMessages.length,\r\n });\r\n chatLogger.trace(\"sendMessage details\", {\r\n agentId: targetAgentId,\r\n promptPreview: prompt.slice(0, 200),\r\n hasResume: !!overrideOptions?.resume,\r\n hasContextOverride: !!overrideOptions?.contextOverride,\r\n });\r\n\r\n const userMessage: PersonaMessage = {\r\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\r\n role: \"user\",\r\n content: prompt,\r\n createdAt: new Date(),\r\n };\r\n\r\n const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\r\n const placeholderAssistant: PersonaMessage = {\r\n id: assistantMessageId,\r\n role: \"assistant\",\r\n content: \"\",\r\n createdAt: new Date(),\r\n isStreaming: true,\r\n toolCalls: [],\r\n };\r\n\r\n const nextMessages = [...baseMessages, userMessage];\r\n setMessages([...nextMessages, placeholderAssistant]);\r\n setInput(\"\");\r\n setIsStreaming(true);\r\n setError(null);\r\n setInterrupt(null);\r\n\r\n const controller = new AbortController();\r\n abortControllerRef.current = controller;\r\n\r\n const finalizeReasoning = () => {\r\n setMessages((prev) =>\r\n prev.map((m) => (m.role === \"reasoning\" && m.isStreaming ? { ...m, isStreaming: false } : m)),\r\n );\r\n };\r\n\r\n try {\r\n const payloadMessages = nextMessages\r\n .filter((m) => m.role !== \"reasoning\")\r\n .map((m) => ({\r\n role: m.role === \"assistant\" ? (\"assistant\" as const) : (\"user\" as const),\r\n content: m.content,\r\n }));\r\n\r\n let resolvedThreadId: string | undefined = (await (overrideOptions?.threadId as string | undefined)) ?? effectiveThreadId;\r\n if (!resolvedThreadId) {\r\n chatLogger.info(\"minting real thread for ephemeral chat\", { agentId: targetAgentId });\r\n const createRes = await fetchWithAuth(\"/threads\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ agentId: targetAgentId }),\r\n });\r\n if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);\r\n const createBody = await createRes.json();\r\n const created = (createBody?.data ?? createBody) as { _id?: string; id?: string };\r\n resolvedThreadId = created._id ?? created.id;\r\n if (!resolvedThreadId) throw new Error(\"Thread creation returned no id\");\r\n setInternalThreadId(resolvedThreadId);\r\n loadedThreadIdRef.current = resolvedThreadId;\r\n options.onThreadCreated?.(resolvedThreadId);\r\n chatLogger.info(\"ephemeral chat minted\", { threadId: resolvedThreadId });\r\n }\r\n chatLogger.trace(\"resolved threadId\", { threadId: resolvedThreadId });\r\n\r\n const token = getAuthToken ? await getAuthToken() : null;\r\n const resolvedHookContext = typeof options.context === \"function\" ? options.context() : options.context;\r\n const mergedContext = { ...resolvedHookContext, ...overrideOptions?.context };\r\n const hasContext = Object.keys(mergedContext).length > 0;\r\n chatLogger.debug(\"opening SSE stream\", {\r\n agentId: targetAgentId,\r\n hasToken: !!token,\r\n hasThreadId: !!resolvedThreadId,\r\n hasContext,\r\n });\r\n const stream = await openSSEStream({\r\n url: `${baseUrl}/chat`,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\r\n },\r\n body: JSON.stringify({\r\n agentId: targetAgentId,\r\n messages: payloadMessages,\r\n threadId: resolvedThreadId,\r\n resume: overrideOptions?.resume,\r\n contextOverride: overrideOptions?.contextOverride,\r\n ...(hasContext ? { context: mergedContext } : {}),\r\n }),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!stream.ok) {\r\n chatLogger.warn(\"SSE stream not ok\", { status: stream.status, errorText: stream.errorText });\r\n chatLogger.error(\"chat stream failed\", { agentId: targetAgentId, status: stream.status, error: stream.errorText });\r\n throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? \"Stream failed\"}`);\r\n }\r\n chatLogger.debug(\"SSE stream opened\", { agentId: targetAgentId, status: stream.status });\r\n chatLogger.info(\"chat stream started\", { agentId: targetAgentId, threadId: resolvedThreadId });\r\n\r\n const reader = stream.reader;\r\n let buffer = \"\";\r\n let accumulatedText = \"\";\r\n const toolCallsMap = new Map<string, PersonaToolCall>();\r\n let streamSeq = 0;\r\n let activeReasoningId: string | null = null;\r\n const reasoningById = new Map<string, { content: string }>();\r\n\r\n const patchAssistant = (patch: Partial<PersonaMessage>) => {\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch } : msg,\r\n ),\r\n );\r\n };\r\n\r\n const insertReasoningMessage = (id: string, seq: number) => {\r\n const msg: PersonaMessage = { id, role: \"reasoning\", content: \"\", createdAt: new Date(), isStreaming: true, seq };\r\n setMessages((prev) => {\r\n const idx = prev.findIndex((m) => m.id === assistantMessageId);\r\n if (idx === -1) return [...prev, msg];\r\n const next = [...prev];\r\n next.splice(idx, 0, msg);\r\n return next;\r\n });\r\n };\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n buffer += value ?? \"\";\r\n const lines = buffer.split(\"\\n\");\r\n buffer = lines.pop() ?? \"\";\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || !trimmed.startsWith(\"data:\")) continue;\r\n const raw = trimmed.replace(/^data:\\s*/, \"\");\r\n if (raw === \"[DONE]\") break;\r\n try {\r\n const event = JSON.parse(raw) as PersonaStreamingEvent;\r\n chatLogger.trace(\"stream event\", { type: event.type, event });\r\n options.onEvent?.(event);\r\n if (event.type === \"TEXT_MESSAGE_CHUNK\" && event.delta) {\r\n chatLogger.debug(\"text chunk\", { deltaLength: event.delta.length });\r\n accumulatedText += event.delta;\r\n patchAssistant({ content: accumulatedText, isStreaming: true });\r\n } else if (event.type === \"TOOL_CALL_CHUNK\" && event.toolCallId) {\r\n chatLogger.debug(\"tool call chunk\", { toolCallId: event.toolCallId, toolCallName: event.toolCallName });\r\n const existing = toolCallsMap.get(event.toolCallId);\r\n if (existing) {\r\n existing.args = (existing.args || \"\") + (event.delta || \"\");\r\n } else {\r\n toolCallsMap.set(event.toolCallId, {\r\n toolCallId: event.toolCallId,\r\n toolName: event.toolCallName || \"\",\r\n args: event.delta || \"\",\r\n seq: streamSeq++,\r\n });\r\n }\r\n patchAssistant({});\r\n } else if (event.type === \"TOOL_CALL_RESULT\") {\r\n chatLogger.debug(\"tool call result\", { toolCallId: event.toolCallId });\r\n const existing = toolCallsMap.get(event.toolCallId);\r\n if (existing) {\r\n existing.result = event.content;\r\n existing.isError = isErrorToolContent(event.content);\r\n if (existing.isError) chatLogger.warn(\"tool call error\", { toolCallId: event.toolCallId });\r\n if (existing.toolName === \"present_file\" && !existing.isError) {\r\n const presented = parsePresentedFile(event.content);\r\n if (presented) {\r\n chatLogger.info(\"present_file\", { path: presented.path });\r\n setPresentedFile(presented);\r\n }\r\n }\r\n patchAssistant({});\r\n }\r\n } else if (event.type === \"STATE_SNAPSHOT\") {\r\n chatLogger.debug(\"state snapshot\", {\r\n fileCount: Object.keys(event.snapshot.files ?? {}).length,\r\n todoCount: event.snapshot.todos?.length ?? 0,\r\n });\r\n setFiles(normalizeWorkspaceFiles(event.snapshot.files ?? {}));\r\n setTodos(event.snapshot.todos ?? []);\r\n } else if (event.type === \"REASONING_MESSAGE_START\" && event.messageId) {\r\n chatLogger.debug(\"reasoning start\", { messageId: event.messageId });\r\n activeReasoningId = event.messageId;\r\n reasoningById.set(event.messageId, { content: \"\" });\r\n insertReasoningMessage(event.messageId, streamSeq++);\r\n } else if (event.type === \"REASONING_MESSAGE_CONTENT\") {\r\n let rid: string = event.messageId || activeReasoningId || \"\";\r\n if (!rid || !reasoningById.has(rid)) {\r\n rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\r\n activeReasoningId = rid;\r\n reasoningById.set(rid, { content: \"\" });\r\n insertReasoningMessage(rid, streamSeq++);\r\n chatLogger.debug(\"reasoning lazy start\", { messageId: rid });\r\n }\r\n const entry = reasoningById.get(rid)!;\r\n entry.content += event.delta;\r\n chatLogger.trace(\"reasoning content\", { messageId: rid, deltaLength: event.delta?.length ?? 0 });\r\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m)));\r\n } else if (event.type === \"REASONING_END\") {\r\n chatLogger.debug(\"reasoning end\", { messageId: activeReasoningId });\r\n const rid = activeReasoningId;\r\n activeReasoningId = null;\r\n if (rid) {\r\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m)));\r\n }\r\n } else if (event.type === \"CUSTOM\") {\r\n chatLogger.debug(\"custom event\", { name: event.name });\r\n if (event.name === \"hitl_request\") {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: \"hitl\" }>;\r\n chatLogger.info(\"hitl interrupt\", { actionCount: value.actionRequests?.length ?? 0 });\r\n setInterrupt({ kind: \"hitl\", actionRequests: value.actionRequests, reviewConfigs: value.reviewConfigs });\r\n } else if (event.name === \"clarification_request\") {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: \"clarification\" }>;\r\n chatLogger.info(\"clarification interrupt\", { questionCount: value.questions?.length ?? 0 });\r\n setInterrupt({ kind: \"clarification\", questions: value.questions });\r\n } else if (event.name === \"subagent_activity\") {\r\n const { toolCallId, ...entry } = event.value as { toolCallId: string } & PersonaSubagentActivityEntry;\r\n chatLogger.trace(\"subagent activity\", { toolCallId, kind: entry.kind });\r\n const existing = toolCallsMap.get(toolCallId);\r\n if (existing) {\r\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\r\n patchAssistant({});\r\n }\r\n } else if (event.name === \"mcp_app\") {\r\n const val = event.value as { toolCallId?: string; resourceUri?: string; mcpId?: string } | undefined;\r\n if (val?.toolCallId && val?.resourceUri && val?.mcpId) {\r\n const existing = toolCallsMap.get(val.toolCallId);\r\n if (existing) {\r\n existing.mcpApp = { resourceUri: val.resourceUri, mcpId: val.mcpId };\r\n patchAssistant({});\r\n }\r\n }\r\n }\r\n } else if ((event as { type: string; title?: string }).type === \"title\") {\r\n const title = (event as { title?: string }).title;\r\n if (typeof title === \"string\" && title.trim()) {\r\n chatLogger.info(\"auto title\", { title });\r\n (options as { onTitle?: (t: string) => void }).onTitle?.(title);\r\n }\r\n } else if (event.type === \"RUN_ERROR\") {\r\n chatLogger.warn(\"run error\", { message: event.message, code: event.code });\r\n chatLogger.error(\"stream run error\", { code: event.code, message: event.message });\r\n throw new Error(event.message || \"Stream error from agent\");\r\n } else {\r\n chatLogger.trace(\"unhandled event\", { type: event.type });\r\n }\r\n } catch (e) {\r\n if (e instanceof Error && e.message.startsWith(\"Stream error\")) throw e;\r\n chatLogger.warn(\"event parse error\", { raw: raw.slice(0, 200), error: e instanceof Error ? e.message : String(e) });\r\n }\r\n }\r\n }\r\n\r\n const finalMessage: PersonaMessage = {\r\n id: assistantMessageId,\r\n role: \"assistant\",\r\n content: accumulatedText,\r\n createdAt: new Date(),\r\n isStreaming: false,\r\n toolCalls: Array.from(toolCallsMap.values()),\r\n };\r\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg)));\r\n chatLogger.info(\"sendMessage succeeded\", { agentId: targetAgentId, textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });\r\n chatLogger.debug(\"sendMessage completed\", { agentId: targetAgentId, textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });\r\n options.onFinish?.(finalMessage);\r\n return true;\r\n } catch (err) {\r\n if (controller.signal.aborted) {\r\n chatLogger.info(\"sendMessage aborted\", { agentId: targetAgentId });\r\n chatLogger.debug(\"stream aborted\", { agentId: targetAgentId });\r\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg)));\r\n return false;\r\n }\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n chatLogger.warn(\"sendMessage failed\", { agentId: targetAgentId, error: errorObj.message });\r\n chatLogger.error(\"sendMessage error\", { agentId: targetAgentId, error: errorObj.message });\r\n setError(errorObj);\r\n options.onError?.(errorObj);\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId\r\n ? { ...msg, content: msg.content || `⚠️ Error: ${errorObj.message || \"Failed to get response.\"}`, isStreaming: false }\r\n : msg,\r\n ),\r\n );\r\n return false;\r\n } finally {\r\n setIsStreaming(false);\r\n abortControllerRef.current = null;\r\n finalizeReasoning();\r\n chatLogger.debug(\"sendMessage finally\", { agentId: targetAgentId, isStreaming: false });\r\n chatLogger.trace(\"sendMessage end\", { agentId: targetAgentId });\r\n }\r\n },\r\n [agentId, baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId],\r\n );\r\n\r\n const sendMessage = useCallback(\r\n async (contentToSend?: string, overrideOptions?: SendMessageOverride): Promise<boolean> => {\r\n const prompt = (contentToSend ?? input).trim();\r\n if (!prompt || isStreaming) {\r\n chatLogger.trace(\"sendMessage skipped\", {\r\n hasPrompt: !!prompt,\r\n isStreaming,\r\n });\r\n if (isStreaming) {\r\n chatLogger.warn(\"sendMessage dropped while streaming — caller should queue or disable send\", {});\r\n }\r\n return false;\r\n }\r\n return doSend(prompt, messages, overrideOptions);\r\n },\r\n [input, isStreaming, messages, doSend, chatLogger],\r\n );\r\n\r\n const handleInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n chatLogger.trace(\"handleInputChange\", { length: e.target.value.length });\r\n setInput(e.target.value);\r\n },\r\n [chatLogger],\r\n );\r\n\r\n const handleSubmit = useCallback(\r\n (e?: React.FormEvent) => {\r\n if (e) e.preventDefault();\r\n chatLogger.debug(\"handleSubmit\", {});\r\n void sendMessage();\r\n },\r\n [sendMessage, chatLogger],\r\n );\r\n\r\n const reload = useCallback(async (): Promise<boolean> => {\r\n if (messages.length === 0 || isStreaming) {\r\n chatLogger.trace(\"reload skipped\", {\r\n messageCount: messages.length,\r\n isStreaming,\r\n });\r\n return false;\r\n }\r\n let lastUserIndex = -1;\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n if (messages[i].role === \"user\") {\r\n lastUserIndex = i;\r\n break;\r\n }\r\n }\r\n if (lastUserIndex === -1) {\r\n chatLogger.warn(\"reload no user message\", {});\r\n return false;\r\n }\r\n\r\n const lastUserMessage = messages[lastUserIndex];\r\n const truncated = messages.slice(0, lastUserIndex);\r\n chatLogger.info(\"reload\", { messageId: lastUserMessage.id });\r\n chatLogger.debug(\"reload last user\", {\r\n preview: lastUserMessage.content.slice(0, 100),\r\n });\r\n return doSend(lastUserMessage.content, truncated);\r\n }, [isStreaming, messages, doSend, chatLogger]);\r\n\r\n // Unpauses a paused HITL/clarification run. `displayContent` becomes the\r\n // visible user-turn bubble (e.g. \"Approved\", or the typed clarification\r\n // answer) — the server resolves the actual resume value from `resume`\r\n // itself, `displayContent` is only ever used for its own transcript text.\r\n const resumeInterrupt = useCallback(\r\n (resume: PersonaResumeValue, displayContent: string) => {\r\n chatLogger.info(\"resumeInterrupt\", {\r\n kind: (resume as { decisions?: unknown[] }).decisions\r\n ? \"hitl\"\r\n : \"clarification\",\r\n preview: displayContent.slice(0, 50),\r\n });\r\n return sendMessage(displayContent, { resume });\r\n },\r\n [sendMessage, chatLogger],\r\n );\r\n\r\n const dismissPresentedFile = useCallback(() => {\r\n chatLogger.debug(\"dismissPresentedFile\", {});\r\n setPresentedFile(null);\r\n }, [chatLogger]);\r\n\r\n // Manually re-open a workspace file — e.g. a present_file tool card's\r\n // \"Open\" button, after the auto-opened drawer was closed or a different\r\n // file was selected since.\r\n const openWorkspaceFile = useCallback(\r\n (path: string) => {\r\n chatLogger.debug(\"openWorkspaceFile\", { path });\r\n setPresentedFile({\r\n path,\r\n title: path.split(\"/\").pop() || path,\r\n description: \"\",\r\n });\r\n },\r\n [chatLogger],\r\n );\r\n\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n handleInputChange,\r\n handleSubmit,\r\n sendMessage,\r\n isStreaming,\r\n isLoading: isStreaming,\r\n isLoadingHistory,\r\n error,\r\n interrupt,\r\n resumeInterrupt,\r\n files,\r\n todos,\r\n presentedFile,\r\n dismissPresentedFile,\r\n openWorkspaceFile,\r\n sandboxCommands,\r\n stop,\r\n reload,\r\n clear,\r\n startNewChat,\r\n currentThreadId: effectiveThreadId,\r\n isEphemeral: !effectiveThreadId,\r\n setMessages,\r\n loadThreadMessages,\r\n };\r\n}\r\n","/**\r\n * SSE transport for chat streams, with a React Native fallback.\r\n *\r\n * On the web, `fetch` gives a streaming `response.body` and we read it with a\r\n * ReadableStream reader. React Native's `fetch` is the whatwg-fetch polyfill\r\n * over XMLHttpRequest: `response.body` is `undefined`, and the promise only\r\n * settles once the entire response has arrived. That means the check cannot be\r\n * \"call fetch, then see whether body exists\" - by that point the whole stream\r\n * has already been buffered and the chance to stream is gone. The transport has\r\n * to be chosen *before* the request is made.\r\n *\r\n * XMLHttpRequest itself does stream everywhere React Native runs: it appends to\r\n * `responseText` and fires `readyState === 3` (LOADING) on every chunk, which is\r\n * all an SSE consumer needs. So the RN path issues the request over raw XHR and\r\n * hands back the same reader interface the fetch path does, leaving callers\r\n * unaware of which one they got.\r\n */\r\n\r\n/** Minimal reader interface, mirroring the shape of a ReadableStream reader. */\r\nexport interface SSEReader {\r\n /** Resolves with the next decoded chunk, or `{ done: true }` at end of stream. */\r\n read(): Promise<{ done: boolean; value?: string }>;\r\n /** Aborts the underlying request. */\r\n cancel(): void;\r\n}\r\n\r\nexport interface SSEStream {\r\n status: number;\r\n ok: boolean;\r\n getHeader(name: string): string | null;\r\n /** Present only when `ok` is false, so callers can surface the server's message. */\r\n errorText?: string;\r\n reader: SSEReader;\r\n}\r\n\r\nexport interface OpenSSEOptions {\r\n url: string;\r\n headers: Record<string, string>;\r\n body: string;\r\n signal?: AbortSignal;\r\n}\r\n\r\n/**\r\n * Whether `fetch` on this platform yields a streaming body.\r\n *\r\n * `navigator.product === 'ReactNative'` is the long-standing marker React\r\n * Native sets, and is checked rather than feature-detecting `ReadableStream`:\r\n * newer RN versions do expose a global `ReadableStream` while still leaving\r\n * `response.body` undefined, so the presence of the type says nothing about\r\n * whether fetch will populate it.\r\n */\r\nexport function supportsStreamingFetch(): boolean {\r\n if (\r\n typeof navigator !== \"undefined\" &&\r\n (navigator as { product?: string }).product === \"ReactNative\"\r\n ) {\r\n return false;\r\n }\r\n return typeof fetch !== \"undefined\" && typeof ReadableStream !== \"undefined\";\r\n}\r\n\r\n/** Wraps a whatwg ReadableStream reader so it decodes to strings. */\r\nfunction fetchReader(\r\n response: Response,\r\n controller: AbortController,\r\n): SSEReader {\r\n const reader = response.body!.getReader();\r\n const decoder = new TextDecoder(\"utf-8\");\r\n\r\n return {\r\n async read() {\r\n const { done, value } = await reader.read();\r\n if (done) return { done: true };\r\n return { done: false, value: decoder.decode(value, { stream: true }) };\r\n },\r\n cancel() {\r\n controller.abort();\r\n void reader.cancel().catch(() => {});\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Issues the request over XMLHttpRequest and exposes new text as it arrives.\r\n *\r\n * XHR keeps the whole response in `responseText` and only ever appends, so each\r\n * chunk is the slice past what has already been handed out.\r\n */\r\nfunction xhrStream(opts: OpenSSEOptions): Promise<SSEStream> {\r\n return new Promise<SSEStream>((resolveStream, rejectStream) => {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open(\"POST\", opts.url);\r\n for (const [key, val] of Object.entries(opts.headers))\r\n xhr.setRequestHeader(key, val);\r\n\r\n let consumed = 0;\r\n let finished = false;\r\n let failure: Error | null = null;\r\n // Chunks that arrived before the consumer asked for them, and the pending\r\n // read waiting for one - only one of the two is ever non-empty.\r\n const queue: string[] = [];\r\n let waiting: ((r: { done: boolean; value?: string }) => void) | null = null;\r\n let waitingReject: ((e: Error) => void) | null = null;\r\n let headersResolved = false;\r\n\r\n const pump = () => {\r\n const text = xhr.responseText;\r\n if (text.length <= consumed) return;\r\n const chunk = text.slice(consumed);\r\n consumed = text.length;\r\n\r\n if (waiting) {\r\n const resolve = waiting;\r\n waiting = null;\r\n waitingReject = null;\r\n resolve({ done: false, value: chunk });\r\n } else {\r\n queue.push(chunk);\r\n }\r\n };\r\n\r\n const finish = (err?: Error) => {\r\n if (finished) return;\r\n finished = true;\r\n failure = err ?? null;\r\n if (waiting) {\r\n const resolve = waiting;\r\n const reject = waitingReject;\r\n waiting = null;\r\n waitingReject = null;\r\n if (err && reject) reject(err);\r\n else resolve({ done: true });\r\n }\r\n };\r\n\r\n const reader: SSEReader = {\r\n read() {\r\n if (queue.length > 0) {\r\n return Promise.resolve({ done: false, value: queue.shift() });\r\n }\r\n if (finished) {\r\n return failure\r\n ? Promise.reject(failure)\r\n : Promise.resolve({ done: true });\r\n }\r\n return new Promise((resolve, reject) => {\r\n waiting = resolve;\r\n waitingReject = reject;\r\n });\r\n },\r\n cancel() {\r\n finish();\r\n xhr.abort();\r\n },\r\n };\r\n\r\n // Headers are available from readyState 2, which is what lets a non-2xx\r\n // response be reported without waiting for the body to finish.\r\n const resolveHeaders = () => {\r\n if (headersResolved) return;\r\n headersResolved = true;\r\n const ok = xhr.status >= 200 && xhr.status < 300;\r\n resolveStream({\r\n status: xhr.status,\r\n ok,\r\n getHeader: (name: string) => xhr.getResponseHeader(name),\r\n reader,\r\n });\r\n };\r\n\r\n xhr.onreadystatechange = () => {\r\n if (xhr.readyState === 2) {\r\n resolveHeaders();\r\n } else if (xhr.readyState === 3) {\r\n resolveHeaders();\r\n pump();\r\n } else if (xhr.readyState === 4) {\r\n resolveHeaders();\r\n pump();\r\n finish();\r\n }\r\n };\r\n\r\n xhr.onerror = () => {\r\n const err = new Error(\"Network request failed\");\r\n if (!headersResolved) rejectStream(err);\r\n finish(err);\r\n };\r\n xhr.ontimeout = () => {\r\n const err = new Error(\"Network request timed out\");\r\n if (!headersResolved) rejectStream(err);\r\n finish(err);\r\n };\r\n\r\n if (opts.signal) {\r\n if (opts.signal.aborted) {\r\n xhr.abort();\r\n finish();\r\n } else {\r\n opts.signal.addEventListener(\"abort\", () => {\r\n finish();\r\n xhr.abort();\r\n });\r\n }\r\n }\r\n\r\n xhr.send(opts.body);\r\n });\r\n}\r\n\r\n/**\r\n * Opens an SSE stream, using whichever transport this platform can stream over.\r\n */\r\nexport async function openSSEStream(opts: OpenSSEOptions): Promise<SSEStream> {\r\n if (!supportsStreamingFetch()) {\r\n return xhrStream(opts);\r\n }\r\n\r\n const controller = new AbortController();\r\n if (opts.signal) {\r\n if (opts.signal.aborted) controller.abort();\r\n else opts.signal.addEventListener(\"abort\", () => controller.abort());\r\n }\r\n\r\n const response = await fetch(opts.url, {\r\n method: \"POST\",\r\n headers: opts.headers,\r\n body: opts.body,\r\n signal: controller.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => \"Stream failed\");\r\n return {\r\n status: response.status,\r\n ok: false,\r\n errorText,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: {\r\n read: async () => ({ done: true }),\r\n cancel: () => controller.abort(),\r\n },\r\n };\r\n }\r\n\r\n if (!response.body) {\r\n // A streaming-capable platform that still gave no body - fall back to the\r\n // buffered text rather than failing outright.\r\n const text = await response.text();\r\n let handed = false;\r\n return {\r\n status: response.status,\r\n ok: true,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: {\r\n read: async () =>\r\n handed\r\n ? { done: true }\r\n : ((handed = true), { done: false, value: text }),\r\n cancel: () => controller.abort(),\r\n },\r\n };\r\n }\r\n\r\n return {\r\n status: response.status,\r\n ok: true,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: fetchReader(response, controller),\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport type { PersonaMemoryFile, PersonaMemoryList } from \"../types.js\";\r\n\r\nexport function useMemory(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [memory, setMemory] = useState<PersonaMemoryList>({\r\n userFiles: [],\r\n agentMemories: [],\r\n });\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchMemory = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/memory\");\r\n if (!res.ok) {\r\n throw new Error(`Failed to fetch memory: ${res.statusText}`);\r\n }\r\n const data = (await res.json()) as PersonaMemoryList;\r\n setMemory(data);\r\n return data;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return { userFiles: [], agentMemories: [] };\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n const getFile = useCallback(\r\n async (params: {\r\n path: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const query = new URLSearchParams({ path: params.path });\r\n if (params.scope) query.set(\"scope\", params.scope);\r\n if (params.agentId) query.set(\"agentId\", params.agentId);\r\n\r\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`);\r\n if (!res.ok)\r\n throw new Error(`Failed to get memory file: ${res.statusText}`);\r\n return (await res.json()) as PersonaMemoryFile;\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const writeFile = useCallback(\r\n async (params: {\r\n path: string;\r\n content: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const res = await fetchWithAuth(\"/memory/file\", {\r\n method: \"PUT\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify(params),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to write memory file: ${res.statusText}`);\r\n const updated = (await res.json()) as PersonaMemoryFile;\r\n void fetchMemory();\r\n return updated;\r\n },\r\n [fetchWithAuth, fetchMemory],\r\n );\r\n\r\n const deleteFile = useCallback(\r\n async (params: {\r\n path: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const query = new URLSearchParams({ path: params.path });\r\n if (params.scope) query.set(\"scope\", params.scope);\r\n if (params.agentId) query.set(\"agentId\", params.agentId);\r\n\r\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`, {\r\n method: \"DELETE\",\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to delete memory file: ${res.statusText}`);\r\n void fetchMemory();\r\n },\r\n [fetchWithAuth, fetchMemory],\r\n );\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchMemory();\r\n }\r\n }, [autoFetch, fetchMemory]);\r\n\r\n return {\r\n memory,\r\n isLoading,\r\n error,\r\n refetch: fetchMemory,\r\n getFile,\r\n writeFile,\r\n deleteFile,\r\n };\r\n}\r\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport type { PersonaThread } from \"../types.js\";\n\nexport function useThreads(autoFetch = true) {\n const { fetchWithAuth, defaultAgentId } = usePersonaContext();\n const [threads, setThreads] = useState<PersonaThread[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchThreads = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth(\"/threads\");\n if (!res.ok) throw new Error(`Failed to list threads: ${res.statusText}`);\n const data = await res.json();\n // Real shape is { items, pagination }. Bare array / `.data` / `.threads`\n // are defensive fallbacks for other deployments, not the actual contract.\n const items: PersonaThread[] = Array.isArray(data)\n ? data\n : data?.items ||\n data?.threads ||\n (Array.isArray(data?.data) ? data.data : undefined) ||\n [];\n setThreads(items);\n return items;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth]);\n\n const createThread = useCallback(\n async (agentId?: string) => {\n const targetAgentId = agentId || defaultAgentId;\n const res = await fetchWithAuth(\"/threads\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ agentId: targetAgentId }),\n });\n if (!res.ok)\n throw new Error(`Failed to create thread: ${res.statusText}`);\n const data = await res.json();\n const created = (data?.data ?? data) as PersonaThread;\n void fetchThreads();\n return created;\n },\n [fetchWithAuth, defaultAgentId, fetchThreads],\n );\n\n const deleteThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}`, {\n method: \"DELETE\",\n });\n if (!res.ok)\n throw new Error(`Failed to delete thread: ${res.statusText}`);\n setThreads((prev) => prev.filter((t) => t._id !== threadId));\n },\n [fetchWithAuth],\n );\n\n // Best-effort batch delete — no not-found id aborts the rest. Up to 100\n // ids per call, matching the server's own limit.\n const bulkDeleteThreads = useCallback(\n async (threadIds: string[]) => {\n const res = await fetchWithAuth(\"/threads/bulk-delete\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ids: threadIds }),\n });\n if (!res.ok)\n throw new Error(`Failed to bulk-delete threads: ${res.statusText}`);\n const data = await res.json();\n const result = (data?.data ?? data) as {\n deleted: string[];\n failed: Array<{ id: string; reason: string }>;\n };\n const deletedSet = new Set(result.deleted);\n setThreads((prev) => prev.filter((t) => !deletedSet.has(t._id)));\n return result;\n },\n [fetchWithAuth],\n );\n\n // Convenience wrapper: there is no server-side \"delete everything\"\n // endpoint, only bulk-delete-by-id — so this bulk-deletes every\n // currently-loaded thread (up to 100 per call, chunked if there are more).\n const deleteAllThreads = useCallback(async () => {\n const ids = threads.map((t) => t._id);\n for (let i = 0; i < ids.length; i += 100) {\n await bulkDeleteThreads(ids.slice(i, i + 100));\n }\n }, [threads, bulkDeleteThreads]);\n\n // General-purpose update — { title?, isArchived? }.\n const updateThread = useCallback(\n async (\n threadId: string,\n input: { title?: string; isArchived?: boolean },\n ) => {\n const res = await fetchWithAuth(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input),\n });\n if (!res.ok)\n throw new Error(`Failed to update thread: ${res.statusText}`);\n const data = await res.json();\n const updated = (data?.data ?? data) as PersonaThread;\n setThreads((prev) =>\n prev.map((t) => (t._id === threadId ? { ...t, ...updated } : t)),\n );\n return updated;\n },\n [fetchWithAuth],\n );\n\n const renameThread = useCallback(\n (threadId: string, title: string) => updateThread(threadId, { title }),\n [updateThread],\n );\n\n // Clears a thread's conversation content in place (message history, files/\n // todos, subagent traces) while keeping the same thread id/title — unlike\n // deleteThread, nothing about the thread's identity changes, so callers\n // can reuse it as a fresh conversation instead of creating a new one.\n const resetThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}/reset`, {\n method: \"POST\",\n });\n if (!res.ok) throw new Error(`Failed to reset thread: ${res.statusText}`);\n const data = await res.json();\n const reset = (data?.data ?? data) as PersonaThread;\n setThreads((prev) =>\n prev.map((t) => (t._id === threadId ? { ...t, ...reset } : t)),\n );\n return reset;\n },\n [fetchWithAuth],\n );\n\n const getThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}`);\n if (!res.ok) throw new Error(`Failed to fetch thread: ${res.statusText}`);\n const data = await res.json();\n return (data?.data ?? data) as PersonaThread;\n },\n [fetchWithAuth],\n );\n\n useEffect(() => {\n if (autoFetch) {\n void fetchThreads();\n }\n }, [autoFetch, fetchThreads]);\n\n return {\n threads,\n isLoading,\n error,\n refetch: fetchThreads,\n createThread,\n deleteThread,\n bulkDeleteThreads,\n deleteAllThreads,\n updateThread,\n renameThread,\n resetThread,\n getThread,\n };\n}\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport { recorderWorkletUrl, playerWorkletUrl } from \"./voiceWorklets.js\";\r\nimport type {\r\n PersonaVoiceEndReason,\r\n PersonaVoiceState,\r\n PersonaVoiceToolCall,\r\n PersonaVoiceTranscriptLine,\r\n UseVoiceOptions,\r\n UseVoiceResult,\r\n} from \"../types.js\";\r\n\r\ninterface VoiceSessionTicket {\r\n ticket: string;\r\n wsUrl: string;\r\n expiresAt: string;\r\n session: {\r\n model: string;\r\n voice: string;\r\n inputSampleRate: number;\r\n outputSampleRate: number;\r\n maxDurationMs: number;\r\n };\r\n}\r\n\r\n// Gemini Live delivers an agent utterance's output transcription as SEVERAL\r\n// incremental fragments (one serverContent message per fragment) inside a\r\n// single model turn — there is no per-fragment \"finished\" flag; only\r\n// turnComplete closes the turn. The gateway forwards each fragment as its own\r\n// isFinal:true voice_transcript event, so without merging here every fragment\r\n// would render as its own stacked bubble even though the concatenated text is\r\n// one sentence. Fragments arrive as EITHER a cumulative full snapshot OR\r\n// incremental new words (Gemini does both), so handle both:\r\n// - cumulative: next already contains prev from the start -> take next\r\n// - incremental: append next, inserting a space only at a clean word seam\r\nfunction mergeTranscriptText(prev: string, next: string): string {\r\n if (!prev) return next;\r\n if (!next) return prev;\r\n if (next === prev || prev.endsWith(next)) return prev; // no-op / dup tail\r\n if (next.startsWith(prev)) return next; // cumulative snapshot\r\n const needSpace = !/\\s$/.test(prev) && !/^\\s/.test(next);\r\n return prev + (needSpace ? \" \" : \"\") + next;\r\n}\r\n\r\ninterface VoiceTranscriptValue {\r\n speaker: \"user\" | \"agent\";\r\n text: string;\r\n isFinal: boolean;\r\n turnSeq?: number;\r\n}\r\n\r\n/**\r\n * Drives a real-time voice call with an Agent (powered by Gemini Live).\r\n *\r\n * Ticket minting goes through YOUR OWN backend (`POST /voice/sessions` on\r\n * whichever `@personaai/runtime`-based adapter you've mounted) via\r\n * `fetchWithAuth` — same as every other hook in this package. The actual\r\n * call does NOT: once a ticket comes back, this hook opens a WebSocket\r\n * DIRECTLY to Persona (`ticket.wsUrl`), bypassing your backend entirely for\r\n * the live audio. This is deliberate — see the package README's Voice\r\n * section for why (short version: a multi-minute relay would not survive\r\n * on a serverless deployment the way `POST /chat`'s bounded SSE relay\r\n * does), and it means your backend never has to become a WebSocket relay.\r\n *\r\n * Requires a browser with `AudioWorklet` support (all current evergreen\r\n * browsers). The processor code itself needs no `/public` file of your\r\n * own — it's embedded and loaded via a Blob URL (see `voiceWorklets.ts`).\r\n */\r\nexport function useVoice(options: UseVoiceOptions = {}): UseVoiceResult {\r\n const { defaultAgentId, fetchWithAuth, logger } = usePersonaContext();\r\n const voiceLogger = useMemo(() => logger.child(\"voice\"), [logger]);\r\n const agentId = options.agentId || defaultAgentId;\r\n const threadId = options.threadId;\r\n const contextOverride = options.contextOverride;\r\n const context = options.context;\r\n\r\n const [state, setState] = useState<PersonaVoiceState>(\"idle\");\r\n const [isMuted, setIsMuted] = useState(false);\r\n const [transcript, setTranscript] = useState<PersonaVoiceTranscriptLine[]>(\r\n [],\r\n );\r\n const [partial, setPartial] = useState<PersonaVoiceTranscriptLine | null>(\r\n null,\r\n );\r\n const [toolCalls, setToolCalls] = useState<PersonaVoiceToolCall[]>([]);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [endReason, setEndReason] = useState<PersonaVoiceEndReason | null>(\r\n null,\r\n );\r\n\r\n const wsRef = useRef<WebSocket | null>(null);\r\n const streamRef = useRef<MediaStream | null>(null);\r\n const inputCtxRef = useRef<AudioContext | null>(null);\r\n const outputCtxRef = useRef<AudioContext | null>(null);\r\n const recorderNodeRef = useRef<AudioWorkletNode | null>(null);\r\n const playerNodeRef = useRef<AudioWorkletNode | null>(null);\r\n const acceptedTurnSeqRef = useRef(0);\r\n const mountedRef = useRef(true);\r\n // Speaker + turnSeq of the last committed transcript line. Consecutive\r\n // finals with the same speaker AND turnSeq are fragments of one utterance\r\n // (the server bumps turnSeq only at turnComplete), so they merge into the\r\n // line they created instead of spawning a new bubble.\r\n const lastFinalTurnRef = useRef<{ speaker: string; turnSeq?: number } | null>(\r\n null,\r\n );\r\n\r\n useEffect(() => {\r\n mountedRef.current = true;\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n const teardownAudio = useCallback(() => {\r\n try {\r\n streamRef.current?.getTracks().forEach((track) => track.stop());\r\n } catch {\r\n // ignore\r\n }\r\n streamRef.current = null;\r\n\r\n try {\r\n recorderNodeRef.current?.disconnect();\r\n } catch {\r\n // ignore\r\n }\r\n recorderNodeRef.current = null;\r\n\r\n try {\r\n playerNodeRef.current?.disconnect();\r\n } catch {\r\n // ignore\r\n }\r\n playerNodeRef.current = null;\r\n\r\n try {\r\n void inputCtxRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n inputCtxRef.current = null;\r\n\r\n try {\r\n void outputCtxRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n outputCtxRef.current = null;\r\n }, []);\r\n\r\n const stop = useCallback(() => {\r\n voiceLogger.debug(\"stop() called\");\r\n try {\r\n wsRef.current?.close(1000, \"client_stop\");\r\n } catch {\r\n // ignore\r\n }\r\n wsRef.current = null;\r\n teardownAudio();\r\n if (mountedRef.current) setState(\"idle\");\r\n }, [teardownAudio, voiceLogger]);\r\n\r\n useEffect(() => stop, [stop]);\r\n\r\n const startCapture = useCallback(async (inputSampleRate: number) => {\r\n const stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n channelCount: 1,\r\n },\r\n });\r\n streamRef.current = stream;\r\n\r\n const inputCtx = new AudioContext({ sampleRate: inputSampleRate });\r\n inputCtxRef.current = inputCtx;\r\n await inputCtx.audioWorklet.addModule(recorderWorkletUrl());\r\n\r\n const source = inputCtx.createMediaStreamSource(stream);\r\n const recorderNode = new AudioWorkletNode(\r\n inputCtx,\r\n \"pcm-recorder-processor\",\r\n );\r\n recorderNode.port.onmessage = (event: MessageEvent<ArrayBuffer>) => {\r\n if (wsRef.current?.readyState === WebSocket.OPEN) {\r\n wsRef.current.send(event.data);\r\n }\r\n };\r\n recorderNodeRef.current = recorderNode;\r\n source.connect(recorderNode);\r\n }, []);\r\n\r\n const setupPlayback = useCallback(async (outputSampleRate: number) => {\r\n const outputCtx = new AudioContext({ sampleRate: outputSampleRate });\r\n outputCtxRef.current = outputCtx;\r\n await outputCtx.audioWorklet.addModule(playerWorkletUrl());\r\n\r\n const playerNode = new AudioWorkletNode(outputCtx, \"pcm-player-processor\");\r\n playerNode.connect(outputCtx.destination);\r\n playerNodeRef.current = playerNode;\r\n }, []);\r\n\r\n const upsertToolCall = useCallback(\r\n (id: string, patch: Partial<PersonaVoiceToolCall>) => {\r\n setToolCalls((prev) => {\r\n const idx = prev.findIndex((t) => t.id === id);\r\n if (idx === -1) return [...prev, { id, status: \"running\", ...patch }];\r\n const next = [...prev];\r\n next[idx] = { ...next[idx], ...patch } as PersonaVoiceToolCall;\r\n return next;\r\n });\r\n },\r\n [],\r\n );\r\n\r\n const handleTranscript = useCallback((value: VoiceTranscriptValue) => {\r\n const { speaker, text, isFinal, turnSeq } = value;\r\n if (!isFinal) {\r\n setPartial({ id: \"partial\", speaker, text });\r\n return;\r\n }\r\n\r\n // A final may land while a partial of the same speaker is showing (the\r\n // last interim is superseded by the final) — clear it only for that case.\r\n setPartial((prev) => (prev?.speaker === speaker ? null : prev));\r\n\r\n const last = lastFinalTurnRef.current;\r\n const sameUserBurst =\r\n speaker === \"user\" &&\r\n last &&\r\n last.speaker === speaker &&\r\n last.turnSeq === turnSeq;\r\n\r\n setTranscript((prev) => {\r\n const tail = prev[prev.length - 1];\r\n // An agent \"answer\" can arrive as several separate finals: per-fragment\r\n // finals of one utterance, or distinct spoken segments split by a tool\r\n // call mid-answer. Keep them as ONE bubble while no user line has\r\n // intervened — this is exactly how the thread reads the same turns back\r\n // (checkpoint.service normalizeMessages merges consecutive assistant\r\n // messages) and how text chat shows one assistant message per answer.\r\n // A committed user line between two agent lines separates answers, so\r\n // the merge only applies when the open line is also agent.\r\n const agentContinues = speaker === \"agent\" && tail?.speaker === \"agent\";\r\n if (agentContinues || (sameUserBurst && tail?.speaker === \"user\")) {\r\n const merged = mergeTranscriptText(tail.text, text);\r\n if (merged === tail.text) return prev;\r\n return prev.map((l, i) =>\r\n i === prev.length - 1 ? { ...l, text: merged } : l,\r\n );\r\n }\r\n return [...prev, { id: `${speaker}-${prev.length}`, speaker, text }];\r\n });\r\n lastFinalTurnRef.current = { speaker, turnSeq };\r\n }, []);\r\n\r\n const handleCustomEvent = useCallback(\r\n (name: string, value: Record<string, unknown>) => {\r\n switch (name) {\r\n case \"voice_session_ready\":\r\n voiceLogger.debug(\"voice_session_ready\", value);\r\n Promise.all([\r\n setupPlayback(value.outputSampleRate as number),\r\n startCapture(value.inputSampleRate as number),\r\n ])\r\n .then(() => {\r\n if (mountedRef.current) setState(\"listening\");\r\n })\r\n .catch((err) => {\r\n voiceLogger.error(\"audio graph setup failed\", {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n if (mountedRef.current) {\r\n setError(err instanceof Error ? err : new Error(String(err)));\r\n setState(\"error\");\r\n }\r\n });\r\n break;\r\n case \"voice_activity\":\r\n if (value.speaker === \"user\" && value.state === \"start\") {\r\n setState(\"listening\");\r\n } else if (value.speaker === \"user\" && value.state === \"end\") {\r\n setState(\"thinking\");\r\n } else if (value.speaker === \"agent\" && value.state === \"start\") {\r\n setState(\"speaking\");\r\n } else if (value.speaker === \"agent\" && value.state === \"end\") {\r\n setState(\"listening\");\r\n }\r\n break;\r\n case \"voice_transcript\":\r\n handleTranscript(value as unknown as VoiceTranscriptValue);\r\n break;\r\n case \"voice_interrupted\":\r\n acceptedTurnSeqRef.current = value.turnSeq as number;\r\n playerNodeRef.current?.port.postMessage({ type: \"flush\" });\r\n break;\r\n case \"voice_session_resumed\":\r\n voiceLogger.info(\"session transparently resumed\");\r\n break;\r\n case \"voice_session_ended\":\r\n voiceLogger.info(\"session ended\", { reason: value.reason });\r\n setState(\"ended\");\r\n setEndReason((value.reason as PersonaVoiceEndReason) ?? null);\r\n teardownAudio();\r\n try {\r\n wsRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n wsRef.current = null;\r\n break;\r\n default:\r\n break;\r\n }\r\n },\r\n [handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger],\r\n );\r\n\r\n const handleMessage = useCallback(\r\n (event: MessageEvent<ArrayBuffer | string>) => {\r\n if (typeof event.data !== \"string\") {\r\n const buf = event.data;\r\n const view = new DataView(buf);\r\n const turnSeq = view.getUint32(0, true);\r\n // Accept (and adopt) anything >= the last accepted value rather\r\n // than an exact match — the server bumps turnSeq on EVERY new\r\n // agent turn, not only on a barge-in. WebSocket delivers messages\r\n // in send order on one connection, so a voice_interrupted event\r\n // always arrives before any frame from the generation it\r\n // announces — nothing stale can arrive after it.\r\n if (turnSeq >= acceptedTurnSeqRef.current) {\r\n acceptedTurnSeqRef.current = turnSeq;\r\n const pcmBytes = buf.slice(4);\r\n playerNodeRef.current?.port.postMessage(pcmBytes, [pcmBytes]);\r\n }\r\n return;\r\n }\r\n\r\n let msg: Record<string, unknown>;\r\n try {\r\n msg = JSON.parse(event.data);\r\n } catch {\r\n return;\r\n }\r\n\r\n switch (msg.type) {\r\n case \"CUSTOM\":\r\n handleCustomEvent(\r\n msg.name as string,\r\n msg.value as Record<string, unknown>,\r\n );\r\n break;\r\n case \"TOOL_CALL_CHUNK\":\r\n upsertToolCall(msg.toolCallId as string, {\r\n name: msg.toolCallName as string | undefined,\r\n status: \"running\",\r\n });\r\n break;\r\n case \"TOOL_CALL_RESULT\": {\r\n let parsed: { output?: unknown; error?: string } | null = null;\r\n try {\r\n parsed = JSON.parse(msg.content as string);\r\n } catch {\r\n parsed = { output: msg.content };\r\n }\r\n upsertToolCall(msg.toolCallId as string, {\r\n status: parsed?.error ? \"error\" : \"done\",\r\n summary:\r\n parsed?.error ||\r\n (typeof parsed?.output === \"string\"\r\n ? parsed.output\r\n : JSON.stringify(parsed?.output ?? \"\")),\r\n });\r\n break;\r\n }\r\n case \"RUN_ERROR\":\r\n voiceLogger.warn(\"RUN_ERROR\", { message: msg.message });\r\n setError(\r\n new Error((msg.message as string) || \"The agent run failed.\"),\r\n );\r\n setState(\"error\");\r\n break;\r\n default:\r\n break;\r\n }\r\n },\r\n [handleCustomEvent, upsertToolCall, voiceLogger],\r\n );\r\n\r\n const start = useCallback(async () => {\r\n if (!agentId) {\r\n const err = new Error(\r\n \"useVoice: no agentId provided and no defaultAgentId set on PersonaProvider\",\r\n );\r\n setError(err);\r\n setState(\"error\");\r\n return;\r\n }\r\n\r\n setError(null);\r\n setEndReason(null);\r\n setTranscript([]);\r\n setPartial(null);\r\n setToolCalls([]);\r\n acceptedTurnSeqRef.current = 0;\r\n setState(\"connecting\");\r\n voiceLogger.debug(\"start() called\", {\r\n agentId,\r\n threadId,\r\n hasContextOverride: !!contextOverride,\r\n hasContext: !!context,\r\n });\r\n\r\n try {\r\n const res = await fetchWithAuth(\"/voice/sessions\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n agentId,\r\n ...(threadId ? { threadId } : {}),\r\n ...(contextOverride ? { contextOverride } : {}),\r\n ...(context ? { context } : {}),\r\n }),\r\n });\r\n if (!res.ok) {\r\n throw new Error(`Failed to start voice session: ${res.statusText}`);\r\n }\r\n const data = await res.json();\r\n const ticket = (data?.data ?? data) as VoiceSessionTicket;\r\n if (!ticket?.wsUrl) {\r\n throw new Error(\"Server did not return a voice session URL.\");\r\n }\r\n\r\n const ws = new WebSocket(ticket.wsUrl);\r\n ws.binaryType = \"arraybuffer\";\r\n wsRef.current = ws;\r\n\r\n ws.onmessage = handleMessage;\r\n ws.onerror = () => {\r\n voiceLogger.warn(\"WebSocket error\");\r\n if (mountedRef.current) {\r\n setError(new Error(\"Voice connection error.\"));\r\n setState(\"error\");\r\n }\r\n };\r\n ws.onclose = () => {\r\n if (mountedRef.current && wsRef.current === ws) {\r\n setState((prev) => (prev === \"error\" ? prev : \"idle\"));\r\n }\r\n };\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n voiceLogger.error(\"start() failed\", { error: errorObj.message });\r\n if (mountedRef.current) {\r\n setError(errorObj);\r\n setState(\"error\");\r\n }\r\n teardownAudio();\r\n }\r\n }, [agentId, threadId, contextOverride, context, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);\r\n\r\n const mute = useCallback((muted: boolean) => {\r\n setIsMuted(muted);\r\n streamRef.current?.getAudioTracks().forEach((track) => {\r\n track.enabled = !muted;\r\n });\r\n }, []);\r\n\r\n const sendText = useCallback((text: string) => {\r\n if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;\r\n wsRef.current.send(JSON.stringify({ type: \"voice.text\", text }));\r\n }, []);\r\n\r\n // Live refresh for the rest of an already-open call — the backend merges\r\n // this into whatever turnContext it already has (the start() seed, or an\r\n // earlier updateContext() call), so callers only need to send what\r\n // actually changed. A no-op while there's no open socket, same guard\r\n // sendText uses — nothing queues for \"once connected.\"\r\n const updateContext = useCallback((newContext: Record<string, unknown>) => {\r\n if (wsRef.current?.readyState !== WebSocket.OPEN) return;\r\n wsRef.current.send(JSON.stringify({ type: \"voice.context\", context: newContext }));\r\n }, []);\r\n\r\n return {\r\n state,\r\n isMuted,\r\n transcript,\r\n partial,\r\n toolCalls,\r\n error,\r\n endReason,\r\n start,\r\n stop,\r\n mute,\r\n sendText,\r\n updateContext,\r\n };\r\n}\r\n","/**\n * AudioWorklet processor source for `useVoice`, embedded as strings rather\n * than shipped as separate static files. A consumer app has no `/public`\n * directory we can rely on being copied into (unlike our own first-party\n * frontend, which loads these from `/voice/*.js`) — `URL.createObjectURL`\n * + a Blob is the standard way to hand `audioWorklet.addModule()` a module\n * with zero setup required from the host app.\n */\n\nconst RECORDER_WORKLET_SOURCE = `\nclass PCMRecorderProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this._buffer = [];\n this._chunkSamples = 320; // 20ms @ 16kHz\n }\n\n process(inputs) {\n const input = inputs[0];\n const channel = input && input[0];\n if (channel) {\n for (let i = 0; i < channel.length; i++) {\n this._buffer.push(channel[i]);\n }\n while (this._buffer.length >= this._chunkSamples) {\n const chunk = this._buffer.splice(0, this._chunkSamples);\n const int16 = new Int16Array(chunk.length);\n for (let i = 0; i < chunk.length; i++) {\n const s = Math.max(-1, Math.min(1, chunk[i]));\n int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff;\n }\n this.port.postMessage(int16.buffer, [int16.buffer]);\n }\n }\n return true;\n }\n}\n\nregisterProcessor('pcm-recorder-processor', PCMRecorderProcessor);\n`;\n\nconst PLAYER_WORKLET_SOURCE = `\nclass PCMPlayerProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this._queue = [];\n this._readOffset = 0;\n this.port.onmessage = (event) => {\n const msg = event.data;\n if (msg && msg.type === 'flush') {\n this._queue = [];\n this._readOffset = 0;\n return;\n }\n const int16 = new Int16Array(msg);\n const float32 = new Float32Array(int16.length);\n for (let i = 0; i < int16.length; i++) {\n float32[i] = int16[i] / 0x8000;\n }\n this._queue.push(float32);\n };\n }\n\n process(_inputs, outputs) {\n const output = outputs[0][0];\n let outIdx = 0;\n while (outIdx < output.length) {\n if (this._queue.length === 0) {\n output[outIdx++] = 0;\n continue;\n }\n const current = this._queue[0];\n const remaining = current.length - this._readOffset;\n const toCopy = Math.min(remaining, output.length - outIdx);\n output.set(current.subarray(this._readOffset, this._readOffset + toCopy), outIdx);\n outIdx += toCopy;\n this._readOffset += toCopy;\n if (this._readOffset >= current.length) {\n this._queue.shift();\n this._readOffset = 0;\n }\n }\n return true;\n }\n}\n\nregisterProcessor('pcm-player-processor', PCMPlayerProcessor);\n`;\n\nfunction toModuleUrl(source: string): string {\n const blob = new Blob([source], { type: \"application/javascript\" });\n return URL.createObjectURL(blob);\n}\n\nexport function recorderWorkletUrl(): string {\n return toModuleUrl(RECORDER_WORKLET_SOURCE);\n}\n\nexport function playerWorkletUrl(): string {\n return toModuleUrl(PLAYER_WORKLET_SOURCE);\n}\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport type { PersonaFileItem } from \"../types.js\";\r\n\r\nexport type { PersonaFileItem };\r\n\r\nexport function useFiles(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [files, setFiles] = useState<PersonaFileItem[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [isUploading, setIsUploading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchFiles = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/files\");\r\n if (!res.ok) throw new Error(`Failed to list files: ${res.statusText}`);\r\n const data = await res.json();\r\n // Real shape is { items, pagination } — bare array/`.files` are\r\n // defensive fallbacks, not the actual wire contract.\r\n const items: PersonaFileItem[] = Array.isArray(data)\r\n ? data\r\n : data?.items || data?.files || [];\r\n setFiles(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n const uploadFile = useCallback(\r\n async (\r\n fileOrFormData: FormData | { name: string; uri: string; type?: string },\r\n ) => {\r\n setIsUploading(true);\r\n setError(null);\r\n try {\r\n let body: FormData;\r\n if (fileOrFormData instanceof FormData) {\r\n body = fileOrFormData;\r\n } else {\r\n // React Native FormData support\r\n body = new FormData();\r\n body.append(\"file\", fileOrFormData as unknown as Blob);\r\n }\r\n\r\n const res = await fetchWithAuth(\"/files\", {\r\n method: \"POST\",\r\n body,\r\n });\r\n\r\n if (!res.ok) {\r\n const errText = await res.text().catch(() => \"Upload failed\");\r\n throw new Error(`Upload error (${res.status}): ${errText}`);\r\n }\r\n\r\n const uploaded = (await res.json()) as PersonaFileItem;\r\n void fetchFiles();\r\n return uploaded;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n throw errorObj;\r\n } finally {\r\n setIsUploading(false);\r\n }\r\n },\r\n [fetchWithAuth, fetchFiles],\r\n );\r\n\r\n const deleteFile = useCallback(\r\n async (fileId: string) => {\r\n const res = await fetchWithAuth(`/files/${fileId}`, { method: \"DELETE\" });\r\n if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);\r\n setFiles((prev) => prev.filter((f) => f.id !== fileId));\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const bulkDeleteFiles = useCallback(\r\n async (fileIds: string[]) => {\r\n const res = await fetchWithAuth(\"/files/bulk-delete\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ ids: fileIds }),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to bulk-delete files: ${res.statusText}`);\r\n const idSet = new Set(fileIds);\r\n setFiles((prev) => prev.filter((f) => !idSet.has(f.id)));\r\n return (await res.json()) as {\r\n deleted: string[];\r\n failed: Array<{ id: string; reason: string }>;\r\n };\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const getDownloadUrl = useCallback((fileId: string) => {\r\n return `/files/${fileId}`;\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchFiles();\r\n }\r\n }, [autoFetch, fetchFiles]);\r\n\r\n return {\r\n files,\r\n isLoading,\r\n isUploading,\r\n error,\r\n refetch: fetchFiles,\r\n uploadFile,\r\n deleteFile,\r\n bulkDeleteFiles,\r\n getDownloadUrl,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\nexport interface PersonaAgentSummary {\r\n _id: string;\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n tagline?: string;\r\n avatar?: string;\r\n}\r\n\r\nexport function useAgents(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [agents, setAgents] = useState<PersonaAgentSummary[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchAgents = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/agents\");\r\n if (!res.ok) throw new Error(`Failed to list agents: ${res.statusText}`);\r\n const data = await res.json();\r\n // Real shape is { items, pagination }.\r\n const items: PersonaAgentSummary[] = Array.isArray(data)\r\n ? data\r\n : data?.items || data?.agents || [];\r\n setAgents(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchAgents();\r\n }\r\n }, [autoFetch, fetchAgents]);\r\n\r\n return {\r\n agents,\r\n isLoading,\r\n error,\r\n refetch: fetchAgents,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\nexport interface PersonaHealthInfo {\r\n status: string;\r\n version?: string;\r\n capabilities?: Record<string, boolean>;\r\n}\r\n\r\nexport function useConnection(autoCheck = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [health, setHealth] = useState<PersonaHealthInfo | null>(null);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const checkHealth = useCallback(async () => {\r\n setIsLoading(true);\r\n try {\r\n const res = await fetchWithAuth(\"/health\");\r\n if (res.ok) {\r\n const data = (await res.json()) as PersonaHealthInfo;\r\n setHealth(data);\r\n setIsConnected(true);\r\n return data;\r\n }\r\n setIsConnected(false);\r\n return null;\r\n } catch {\r\n setIsConnected(false);\r\n return null;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n useEffect(() => {\r\n if (autoCheck) {\r\n void checkHealth();\r\n }\r\n }, [autoCheck, checkHealth]);\r\n\r\n return {\r\n isConnected,\r\n health,\r\n isLoading,\r\n checkHealth,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\n/**\r\n * One `authType: 'oauth', authMode: 'user'` MCP an Agent has attached, and\r\n * whether the current end user has connected it yet. `authorizeUrl` is only\r\n * present when `connected` is `false` — navigate the browser there (a\r\n * same-tab redirect is fine; it's a real OAuth authorization URL) to start\r\n * the consent flow.\r\n */\r\nexport interface PersonaMcpConnection {\r\n mcpId: string;\r\n name: string;\r\n description: string;\r\n connected: boolean;\r\n authorizeUrl: string | null;\r\n}\r\n\r\nexport interface UseMcpConnectionsOptions {\r\n /** @default the PersonaProvider's defaultAgentId */\r\n agentId?: string;\r\n /** Where the browser lands after OAuth consent completes. @default window.location.href */\r\n returnTo?: string;\r\n /** @default true */\r\n autoFetch?: boolean;\r\n}\r\n\r\n/**\r\n * Surfaces the gap that used to be invisible entirely: a user-mode MCP tool\r\n * call for a user who hasn't connected yet is silently dropped from the\r\n * Agent's toolset server-side, with no signal in the chat stream at all.\r\n * Check this before (or alongside) a chat session to show a real \"Connect\r\n * your account\" affordance instead of a capability that just quietly isn't\r\n * there.\r\n */\r\nexport function useMcpConnections(options: UseMcpConnectionsOptions = {}) {\r\n const { defaultAgentId, fetchWithAuth } = usePersonaContext();\r\n const agentId = options.agentId ?? defaultAgentId;\r\n const autoFetch = options.autoFetch ?? true;\r\n\r\n const [connections, setConnections] = useState<PersonaMcpConnection[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchConnections = useCallback(async () => {\r\n if (!agentId) return [];\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const returnTo =\r\n options.returnTo ??\r\n (typeof window !== \"undefined\" ? window.location.href : undefined);\r\n const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : \"\";\r\n const res = await fetchWithAuth(\r\n `/agents/${agentId}/mcp-connections${query}`,\r\n );\r\n if (!res.ok)\r\n throw new Error(`Failed to load MCP connections: ${res.statusText}`);\r\n const data = await res.json();\r\n const items: PersonaMcpConnection[] = Array.isArray(data)\r\n ? data\r\n : data?.items || [];\r\n setConnections(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [agentId, fetchWithAuth, options.returnTo]);\r\n\r\n useEffect(() => {\r\n if (autoFetch) void fetchConnections();\r\n }, [autoFetch, fetchConnections]);\r\n\r\n return {\r\n connections,\r\n /** Convenience filter for the common \"show a banner for what's missing\" case. */\r\n unconnected: connections.filter((c) => !c.connected),\r\n isLoading,\r\n error,\r\n refetch: fetchConnections,\r\n };\r\n}\r\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\n\nexport interface UseMcpOptions {\n /** Default MCP server ID for resource reads and tool calls */\n mcpId?: string;\n}\n\n/**\n * Hook for interacting with MCP servers connected via the Persona runtime.\n * Provides helper functions for reading UI/data resources and calling server tools.\n */\nexport function useMcp(options: UseMcpOptions = {}) {\n const { fetchWithAuth } = usePersonaContext();\n const defaultMcpId = options.mcpId;\n\n /**\n * Reads a resource by URI from an MCP server.\n * @param uri - The resource URI (e.g. `ui://...` or data resource URI).\n * @param mcpId - Optional MCP ID to override the hook's default.\n */\n const readResource = useCallback(\n async (uri: string, mcpId?: string) => {\n const id = mcpId ?? defaultMcpId;\n if (!id) throw new Error(\"MCP server ID is required to read resource\");\n const res = await fetchWithAuth(\n `/mcps/${id}/resource?uri=${encodeURIComponent(uri)}`\n );\n if (!res.ok) {\n throw new Error(`Failed to read MCP resource: ${res.statusText}`);\n }\n return await res.json();\n },\n [fetchWithAuth, defaultMcpId]\n );\n\n /**\n * Invokes a tool exposed by an MCP server.\n * @param name - Tool name.\n * @param args - Arguments matching the tool's schema.\n * @param mcpId - Optional MCP ID to override the hook's default.\n */\n const callTool = useCallback(\n async (\n name: string,\n args?: Record<string, unknown>,\n mcpId?: string\n ) => {\n const id = mcpId ?? defaultMcpId;\n if (!id) throw new Error(\"MCP server ID is required to call tool\");\n const res = await fetchWithAuth(`/mcps/${id}/call-tool`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name, arguments: args }),\n });\n if (!res.ok) {\n throw new Error(`Failed to call MCP tool: ${res.statusText}`);\n }\n return await res.json();\n },\n [fetchWithAuth, defaultMcpId]\n );\n\n return {\n readResource,\n callTool,\n };\n}\n","export * from \"./types.js\";\r\nexport * from \"./context/PersonaContext.js\";\r\nexport * from \"./hooks/useChat.js\";\r\nexport * from \"./hooks/useMemory.js\";\r\nexport * from \"./hooks/useThreads.js\";\r\nexport * from \"./hooks/useVoice.js\";\r\nexport * from \"./hooks/useFiles.js\";\r\nexport * from \"./hooks/useAgents.js\";\r\nexport * from \"./hooks/useConnection.js\";\r\nexport * from \"./hooks/useMcpConnections.js\";\r\nexport * from \"./hooks/useMcp.js\";\r\nexport * from \"./streaming.js\";\r\nexport {\r\n createLogger,\r\n createNoopLogger,\r\n setLogLevel,\r\n getLogLevel,\r\n isLevelEnabled,\r\n} from \"@personaai/logger\";\r\nexport type {\r\n Logger,\r\n LogLevel,\r\n LogTransport,\r\n CreateLoggerOptions,\r\n} from \"@personaai/logger\";\r\n\r\nexport const VERSION = \"0.8.1\";\r\n"],"mappings":"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","names":["useMemo","useMemo","value","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useMemo","useRef","useState","useMemo","useState","useRef","useEffect","useCallback","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useCallback","createLogger"]}
1
+ {"version":3,"sources":["../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/streamEventHelpers.ts","../src/hooks/useArchitectChat.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useVoice.ts","../src/hooks/voiceWorklets.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts","../src/hooks/useMcp.ts","../src/hooks/useWorkflows.ts","../src/hooks/useWorkflow.ts","../src/hooks/useWorkflowStream.ts","../src/hooks/useWorkflowRuns.ts","../src/index.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { createContext, useContext, useMemo } from \"react\";\r\nimport type { PersonaProviderProps } from \"../types.js\";\r\nimport { createLogger, type Logger } from \"@personaai/logger\";\r\n\r\ninterface PersonaContextValue {\r\n baseUrl: string;\r\n getAuthToken?: () =>\r\n Promise<string | null | undefined> | string | null | undefined;\r\n defaultAgentId?: string;\r\n fetchWithAuth: (path: string, init?: RequestInit) => Promise<Response>;\r\n logger: Logger;\r\n}\r\n\r\nconst PersonaContext = createContext<PersonaContextValue | null>(null);\r\n\r\nexport function PersonaProvider({\r\n baseUrl,\r\n getAuthToken,\r\n defaultAgentId,\r\n logLevel,\r\n logger: loggerProp,\r\n children,\r\n}: PersonaProviderProps) {\r\n const normalizedBaseUrl = useMemo(\r\n () => baseUrl.replace(/\\/+$/, \"\"),\r\n [baseUrl],\r\n );\r\n\r\n const logger = useMemo<Logger>(() => {\r\n const l =\r\n loggerProp ??\r\n createLogger(\r\n \"react\",\r\n logLevel !== undefined ? { level: logLevel } : undefined,\r\n );\r\n l.debug(\"PersonaProvider created\", {\r\n baseUrl: normalizedBaseUrl,\r\n hasDefaultAgentId: !!defaultAgentId,\r\n });\r\n l.info(\"PersonaProvider mounted\", { baseUrl: normalizedBaseUrl });\r\n l.trace(\"PersonaProvider config\", {\r\n baseUrl: normalizedBaseUrl,\r\n hasGetAuthToken: !!getAuthToken,\r\n });\r\n return l;\r\n }, [loggerProp, logLevel, normalizedBaseUrl, defaultAgentId, getAuthToken]);\r\n\r\n const value = useMemo<PersonaContextValue>(() => {\r\n async function fetchWithAuth(\r\n path: string,\r\n init: RequestInit = {},\r\n ): Promise<Response> {\r\n const token = getAuthToken ? await getAuthToken() : null;\r\n const headers = new Headers(init.headers || {});\r\n if (token) {\r\n headers.set(\"Authorization\", `Bearer ${token}`);\r\n logger.trace(\"fetchWithAuth with token\", { path });\r\n } else {\r\n logger.trace(\"fetchWithAuth without token\", { path });\r\n logger.debug(\"fetchWithAuth no token\", { path });\r\n }\r\n\r\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n const url = `${normalizedBaseUrl}${cleanPath}`;\r\n logger.debug(\"fetchWithAuth request\", {\r\n path: cleanPath,\r\n url,\r\n hasToken: !!token,\r\n });\r\n logger.trace(\"fetchWithAuth details\", {\r\n url,\r\n path: cleanPath,\r\n hasToken: !!token,\r\n });\r\n\r\n try {\r\n const res = await fetch(url, {\r\n ...init,\r\n headers,\r\n });\r\n logger.debug(\"fetchWithAuth response\", {\r\n path: cleanPath,\r\n status: res.status,\r\n ok: res.ok,\r\n });\r\n if (!res.ok) {\r\n logger.warn(\"fetchWithAuth non-ok\", {\r\n path: cleanPath,\r\n status: res.status,\r\n });\r\n } else {\r\n logger.info(\"fetchWithAuth succeeded\", {\r\n path: cleanPath,\r\n status: res.status,\r\n });\r\n }\r\n return res;\r\n } catch (err) {\r\n logger.error(\"fetchWithAuth failed\", {\r\n path: cleanPath,\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n throw err;\r\n }\r\n }\r\n\r\n return {\r\n baseUrl: normalizedBaseUrl,\r\n getAuthToken,\r\n defaultAgentId,\r\n fetchWithAuth,\r\n logger,\r\n };\r\n }, [normalizedBaseUrl, getAuthToken, defaultAgentId, logger]);\r\n\r\n return (\r\n <PersonaContext.Provider value={value}>{children}</PersonaContext.Provider>\r\n );\r\n}\r\n\r\nexport function usePersonaContext(): PersonaContextValue {\r\n const context = useContext(PersonaContext);\r\n if (!context) {\r\n throw new Error(\r\n \"usePersonaContext must be used within a <PersonaProvider>\",\r\n );\r\n }\r\n return context;\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport { openSSEStream } from \"../streaming.js\";\r\nimport type {\r\n PersonaInterrupt,\r\n PersonaMessage,\r\n PersonaPresentedFile,\r\n PersonaResumeValue,\r\n PersonaRole,\r\n PersonaSandboxCommand,\r\n PersonaStreamingEvent,\r\n PersonaSubagentActivityEntry,\r\n PersonaTodo,\r\n PersonaToolCall,\r\n PersonaWorkspaceFile,\r\n SendMessageOverride,\r\n UseChatOptions,\r\n} from \"../types.js\";\r\nimport {\r\n isErrorToolContent,\r\n normalizePendingInterrupt,\r\n normalizeWorkspaceFiles,\r\n parsePresentedFile,\r\n persistedTraceToActivityEntries,\r\n type PersistedSubagentTraceItem,\r\n} from \"./streamEventHelpers.js\";\r\n\r\n// execute's args are `{ command }` and result `{ output, exitCode }` (see\r\n// CodeSandboxBackend.execute, agent-backend/src/modules/sandbox) — both\r\n// arrive here as opaque JSON strings, so this stays defensive rather than\r\n// assuming either parses cleanly (args in particular is still-accumulating\r\n// JSON while the call streams in).\r\nfunction parseSandboxCommand(tc: PersonaToolCall): PersonaSandboxCommand {\r\n let command = tc.args ?? \"\";\r\n try {\r\n const parsedArgs = JSON.parse(tc.args || \"{}\");\r\n if (typeof parsedArgs.command === \"string\") command = parsedArgs.command;\r\n } catch {\r\n // incomplete/still-streaming args — show the raw partial string\r\n }\r\n\r\n let output: string | undefined;\r\n let exitCode: number | null | undefined;\r\n if (tc.result) {\r\n try {\r\n const parsedResult = JSON.parse(tc.result);\r\n if (typeof parsedResult.output === \"string\") {\r\n output = parsedResult.output;\r\n exitCode =\r\n typeof parsedResult.exitCode === \"number\"\r\n ? parsedResult.exitCode\r\n : null;\r\n } else {\r\n output = tc.result;\r\n }\r\n } catch {\r\n output = tc.result;\r\n }\r\n }\r\n\r\n return {\r\n toolCallId: tc.toolCallId,\r\n command,\r\n output,\r\n exitCode,\r\n status: tc.isError ? \"error\" : tc.result ? \"done\" : \"running\",\r\n seq: tc.seq,\r\n };\r\n}\r\n\r\nexport function useChat(options: UseChatOptions = {}) {\r\n const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken, logger } =\r\n usePersonaContext();\r\n const chatLogger = useMemo(() => logger.child(\"chat\"), [logger]);\r\n const agentId = options.agentId || defaultAgentId;\r\n const threadId = options.threadId;\r\n // Ephemeral/fake thread support: when threadId is null/undefined the chat is\r\n // in \"new chat\" mode — no history fetch, no thread creation until first send.\r\n // The real id is minted lazily inside doSend and surfaced via\r\n // options.onThreadCreated so the host can sync its sidebar state.\r\n const [internalThreadId, setInternalThreadId] = useState<string | undefined>(undefined);\r\n const effectiveThreadId = threadId ?? internalThreadId;\r\n // Keep internal in sync when host drives threadId (e.g. after mint)\r\n useEffect(() => {\r\n if (threadId !== undefined) setInternalThreadId(threadId);\r\n }, [threadId]);\r\n\r\n // Log hook initialization at most once per mount (debug/info visible, trace for details)\r\n // This runs during render, so guard with a ref to avoid spam on every re-render\r\n const didLogInitRef = useRef(false);\r\n if (!didLogInitRef.current) {\r\n didLogInitRef.current = true;\r\n chatLogger.debug(\"useChat init\", {\r\n agentId,\r\n threadId,\r\n hasInitialMessages: !!options.initialMessages?.length,\r\n });\r\n chatLogger.trace(\"useChat options\", {\r\n agentId,\r\n threadId,\r\n initialMessageCount: options.initialMessages?.length ?? 0,\r\n });\r\n }\r\n\r\n const [messages, setMessages] = useState<PersonaMessage[]>(\r\n options.initialMessages || [],\r\n );\r\n const [input, setInput] = useState(\"\");\r\n const [isStreaming, setIsStreaming] = useState(false);\r\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [interrupt, setInterrupt] = useState<PersonaInterrupt | null>(null);\r\n const [files, setFiles] = useState<Record<string, PersonaWorkspaceFile>>({});\r\n const [todos, setTodos] = useState<PersonaTodo[]>([]);\r\n const [presentedFile, setPresentedFile] =\r\n useState<PersonaPresentedFile | null>(null);\r\n\r\n // Derived (not separately tracked) from `messages` — every `execute` tool\r\n // call already lives there, both live-streamed and loaded from history, so\r\n // this stays correct for free instead of needing its own reset/restore\r\n // logic the way `presentedFile` (a single most-recent value, not a list)\r\n // does.\r\n const sandboxCommands = useMemo<PersonaSandboxCommand[]>(() => {\r\n const commands: PersonaSandboxCommand[] = [];\r\n for (const message of messages) {\r\n for (const tc of message.toolCalls ?? []) {\r\n if (tc.toolName === \"execute\") commands.push(parseSandboxCommand(tc));\r\n }\r\n }\r\n return commands;\r\n }, [messages]);\r\n\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\r\n\r\n // Voice sync bookkeeping — see the effect below. Kept as refs (not state)\r\n // because they're pure injection-cursor plumbing, never rendered.\r\n const voiceThreadRef = useRef<string | undefined>(effectiveThreadId);\r\n const voicePrevLenRef = useRef(0);\r\n const voiceStreamingIdRef = useRef<string | null>(null);\r\n const voiceUserPartialIdRef = useRef<string | null>(null);\r\n\r\n const stop = useCallback(() => {\r\n if (abortControllerRef.current) {\r\n chatLogger.info(\"stop streaming\", {});\r\n chatLogger.debug(\"abort controller\", {\r\n hasController: !!abortControllerRef.current,\r\n });\r\n abortControllerRef.current.abort();\r\n abortControllerRef.current = null;\r\n setIsStreaming(false);\r\n chatLogger.debug(\"streaming stopped\");\r\n } else {\r\n chatLogger.trace(\"stop called — no active stream\");\r\n }\r\n }, [chatLogger]);\r\n\r\n const clear = useCallback(() => {\r\n chatLogger.info(\"clear chat\", { messageCount: messages.length });\r\n chatLogger.debug(\"clear\", { messageCount: messages.length });\r\n stop();\r\n setMessages([]);\r\n setError(null);\r\n setInterrupt(null);\r\n setFiles({});\r\n setTodos([]);\r\n setPresentedFile(null);\r\n loadedThreadIdRef.current = undefined;\r\n }, [stop, chatLogger, messages.length]);\r\n\r\n const startNewChat = useCallback(() => {\r\n chatLogger.info(\"startNewChat — entering ephemeral mode\");\r\n stop();\r\n setMessages([]);\r\n setError(null);\r\n setInterrupt(null);\r\n setFiles({});\r\n setTodos([]);\r\n setPresentedFile(null);\r\n setInput(\"\");\r\n loadedThreadIdRef.current = undefined;\r\n voiceThreadRef.current = undefined;\r\n voicePrevLenRef.current = 0;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n setInternalThreadId(undefined);\r\n }, [stop, chatLogger]);\r\n\r\n const loadThreadMessages = useCallback(\r\n async (id: string) => {\r\n chatLogger.debug(\"loadThreadMessages start\", { threadId: id });\r\n chatLogger.trace(\"loadThreadMessages\", { threadId: id });\r\n setIsLoadingHistory(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(`/threads/${id}/messages`);\r\n if (!res.ok)\r\n throw new Error(`Failed to load thread history: ${res.statusText}`);\r\n const body = await res.json();\r\n const data = body?.data ?? body;\r\n const raw = (data?.messages ?? []) as Array<{\r\n id?: string;\r\n role: PersonaMessage[\"role\"];\r\n content: string;\r\n toolCalls?: PersonaToolCall[];\r\n }>;\r\n const subagentTraces = (data?.subagentTraces ?? {}) as Record<\r\n string,\r\n PersistedSubagentTraceItem[]\r\n >;\r\n const loaded: PersonaMessage[] = raw.map((m, i) => ({\r\n id: m.id || `history-${id}-${i}`,\r\n role: m.role,\r\n content: m.content,\r\n createdAt: new Date(),\r\n toolCalls: m.toolCalls?.map((tc) => {\r\n const trace = subagentTraces[tc.toolCallId];\r\n return Array.isArray(trace) && trace.length > 0\r\n ? {\r\n ...tc,\r\n subagentActivity: persistedTraceToActivityEntries(trace),\r\n }\r\n : tc;\r\n }),\r\n }));\r\n setMessages(loaded);\r\n // Re-show the approval/clarification card on reload if this thread\r\n // is currently paused — otherwise it wouldn't reappear until the\r\n // next live stream re-surfaces it.\r\n setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));\r\n // Restore the workspace files/todos this thread already had (same\r\n // cleaned shape checkpoint.service.js now derives via\r\n // buildFilesTodosSnapshot, matching the live STATE_SNAPSHOT event).\r\n setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));\r\n setTodos((data?.state?.todos ?? []) as PersonaTodo[]);\r\n loadedThreadIdRef.current = id;\r\n chatLogger.info(\"loadThreadMessages succeeded\", {\r\n threadId: id,\r\n messageCount: loaded.length,\r\n });\r\n chatLogger.debug(\"loadThreadMessages completed\", {\r\n threadId: id,\r\n messageCount: loaded.length,\r\n });\r\n return loaded;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n chatLogger.warn(\"loadThreadMessages failed\", {\r\n threadId: id,\r\n error: errorObj.message,\r\n });\r\n chatLogger.error(\"loadThreadMessages error\", {\r\n threadId: id,\r\n error: errorObj.message,\r\n });\r\n setError(errorObj);\r\n if (loadedThreadIdRef.current === id) loadedThreadIdRef.current = undefined;\r\n return [];\r\n } finally {\r\n setIsLoadingHistory(false);\r\n chatLogger.trace(\"loadThreadMessages end\", { threadId: id });\r\n }\r\n },\r\n [fetchWithAuth, chatLogger],\r\n );\r\n\r\n // Auto-load history the first time a thread with no in-memory messages is\r\n // selected (switching threads in the sidebar). Skipped for a thread whose\r\n // messages already live in state — e.g. one just created by handleSend,\r\n // which sets its placeholder messages in the same render batch as the\r\n // threadId change, so `messages` there is never empty at effect time.\r\n useEffect(() => {\r\n if (!effectiveThreadId || isStreaming) {\r\n chatLogger.trace(\"auto-load skipped\", { threadId: effectiveThreadId, isStreaming });\r\n return;\r\n }\r\n if (loadedThreadIdRef.current === effectiveThreadId) {\r\n chatLogger.trace(\"auto-load already loaded\", { threadId: effectiveThreadId });\r\n return;\r\n }\r\n if (messages.length > 0) {\r\n chatLogger.trace(\"auto-load has messages\", {\r\n threadId: effectiveThreadId,\r\n count: messages.length,\r\n });\r\n return;\r\n }\r\n chatLogger.info(\"auto-load thread history\", { threadId: effectiveThreadId });\r\n chatLogger.debug(\"loadThreadMessages trigger\", { threadId: effectiveThreadId });\r\n void loadThreadMessages(effectiveThreadId);\r\n }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);\r\n\r\n // Merge a `useVoice()` session's live transcript into `messages` — see\r\n // `UseChatOptions.voice`. This replaces the hand-rolled sync effects the\r\n // README used to tell every consumer to write themselves (dedup against\r\n // thread history, merge same-speaker fragments into one bubble, update the\r\n // in-progress agent line in place, and not replay a call's old transcript\r\n // after a threadId switch under the same `useVoice()` instance).\r\n const voice = options.voice;\r\n useEffect(() => {\r\n if (!voice) return;\r\n\r\n // The passed useVoice() instance now targets a different thread (e.g. the\r\n // host app switched conversations without remounting either hook) — its\r\n // transcript belongs to a call that's over as far as this feed is\r\n // concerned. Stop injecting and don't let anything already spoken bleed\r\n // into the new thread's feed once a new call starts.\r\n if (voiceThreadRef.current !== effectiveThreadId) {\r\n voiceThreadRef.current = effectiveThreadId;\r\n voicePrevLenRef.current = voice.transcript.length;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n return;\r\n }\r\n\r\n const isVoiceActive =\r\n voice.state !== \"idle\" && voice.state !== \"ended\" && voice.state !== \"error\";\r\n const curLen = voice.transcript.length;\r\n\r\n // start() resets transcript to [] for a fresh call — realign the cursor.\r\n if (curLen < voicePrevLenRef.current) {\r\n voicePrevLenRef.current = 0;\r\n voiceStreamingIdRef.current = null;\r\n voiceUserPartialIdRef.current = null;\r\n }\r\n\r\n if (!isVoiceActive) {\r\n // Flush any unseen transcript lines that arrived just before stop()\r\n // set state to idle (A1). Previously this block only advanced the\r\n // pointer, permanently discarding the final user utterance.\r\n if (curLen > voicePrevLenRef.current) {\r\n const pendingLines = voice.transcript.slice(voicePrevLenRef.current);\r\n voicePrevLenRef.current = curLen;\r\n for (const line of pendingLines) {\r\n const text = (line.text || \"\").trim();\r\n if (!text) continue;\r\n const role: PersonaRole = line.speaker === \"user\" ? \"user\" : \"assistant\";\r\n const voiceId = `voice-${line.id}`;\r\n setMessages((prev) => {\r\n if (prev.some((m) => m.id === voiceId)) return prev;\r\n if (prev.some((m) => !m.id.startsWith(\"voice-\") && m.role === role && m.content.trim() === text)) return prev;\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\" && role === \"assistant\") {\r\n const merged = text.startsWith(last.content) ? text : `${last.content} ${text}`.trim();\r\n return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];\r\n }\r\n return [...prev, { id: voiceId, role, content: text, createdAt: new Date() }];\r\n });\r\n }\r\n } else {\r\n voicePrevLenRef.current = voice.transcript.length;\r\n }\r\n if (voiceStreamingIdRef.current) {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n return;\r\n }\r\n\r\n if (curLen > voicePrevLenRef.current) {\r\n const newLines = voice.transcript.slice(voicePrevLenRef.current);\r\n voicePrevLenRef.current = curLen;\r\n for (const line of newLines) {\r\n const text = (line.text || \"\").trim();\r\n if (!text) continue;\r\n const role: PersonaRole = line.speaker === \"user\" ? \"user\" : \"assistant\";\r\n const voiceId = `voice-${line.id}`;\r\n setMessages((prev) => {\r\n // Already injected this exact line.\r\n if (prev.some((m) => m.id === voiceId)) return prev;\r\n // Already on the thread as a persisted turn (voice shares the\r\n // thread, so a refresh/reload can already hold it).\r\n if (\r\n prev.some(\r\n (m) =>\r\n !m.id.startsWith(\"voice-\") &&\r\n m.role === role &&\r\n m.content.trim() === text,\r\n )\r\n )\r\n return prev;\r\n const last = prev[prev.length - 1];\r\n // Consecutive agent finals of one spoken answer merge into the\r\n // bubble they opened, same as useVoice() does for `transcript`\r\n // itself — mirrors how the thread coalesces them on reload.\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\" && role === \"assistant\") {\r\n const merged = text.startsWith(last.content)\r\n ? text\r\n : `${last.content} ${text}`.trim();\r\n return [...prev.slice(0, -1), { ...last, content: merged, isStreaming: false }];\r\n }\r\n return [...prev, { id: voiceId, role, content: text, createdAt: new Date() }];\r\n });\r\n }\r\n }\r\n\r\n const agentPartialText = voice.partial?.speaker === \"agent\" ? voice.partial.text.trim() : \"\";\r\n const userPartialText = voice.partial?.speaker === \"user\" ? voice.partial.text.trim() : \"\";\r\n\r\n if (agentPartialText) {\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n setMessages((prev) => {\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"assistant\") {\r\n voiceStreamingIdRef.current = last.id;\r\n return [...prev.slice(0, -1), { ...last, content: agentPartialText, isStreaming: true }];\r\n }\r\n const id = voiceStreamingIdRef.current || `voice-partial-${Date.now()}`;\r\n voiceStreamingIdRef.current = id;\r\n return [...prev, { id, role: \"assistant\", content: agentPartialText, isStreaming: true, createdAt: new Date() }];\r\n });\r\n } else if (userPartialText) {\r\n if (voiceStreamingIdRef.current) {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n setMessages((prev) => {\r\n const last = prev[prev.length - 1];\r\n if (last?.id.startsWith(\"voice-\") && last.role === \"user\" && last.isStreaming) {\r\n voiceUserPartialIdRef.current = last.id;\r\n return [...prev.slice(0, -1), { ...last, content: userPartialText, isStreaming: true }];\r\n }\r\n const id = voiceUserPartialIdRef.current || `voice-partial-user-${Date.now()}`;\r\n voiceUserPartialIdRef.current = id;\r\n return [...prev, { id, role: \"user\", content: userPartialText, isStreaming: true, createdAt: new Date() }];\r\n });\r\n } else {\r\n if (voiceStreamingIdRef.current && voice.state !== \"speaking\") {\r\n const doneId = voiceStreamingIdRef.current;\r\n voiceStreamingIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n if (voiceUserPartialIdRef.current) {\r\n const doneId = voiceUserPartialIdRef.current;\r\n voiceUserPartialIdRef.current = null;\r\n setMessages((prev) => prev.map((m) => (m.id === doneId ? { ...m, isStreaming: false } : m)));\r\n }\r\n }\r\n // `voice` itself isn't a dep — useVoice() returns a fresh object every\r\n // render, so keying off it would re-run this every render regardless of\r\n // whether the transcript actually changed.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [voice?.transcript, voice?.partial, voice?.state, effectiveThreadId]);\r\n\r\n // Internal stream executor — shared by sendMessage and reload so reload can\r\n // supply a truncated base (B1: reload must not build nextMessages from the\r\n // stale full closure). Caller has already validated prompt/isStreaming.\r\n const doSend = useCallback(\r\n async (prompt: string, baseMessages: PersonaMessage[], overrideOptions?: SendMessageOverride): Promise<boolean> => {\r\n const targetAgentId = overrideOptions?.agentId || agentId;\r\n if (!targetAgentId) {\r\n const err = new Error(\"No Agent ID specified for useChat.\");\r\n chatLogger.warn(\"sendMessage no agentId\", {});\r\n chatLogger.error(\"sendMessage failed — no agent\", { error: err.message });\r\n setError(err);\r\n options.onError?.(err);\r\n return false;\r\n }\r\n\r\n chatLogger.debug(\"sendMessage start\", {\r\n promptPreview: prompt.slice(0, 100),\r\n agentId: targetAgentId,\r\n threadId: effectiveThreadId ?? (overrideOptions?.threadId as string | undefined),\r\n hasResume: !!overrideOptions?.resume,\r\n hasContextOverride: !!overrideOptions?.contextOverride,\r\n messageCount: baseMessages.length,\r\n });\r\n chatLogger.trace(\"sendMessage details\", {\r\n agentId: targetAgentId,\r\n promptPreview: prompt.slice(0, 200),\r\n hasResume: !!overrideOptions?.resume,\r\n hasContextOverride: !!overrideOptions?.contextOverride,\r\n });\r\n\r\n const userMessage: PersonaMessage = {\r\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\r\n role: \"user\",\r\n content: prompt,\r\n createdAt: new Date(),\r\n };\r\n\r\n const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\r\n const placeholderAssistant: PersonaMessage = {\r\n id: assistantMessageId,\r\n role: \"assistant\",\r\n content: \"\",\r\n createdAt: new Date(),\r\n isStreaming: true,\r\n toolCalls: [],\r\n };\r\n\r\n const nextMessages = [...baseMessages, userMessage];\r\n setMessages([...nextMessages, placeholderAssistant]);\r\n setInput(\"\");\r\n setIsStreaming(true);\r\n setError(null);\r\n setInterrupt(null);\r\n\r\n const controller = new AbortController();\r\n abortControllerRef.current = controller;\r\n\r\n const finalizeReasoning = () => {\r\n setMessages((prev) =>\r\n prev.map((m) => (m.role === \"reasoning\" && m.isStreaming ? { ...m, isStreaming: false } : m)),\r\n );\r\n };\r\n\r\n try {\r\n const payloadMessages = nextMessages\r\n .filter((m) => m.role !== \"reasoning\")\r\n .map((m) => ({\r\n role: m.role === \"assistant\" ? (\"assistant\" as const) : (\"user\" as const),\r\n content: m.content,\r\n }));\r\n\r\n let resolvedThreadId: string | undefined = (await (overrideOptions?.threadId as string | undefined)) ?? effectiveThreadId;\r\n if (!resolvedThreadId) {\r\n chatLogger.info(\"minting real thread for ephemeral chat\", { agentId: targetAgentId });\r\n const createRes = await fetchWithAuth(\"/threads\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ agentId: targetAgentId }),\r\n });\r\n if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);\r\n const createBody = await createRes.json();\r\n const created = (createBody?.data ?? createBody) as { _id?: string; id?: string };\r\n resolvedThreadId = created._id ?? created.id;\r\n if (!resolvedThreadId) throw new Error(\"Thread creation returned no id\");\r\n setInternalThreadId(resolvedThreadId);\r\n loadedThreadIdRef.current = resolvedThreadId;\r\n options.onThreadCreated?.(resolvedThreadId);\r\n chatLogger.info(\"ephemeral chat minted\", { threadId: resolvedThreadId });\r\n }\r\n chatLogger.trace(\"resolved threadId\", { threadId: resolvedThreadId });\r\n\r\n const token = getAuthToken ? await getAuthToken() : null;\r\n const resolvedHookContext = typeof options.context === \"function\" ? options.context() : options.context;\r\n const mergedContext = { ...resolvedHookContext, ...overrideOptions?.context };\r\n const hasContext = Object.keys(mergedContext).length > 0;\r\n chatLogger.debug(\"opening SSE stream\", {\r\n agentId: targetAgentId,\r\n hasToken: !!token,\r\n hasThreadId: !!resolvedThreadId,\r\n hasContext,\r\n });\r\n const stream = await openSSEStream({\r\n url: `${baseUrl}/chat`,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\r\n },\r\n body: JSON.stringify({\r\n agentId: targetAgentId,\r\n messages: payloadMessages,\r\n threadId: resolvedThreadId,\r\n resume: overrideOptions?.resume,\r\n contextOverride: overrideOptions?.contextOverride,\r\n ...(hasContext ? { context: mergedContext } : {}),\r\n }),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!stream.ok) {\r\n chatLogger.warn(\"SSE stream not ok\", { status: stream.status, errorText: stream.errorText });\r\n chatLogger.error(\"chat stream failed\", { agentId: targetAgentId, status: stream.status, error: stream.errorText });\r\n throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? \"Stream failed\"}`);\r\n }\r\n chatLogger.debug(\"SSE stream opened\", { agentId: targetAgentId, status: stream.status });\r\n chatLogger.info(\"chat stream started\", { agentId: targetAgentId, threadId: resolvedThreadId });\r\n\r\n const reader = stream.reader;\r\n let buffer = \"\";\r\n let accumulatedText = \"\";\r\n const toolCallsMap = new Map<string, PersonaToolCall>();\r\n let streamSeq = 0;\r\n let activeReasoningId: string | null = null;\r\n const reasoningById = new Map<string, { content: string }>();\r\n\r\n const patchAssistant = (patch: Partial<PersonaMessage>) => {\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch } : msg,\r\n ),\r\n );\r\n };\r\n\r\n const insertReasoningMessage = (id: string, seq: number) => {\r\n const msg: PersonaMessage = { id, role: \"reasoning\", content: \"\", createdAt: new Date(), isStreaming: true, seq };\r\n setMessages((prev) => {\r\n const idx = prev.findIndex((m) => m.id === assistantMessageId);\r\n if (idx === -1) return [...prev, msg];\r\n const next = [...prev];\r\n next.splice(idx, 0, msg);\r\n return next;\r\n });\r\n };\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n buffer += value ?? \"\";\r\n const lines = buffer.split(\"\\n\");\r\n buffer = lines.pop() ?? \"\";\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || !trimmed.startsWith(\"data:\")) continue;\r\n const raw = trimmed.replace(/^data:\\s*/, \"\");\r\n if (raw === \"[DONE]\") break;\r\n try {\r\n const event = JSON.parse(raw) as PersonaStreamingEvent;\r\n chatLogger.trace(\"stream event\", { type: event.type, event });\r\n options.onEvent?.(event);\r\n if (event.type === \"TEXT_MESSAGE_CHUNK\" && event.delta) {\r\n chatLogger.debug(\"text chunk\", { deltaLength: event.delta.length });\r\n accumulatedText += event.delta;\r\n patchAssistant({ content: accumulatedText, isStreaming: true });\r\n } else if (event.type === \"TOOL_CALL_CHUNK\" && event.toolCallId) {\r\n chatLogger.debug(\"tool call chunk\", { toolCallId: event.toolCallId, toolCallName: event.toolCallName });\r\n const existing = toolCallsMap.get(event.toolCallId);\r\n if (existing) {\r\n existing.args = (existing.args || \"\") + (event.delta || \"\");\r\n } else {\r\n toolCallsMap.set(event.toolCallId, {\r\n toolCallId: event.toolCallId,\r\n toolName: event.toolCallName || \"\",\r\n args: event.delta || \"\",\r\n seq: streamSeq++,\r\n });\r\n }\r\n patchAssistant({});\r\n } else if (event.type === \"TOOL_CALL_RESULT\") {\r\n chatLogger.debug(\"tool call result\", { toolCallId: event.toolCallId });\r\n const existing = toolCallsMap.get(event.toolCallId);\r\n if (existing) {\r\n existing.result = event.content;\r\n existing.isError = isErrorToolContent(event.content);\r\n if (existing.isError) chatLogger.warn(\"tool call error\", { toolCallId: event.toolCallId });\r\n if (existing.toolName === \"present_file\" && !existing.isError) {\r\n const presented = parsePresentedFile(event.content);\r\n if (presented) {\r\n chatLogger.info(\"present_file\", { path: presented.path });\r\n setPresentedFile(presented);\r\n }\r\n }\r\n patchAssistant({});\r\n }\r\n } else if (event.type === \"STATE_SNAPSHOT\") {\r\n chatLogger.debug(\"state snapshot\", {\r\n fileCount: Object.keys(event.snapshot.files ?? {}).length,\r\n todoCount: event.snapshot.todos?.length ?? 0,\r\n });\r\n setFiles(normalizeWorkspaceFiles(event.snapshot.files ?? {}));\r\n setTodos(event.snapshot.todos ?? []);\r\n } else if (event.type === \"REASONING_MESSAGE_START\" && event.messageId) {\r\n chatLogger.debug(\"reasoning start\", { messageId: event.messageId });\r\n activeReasoningId = event.messageId;\r\n reasoningById.set(event.messageId, { content: \"\" });\r\n insertReasoningMessage(event.messageId, streamSeq++);\r\n } else if (event.type === \"REASONING_MESSAGE_CONTENT\") {\r\n let rid: string = event.messageId || activeReasoningId || \"\";\r\n if (!rid || !reasoningById.has(rid)) {\r\n rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\r\n activeReasoningId = rid;\r\n reasoningById.set(rid, { content: \"\" });\r\n insertReasoningMessage(rid, streamSeq++);\r\n chatLogger.debug(\"reasoning lazy start\", { messageId: rid });\r\n }\r\n const entry = reasoningById.get(rid)!;\r\n entry.content += event.delta;\r\n chatLogger.trace(\"reasoning content\", { messageId: rid, deltaLength: event.delta?.length ?? 0 });\r\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m)));\r\n } else if (event.type === \"REASONING_END\") {\r\n chatLogger.debug(\"reasoning end\", { messageId: activeReasoningId });\r\n const rid = activeReasoningId;\r\n activeReasoningId = null;\r\n if (rid) {\r\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m)));\r\n }\r\n } else if (event.type === \"CUSTOM\") {\r\n chatLogger.debug(\"custom event\", { name: event.name });\r\n if (event.name === \"hitl_request\") {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: \"hitl\" }>;\r\n chatLogger.info(\"hitl interrupt\", { actionCount: value.actionRequests?.length ?? 0 });\r\n setInterrupt({ kind: \"hitl\", actionRequests: value.actionRequests, reviewConfigs: value.reviewConfigs });\r\n } else if (event.name === \"clarification_request\") {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: \"clarification\" }>;\r\n chatLogger.info(\"clarification interrupt\", { questionCount: value.questions?.length ?? 0 });\r\n setInterrupt({ kind: \"clarification\", questions: value.questions });\r\n } else if (event.name === \"subagent_activity\") {\r\n const { toolCallId, ...entry } = event.value as { toolCallId: string } & PersonaSubagentActivityEntry;\r\n chatLogger.trace(\"subagent activity\", { toolCallId, kind: entry.kind });\r\n const existing = toolCallsMap.get(toolCallId);\r\n if (existing) {\r\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\r\n patchAssistant({});\r\n }\r\n } else if (event.name === \"mcp_app\") {\r\n const val = event.value as { toolCallId?: string; resourceUri?: string; mcpId?: string } | undefined;\r\n if (val?.toolCallId && val?.resourceUri && val?.mcpId) {\r\n const existing = toolCallsMap.get(val.toolCallId);\r\n if (existing) {\r\n existing.mcpApp = { resourceUri: val.resourceUri, mcpId: val.mcpId };\r\n patchAssistant({});\r\n }\r\n }\r\n }\r\n } else if ((event as { type: string; title?: string }).type === \"title\") {\r\n const title = (event as { title?: string }).title;\r\n if (typeof title === \"string\" && title.trim()) {\r\n chatLogger.info(\"auto title\", { title });\r\n (options as { onTitle?: (t: string) => void }).onTitle?.(title);\r\n }\r\n } else if (event.type === \"RUN_ERROR\") {\r\n chatLogger.warn(\"run error\", { message: event.message, code: event.code });\r\n chatLogger.error(\"stream run error\", { code: event.code, message: event.message });\r\n throw new Error(event.message || \"Stream error from agent\");\r\n } else {\r\n chatLogger.trace(\"unhandled event\", { type: event.type });\r\n }\r\n } catch (e) {\r\n if (e instanceof Error && e.message.startsWith(\"Stream error\")) throw e;\r\n chatLogger.warn(\"event parse error\", { raw: raw.slice(0, 200), error: e instanceof Error ? e.message : String(e) });\r\n }\r\n }\r\n }\r\n\r\n const finalMessage: PersonaMessage = {\r\n id: assistantMessageId,\r\n role: \"assistant\",\r\n content: accumulatedText,\r\n createdAt: new Date(),\r\n isStreaming: false,\r\n toolCalls: Array.from(toolCallsMap.values()),\r\n };\r\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg)));\r\n chatLogger.info(\"sendMessage succeeded\", { agentId: targetAgentId, textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });\r\n chatLogger.debug(\"sendMessage completed\", { agentId: targetAgentId, textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });\r\n options.onFinish?.(finalMessage);\r\n return true;\r\n } catch (err) {\r\n if (controller.signal.aborted) {\r\n chatLogger.info(\"sendMessage aborted\", { agentId: targetAgentId });\r\n chatLogger.debug(\"stream aborted\", { agentId: targetAgentId });\r\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg)));\r\n return false;\r\n }\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n chatLogger.warn(\"sendMessage failed\", { agentId: targetAgentId, error: errorObj.message });\r\n chatLogger.error(\"sendMessage error\", { agentId: targetAgentId, error: errorObj.message });\r\n setError(errorObj);\r\n options.onError?.(errorObj);\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId\r\n ? { ...msg, content: msg.content || `⚠️ Error: ${errorObj.message || \"Failed to get response.\"}`, isStreaming: false }\r\n : msg,\r\n ),\r\n );\r\n return false;\r\n } finally {\r\n setIsStreaming(false);\r\n abortControllerRef.current = null;\r\n finalizeReasoning();\r\n chatLogger.debug(\"sendMessage finally\", { agentId: targetAgentId, isStreaming: false });\r\n chatLogger.trace(\"sendMessage end\", { agentId: targetAgentId });\r\n }\r\n },\r\n [agentId, baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId],\r\n );\r\n\r\n const sendMessage = useCallback(\r\n async (contentToSend?: string, overrideOptions?: SendMessageOverride): Promise<boolean> => {\r\n const prompt = (contentToSend ?? input).trim();\r\n if (!prompt || isStreaming) {\r\n chatLogger.trace(\"sendMessage skipped\", {\r\n hasPrompt: !!prompt,\r\n isStreaming,\r\n });\r\n if (isStreaming) {\r\n chatLogger.warn(\"sendMessage dropped while streaming — caller should queue or disable send\", {});\r\n }\r\n return false;\r\n }\r\n return doSend(prompt, messages, overrideOptions);\r\n },\r\n [input, isStreaming, messages, doSend, chatLogger],\r\n );\r\n\r\n const handleInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n chatLogger.trace(\"handleInputChange\", { length: e.target.value.length });\r\n setInput(e.target.value);\r\n },\r\n [chatLogger],\r\n );\r\n\r\n const handleSubmit = useCallback(\r\n (e?: React.FormEvent) => {\r\n if (e) e.preventDefault();\r\n chatLogger.debug(\"handleSubmit\", {});\r\n void sendMessage();\r\n },\r\n [sendMessage, chatLogger],\r\n );\r\n\r\n const reload = useCallback(async (): Promise<boolean> => {\r\n if (messages.length === 0 || isStreaming) {\r\n chatLogger.trace(\"reload skipped\", {\r\n messageCount: messages.length,\r\n isStreaming,\r\n });\r\n return false;\r\n }\r\n let lastUserIndex = -1;\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n if (messages[i].role === \"user\") {\r\n lastUserIndex = i;\r\n break;\r\n }\r\n }\r\n if (lastUserIndex === -1) {\r\n chatLogger.warn(\"reload no user message\", {});\r\n return false;\r\n }\r\n\r\n const lastUserMessage = messages[lastUserIndex];\r\n const truncated = messages.slice(0, lastUserIndex);\r\n chatLogger.info(\"reload\", { messageId: lastUserMessage.id });\r\n chatLogger.debug(\"reload last user\", {\r\n preview: lastUserMessage.content.slice(0, 100),\r\n });\r\n return doSend(lastUserMessage.content, truncated);\r\n }, [isStreaming, messages, doSend, chatLogger]);\r\n\r\n // Unpauses a paused HITL/clarification run. `displayContent` becomes the\r\n // visible user-turn bubble (e.g. \"Approved\", or the typed clarification\r\n // answer) — the server resolves the actual resume value from `resume`\r\n // itself, `displayContent` is only ever used for its own transcript text.\r\n const resumeInterrupt = useCallback(\r\n (resume: PersonaResumeValue, displayContent: string) => {\r\n chatLogger.info(\"resumeInterrupt\", {\r\n kind: (resume as { decisions?: unknown[] }).decisions\r\n ? \"hitl\"\r\n : \"clarification\",\r\n preview: displayContent.slice(0, 50),\r\n });\r\n return sendMessage(displayContent, { resume });\r\n },\r\n [sendMessage, chatLogger],\r\n );\r\n\r\n const dismissPresentedFile = useCallback(() => {\r\n chatLogger.debug(\"dismissPresentedFile\", {});\r\n setPresentedFile(null);\r\n }, [chatLogger]);\r\n\r\n // Manually re-open a workspace file — e.g. a present_file tool card's\r\n // \"Open\" button, after the auto-opened drawer was closed or a different\r\n // file was selected since.\r\n const openWorkspaceFile = useCallback(\r\n (path: string) => {\r\n chatLogger.debug(\"openWorkspaceFile\", { path });\r\n setPresentedFile({\r\n path,\r\n title: path.split(\"/\").pop() || path,\r\n description: \"\",\r\n });\r\n },\r\n [chatLogger],\r\n );\r\n\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n handleInputChange,\r\n handleSubmit,\r\n sendMessage,\r\n isStreaming,\r\n isLoading: isStreaming,\r\n isLoadingHistory,\r\n error,\r\n interrupt,\r\n resumeInterrupt,\r\n files,\r\n todos,\r\n presentedFile,\r\n dismissPresentedFile,\r\n openWorkspaceFile,\r\n sandboxCommands,\r\n stop,\r\n reload,\r\n clear,\r\n startNewChat,\r\n currentThreadId: effectiveThreadId,\r\n isEphemeral: !effectiveThreadId,\r\n setMessages,\r\n loadThreadMessages,\r\n };\r\n}\r\n","/**\r\n * SSE transport for chat streams, with a React Native fallback.\r\n *\r\n * On the web, `fetch` gives a streaming `response.body` and we read it with a\r\n * ReadableStream reader. React Native's `fetch` is the whatwg-fetch polyfill\r\n * over XMLHttpRequest: `response.body` is `undefined`, and the promise only\r\n * settles once the entire response has arrived. That means the check cannot be\r\n * \"call fetch, then see whether body exists\" - by that point the whole stream\r\n * has already been buffered and the chance to stream is gone. The transport has\r\n * to be chosen *before* the request is made.\r\n *\r\n * XMLHttpRequest itself does stream everywhere React Native runs: it appends to\r\n * `responseText` and fires `readyState === 3` (LOADING) on every chunk, which is\r\n * all an SSE consumer needs. So the RN path issues the request over raw XHR and\r\n * hands back the same reader interface the fetch path does, leaving callers\r\n * unaware of which one they got.\r\n */\r\n\r\n/** Minimal reader interface, mirroring the shape of a ReadableStream reader. */\r\nexport interface SSEReader {\r\n /** Resolves with the next decoded chunk, or `{ done: true }` at end of stream. */\r\n read(): Promise<{ done: boolean; value?: string }>;\r\n /** Aborts the underlying request. */\r\n cancel(): void;\r\n}\r\n\r\nexport interface SSEStream {\r\n status: number;\r\n ok: boolean;\r\n getHeader(name: string): string | null;\r\n /** Present only when `ok` is false, so callers can surface the server's message. */\r\n errorText?: string;\r\n reader: SSEReader;\r\n}\r\n\r\nexport interface OpenSSEOptions {\r\n url: string;\r\n headers: Record<string, string>;\r\n body?: string;\r\n method?: \"GET\" | \"POST\";\r\n signal?: AbortSignal;\r\n}\r\n\r\n/**\r\n * Whether `fetch` on this platform yields a streaming body.\r\n *\r\n * `navigator.product === 'ReactNative'` is the long-standing marker React\r\n * Native sets, and is checked rather than feature-detecting `ReadableStream`:\r\n * newer RN versions do expose a global `ReadableStream` while still leaving\r\n * `response.body` undefined, so the presence of the type says nothing about\r\n * whether fetch will populate it.\r\n */\r\nexport function supportsStreamingFetch(): boolean {\r\n if (\r\n typeof navigator !== \"undefined\" &&\r\n (navigator as { product?: string }).product === \"ReactNative\"\r\n ) {\r\n return false;\r\n }\r\n return typeof fetch !== \"undefined\" && typeof ReadableStream !== \"undefined\";\r\n}\r\n\r\n/** Wraps a whatwg ReadableStream reader so it decodes to strings. */\r\nfunction fetchReader(\r\n response: Response,\r\n controller: AbortController,\r\n): SSEReader {\r\n const reader = response.body!.getReader();\r\n const decoder = new TextDecoder(\"utf-8\");\r\n\r\n return {\r\n async read() {\r\n const { done, value } = await reader.read();\r\n if (done) return { done: true };\r\n return { done: false, value: decoder.decode(value, { stream: true }) };\r\n },\r\n cancel() {\r\n controller.abort();\r\n void reader.cancel().catch(() => {});\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Issues the request over XMLHttpRequest and exposes new text as it arrives.\r\n *\r\n * XHR keeps the whole response in `responseText` and only ever appends, so each\r\n * chunk is the slice past what has already been handed out.\r\n */\r\nfunction xhrStream(opts: OpenSSEOptions): Promise<SSEStream> {\r\n return new Promise<SSEStream>((resolveStream, rejectStream) => {\r\n const xhr = new XMLHttpRequest();\r\n const method = opts.method ?? \"POST\";\r\n xhr.open(method, opts.url);\r\n for (const [key, val] of Object.entries(opts.headers))\r\n xhr.setRequestHeader(key, val);\r\n\r\n let consumed = 0;\r\n let finished = false;\r\n let failure: Error | null = null;\r\n // Chunks that arrived before the consumer asked for them, and the pending\r\n // read waiting for one - only one of the two is ever non-empty.\r\n const queue: string[] = [];\r\n let waiting: ((r: { done: boolean; value?: string }) => void) | null = null;\r\n let waitingReject: ((e: Error) => void) | null = null;\r\n let headersResolved = false;\r\n\r\n const pump = () => {\r\n const text = xhr.responseText;\r\n if (text.length <= consumed) return;\r\n const chunk = text.slice(consumed);\r\n consumed = text.length;\r\n\r\n if (waiting) {\r\n const resolve = waiting;\r\n waiting = null;\r\n waitingReject = null;\r\n resolve({ done: false, value: chunk });\r\n } else {\r\n queue.push(chunk);\r\n }\r\n };\r\n\r\n const finish = (err?: Error) => {\r\n if (finished) return;\r\n finished = true;\r\n failure = err ?? null;\r\n if (waiting) {\r\n const resolve = waiting;\r\n const reject = waitingReject;\r\n waiting = null;\r\n waitingReject = null;\r\n if (err && reject) reject(err);\r\n else resolve({ done: true });\r\n }\r\n };\r\n\r\n const reader: SSEReader = {\r\n read() {\r\n if (queue.length > 0) {\r\n return Promise.resolve({ done: false, value: queue.shift() });\r\n }\r\n if (finished) {\r\n return failure\r\n ? Promise.reject(failure)\r\n : Promise.resolve({ done: true });\r\n }\r\n return new Promise((resolve, reject) => {\r\n waiting = resolve;\r\n waitingReject = reject;\r\n });\r\n },\r\n cancel() {\r\n finish();\r\n xhr.abort();\r\n },\r\n };\r\n\r\n // Headers are available from readyState 2, which is what lets a non-2xx\r\n // response be reported without waiting for the body to finish.\r\n const resolveHeaders = () => {\r\n if (headersResolved) return;\r\n headersResolved = true;\r\n const ok = xhr.status >= 200 && xhr.status < 300;\r\n resolveStream({\r\n status: xhr.status,\r\n ok,\r\n getHeader: (name: string) => xhr.getResponseHeader(name),\r\n reader,\r\n });\r\n };\r\n\r\n xhr.onreadystatechange = () => {\r\n if (xhr.readyState === 2) {\r\n resolveHeaders();\r\n } else if (xhr.readyState === 3) {\r\n resolveHeaders();\r\n pump();\r\n } else if (xhr.readyState === 4) {\r\n resolveHeaders();\r\n pump();\r\n finish();\r\n }\r\n };\r\n\r\n xhr.onerror = () => {\r\n const err = new Error(\"Network request failed\");\r\n if (!headersResolved) rejectStream(err);\r\n finish(err);\r\n };\r\n xhr.ontimeout = () => {\r\n const err = new Error(\"Network request timed out\");\r\n if (!headersResolved) rejectStream(err);\r\n finish(err);\r\n };\r\n\r\n if (opts.signal) {\r\n if (opts.signal.aborted) {\r\n xhr.abort();\r\n finish();\r\n } else {\r\n opts.signal.addEventListener(\"abort\", () => {\r\n finish();\r\n xhr.abort();\r\n });\r\n }\r\n }\r\n\r\n xhr.send(method === \"GET\" ? null : (opts.body ?? null));\r\n });\r\n}\r\n\r\n/**\r\n * Opens an SSE stream, using whichever transport this platform can stream over.\r\n */\r\nexport async function openSSEStream(opts: OpenSSEOptions): Promise<SSEStream> {\r\n if (!supportsStreamingFetch()) {\r\n return xhrStream(opts);\r\n }\r\n\r\n const controller = new AbortController();\r\n if (opts.signal) {\r\n if (opts.signal.aborted) controller.abort();\r\n else opts.signal.addEventListener(\"abort\", () => controller.abort());\r\n }\r\n\r\n const method = opts.method ?? \"POST\";\r\n const response = await fetch(opts.url, {\r\n method,\r\n headers: opts.headers,\r\n body: method === \"GET\" ? undefined : opts.body,\r\n signal: controller.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => \"Stream failed\");\r\n return {\r\n status: response.status,\r\n ok: false,\r\n errorText,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: {\r\n read: async () => ({ done: true }),\r\n cancel: () => controller.abort(),\r\n },\r\n };\r\n }\r\n\r\n if (!response.body) {\r\n // A streaming-capable platform that still gave no body - fall back to the\r\n // buffered text rather than failing outright.\r\n const text = await response.text();\r\n let handed = false;\r\n return {\r\n status: response.status,\r\n ok: true,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: {\r\n read: async () =>\r\n handed\r\n ? { done: true }\r\n : ((handed = true), { done: false, value: text }),\r\n cancel: () => controller.abort(),\r\n },\r\n };\r\n }\r\n\r\n return {\r\n status: response.status,\r\n ok: true,\r\n getHeader: (name: string) => response.headers.get(name),\r\n reader: fetchReader(response, controller),\r\n };\r\n}\r\n","// Shared parsing/normalization helpers for hooks that consume the AG-UI\n// event stream and thread-history payload — used by both useChat and\n// useArchitectChat, since both talk to structurally identical backend\n// runtimes (agui.service.js's runAgentAsAguiEvents drives both).\n\nimport type {\n PersonaInterrupt,\n PersonaPresentedFile,\n PersonaSubagentActivityEntry,\n PersonaWorkspaceFile,\n} from \"../types.js\";\n\n// A failed tool call's TOOL_CALL_RESULT content is a JSON envelope\n// (`{status:'error',message}`, see aguiTranslator.js's buildToolErrorContent)\n// rather than a separate boolean field on the event itself.\nexport function isErrorToolContent(content: string): boolean {\n if (typeof content !== \"string\" || !content.trim().startsWith(\"{\"))\n return false;\n try {\n return JSON.parse(content)?.status === \"error\";\n } catch {\n return false;\n }\n}\n\n// Persisted subagent trace item shape (agent-backend's foldSubagentEvent/\n// subagentTrace.js) — already folded/paired server-side for compact storage,\n// DIFFERENT from the raw per-event `PersonaSubagentActivityEntry` shape the\n// live SSE stream sends (kind: 'text'|'tool_start'|'tool_result'). Reloading\n// a thread previously never read `data.subagentTraces` at all — a completed\n// subagent's activity (its own text/tool timeline) was silently dropped on\n// reload even though the backend already persists and returns it, keyed by\n// the owning `task` tool call's toolCallId (see agui.controller.js's\n// `subagentTraces[callId]`, matching `PersonaToolCall.toolCallId` exactly).\nexport type PersistedSubagentTraceItem =\n | { type: \"text\"; text: string }\n | {\n type: \"tool\";\n name: string;\n argsText: string;\n resultText: string;\n status: \"running\" | \"completed\";\n };\n\n// Re-expands the folded/paired persisted shape back into the raw kind-based\n// entries `PersonaSubagentActivityEntry` (and everything downstream that\n// consumes it — buildSubagentTimeline, the live-preview row, the activity\n// dialog) already knows how to render, so no sdk/ui changes are needed.\nexport function persistedTraceToActivityEntries(\n items: PersistedSubagentTraceItem[],\n): PersonaSubagentActivityEntry[] {\n const entries: PersonaSubagentActivityEntry[] = [];\n for (const item of items) {\n if (item.type === \"text\") {\n if (item.text) entries.push({ kind: \"text\", delta: item.text });\n } else {\n entries.push({\n kind: \"tool_start\",\n toolName: item.name,\n args: item.argsText,\n });\n if (item.status === \"completed\") {\n entries.push({\n kind: \"tool_result\",\n toolName: item.name,\n result: item.resultText,\n });\n }\n }\n }\n return entries;\n}\n\n// present_file's result is `{status:'success', filePath, title, description}`\n// (see present.tool.js) — a signal to highlight that path in the workspace\n// files panel, not something meant to render as a generic tool-result blob.\nexport function parsePresentedFile(content: string): PersonaPresentedFile | null {\n try {\n const parsed = JSON.parse(content);\n if (parsed?.status !== \"success\" || typeof parsed.filePath !== \"string\")\n return null;\n return {\n path: parsed.filePath,\n title: typeof parsed.title === \"string\" ? parsed.title : parsed.filePath,\n description:\n typeof parsed.description === \"string\" ? parsed.description : \"\",\n };\n } catch {\n return null;\n }\n}\n\n// buildFilesTodosSnapshot (aguiTranslator.js) emits snake_case\n// created_at/modified_at on the wire — both from the live STATE_SNAPSHOT\n// event and from a reloaded thread's persisted state (checkpoint.service.js\n// runs the same function). Normalize to the SDK's usual camelCase shape.\nexport function normalizeWorkspaceFiles(\n raw: Record<\n string,\n {\n content: string;\n size: number;\n created_at: string | null;\n modified_at: string | null;\n }\n >,\n): Record<string, PersonaWorkspaceFile> {\n const normalized: Record<string, PersonaWorkspaceFile> = {};\n for (const [path, file] of Object.entries(raw || {})) {\n normalized[path] = {\n content: file.content,\n size: file.size,\n createdAt: file.created_at,\n modifiedAt: file.modified_at,\n };\n }\n return normalized;\n}\n\n// checkpointService.getMessages() wraps a paused thread's interrupt as\n// `{ kind, value }` (see checkpoint.service.js) — the same envelope shape\n// the live hitl_request/clarification_request CUSTOM events carry, just\n// nested one level deeper. Flatten both into the same PersonaInterrupt shape.\nexport function normalizePendingInterrupt(pending: unknown): PersonaInterrupt | null {\n if (!pending || typeof pending !== \"object\") return null;\n const p = pending as { kind?: string; value?: Record<string, unknown> };\n if (p.kind === \"hitl\") {\n return {\n kind: \"hitl\",\n actionRequests: (p.value?.actionRequests ?? []) as Extract<\n PersonaInterrupt,\n { kind: \"hitl\" }\n >[\"actionRequests\"],\n reviewConfigs: (p.value?.reviewConfigs ?? []) as unknown[],\n };\n }\n if (p.kind === \"clarification\") {\n return {\n kind: \"clarification\",\n questions: (p.value?.questions ?? []) as Extract<\n PersonaInterrupt,\n { kind: \"clarification\" }\n >[\"questions\"],\n };\n }\n return null;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport { openSSEStream } from \"../streaming.js\";\nimport type {\n PersonaInterrupt,\n PersonaMessage,\n PersonaPresentedFile,\n PersonaResumeValue,\n PersonaStreamingEvent,\n PersonaSubagentActivityEntry,\n PersonaTodo,\n PersonaToolCall,\n PersonaWorkspaceFile,\n SendArchitectMessageOverride,\n UseArchitectChatOptions,\n} from \"../types.js\";\nimport {\n isErrorToolContent,\n normalizePendingInterrupt,\n normalizeWorkspaceFiles,\n parsePresentedFile,\n persistedTraceToActivityEntries,\n type PersistedSubagentTraceItem,\n} from \"./streamEventHelpers.js\";\n\n/**\n * The Developer Platform Architect's own reserved Agent id\n * (`DEVELOPER_ARCHITECT_AGENT_ID` in agent-backend/src/modules/agents/\n * architectConstants.js) — it isn't a row in the Agent collection, but the\n * backend's `POST /api/v1/developer/threads` special-cases exactly this id\n * past its usual Agent-existence check (see developerThread.controller.js's\n * `assertAgentAccessible`), so a named Architect Thread can be created the\n * same way as for a real Agent. Kept in sync with that backend constant —\n * update both together if it ever changes.\n */\nexport const ARCHITECT_AGENT_ID = \"000000000000000000000002\";\n\n/**\n * Runs the Agent Architect co-pilot — a conversational tool-calling agent\n * that creates/edits the caller's own Agents (`manage_agent`, `manage_skill`,\n * etc.), reached over the runtime's `POST /architect` route (see\n * `@personaai/runtime`'s `routes/architect.ts`). Structurally a trimmed\n * `useChat`: same streaming/interrupt/reload/thread-resume mechanics, but\n * with no `agentId` to pass (the Architect is a single fixed target) and no\n * `voice`/`sandboxCommands` (the Architect has no voice mode and no\n * `execute` tool).\n *\n * `threadId` resume only has an effect when the underlying credential\n * asserts an external user — a bare Project credential has no Subject for a\n * Thread to belong to, so the backend silently keeps its single\n * deterministic per-Project conversation either way (see\n * `developerArchitect.controller.js`'s doc comment).\n */\nexport function useArchitectChat(options: UseArchitectChatOptions = {}) {\n const { fetchWithAuth, baseUrl, getAuthToken, logger } = usePersonaContext();\n const chatLogger = useMemo(() => logger.child(\"architect\"), [logger]);\n const threadId = options.threadId;\n // Ephemeral/fake thread support: when threadId is null/undefined the chat is\n // in \"new chat\" mode — no history fetch, no thread creation until first send.\n // The real id is minted lazily inside doSend and surfaced via\n // options.onThreadCreated so the host can sync its sidebar state.\n const [internalThreadId, setInternalThreadId] = useState<string | undefined>(undefined);\n const effectiveThreadId = threadId ?? internalThreadId;\n // Keep internal in sync when host drives threadId (e.g. after mint)\n useEffect(() => {\n if (threadId !== undefined) setInternalThreadId(threadId);\n }, [threadId]);\n\n // Log hook initialization at most once per mount (debug/info visible, trace for details)\n // This runs during render, so guard with a ref to avoid spam on every re-render\n const didLogInitRef = useRef(false);\n if (!didLogInitRef.current) {\n didLogInitRef.current = true;\n chatLogger.debug(\"useArchitectChat init\", {\n threadId,\n hasInitialMessages: !!options.initialMessages?.length,\n });\n chatLogger.trace(\"useArchitectChat options\", {\n threadId,\n initialMessageCount: options.initialMessages?.length ?? 0,\n });\n }\n\n const [messages, setMessages] = useState<PersonaMessage[]>(\n options.initialMessages || [],\n );\n const [input, setInput] = useState(\"\");\n const [isStreaming, setIsStreaming] = useState(false);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [interrupt, setInterrupt] = useState<PersonaInterrupt | null>(null);\n const [files, setFiles] = useState<Record<string, PersonaWorkspaceFile>>({});\n const [todos, setTodos] = useState<PersonaTodo[]>([]);\n const [presentedFile, setPresentedFile] =\n useState<PersonaPresentedFile | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n chatLogger.info(\"stop streaming\", {});\n chatLogger.debug(\"abort controller\", {\n hasController: !!abortControllerRef.current,\n });\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n chatLogger.debug(\"streaming stopped\");\n } else {\n chatLogger.trace(\"stop called — no active stream\");\n }\n }, [chatLogger]);\n\n const clear = useCallback(() => {\n chatLogger.info(\"clear chat\", { messageCount: messages.length });\n chatLogger.debug(\"clear\", { messageCount: messages.length });\n stop();\n setMessages([]);\n setError(null);\n setInterrupt(null);\n setFiles({});\n setTodos([]);\n setPresentedFile(null);\n loadedThreadIdRef.current = undefined;\n }, [stop, chatLogger, messages.length]);\n\n const startNewChat = useCallback(() => {\n chatLogger.info(\"startNewChat — entering ephemeral mode\");\n stop();\n setMessages([]);\n setError(null);\n setInterrupt(null);\n setFiles({});\n setTodos([]);\n setPresentedFile(null);\n setInput(\"\");\n loadedThreadIdRef.current = undefined;\n setInternalThreadId(undefined);\n }, [stop, chatLogger]);\n\n const loadThreadMessages = useCallback(\n async (id: string) => {\n chatLogger.debug(\"loadThreadMessages start\", { threadId: id });\n chatLogger.trace(\"loadThreadMessages\", { threadId: id });\n setIsLoadingHistory(true);\n setError(null);\n try {\n const res = await fetchWithAuth(`/threads/${id}/messages`);\n if (!res.ok)\n throw new Error(`Failed to load thread history: ${res.statusText}`);\n const body = await res.json();\n const data = body?.data ?? body;\n const raw = (data?.messages ?? []) as Array<{\n id?: string;\n role: PersonaMessage[\"role\"];\n content: string;\n toolCalls?: PersonaToolCall[];\n }>;\n const subagentTraces = (data?.subagentTraces ?? {}) as Record<\n string,\n PersistedSubagentTraceItem[]\n >;\n const loaded: PersonaMessage[] = raw.map((m, i) => ({\n id: m.id || `history-${id}-${i}`,\n role: m.role,\n content: m.content,\n createdAt: new Date(),\n toolCalls: m.toolCalls?.map((tc) => {\n const trace = subagentTraces[tc.toolCallId];\n return Array.isArray(trace) && trace.length > 0\n ? {\n ...tc,\n subagentActivity: persistedTraceToActivityEntries(trace),\n }\n : tc;\n }),\n }));\n setMessages(loaded);\n // Re-show the approval/clarification card on reload if this thread\n // is currently paused — otherwise it wouldn't reappear until the\n // next live stream re-surfaces it.\n setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));\n // Restore the workspace files/todos this thread already had (same\n // cleaned shape checkpoint.service.js now derives via\n // buildFilesTodosSnapshot, matching the live STATE_SNAPSHOT event).\n setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));\n setTodos((data?.state?.todos ?? []) as PersonaTodo[]);\n loadedThreadIdRef.current = id;\n chatLogger.info(\"loadThreadMessages succeeded\", {\n threadId: id,\n messageCount: loaded.length,\n });\n chatLogger.debug(\"loadThreadMessages completed\", {\n threadId: id,\n messageCount: loaded.length,\n });\n return loaded;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n chatLogger.warn(\"loadThreadMessages failed\", {\n threadId: id,\n error: errorObj.message,\n });\n chatLogger.error(\"loadThreadMessages error\", {\n threadId: id,\n error: errorObj.message,\n });\n setError(errorObj);\n if (loadedThreadIdRef.current === id) loadedThreadIdRef.current = undefined;\n return [];\n } finally {\n setIsLoadingHistory(false);\n chatLogger.trace(\"loadThreadMessages end\", { threadId: id });\n }\n },\n [fetchWithAuth, chatLogger],\n );\n\n // Auto-load history the first time a thread with no in-memory messages is\n // selected (switching threads in the sidebar). Skipped for a thread whose\n // messages already live in state — e.g. one just created by handleSend,\n // which sets its placeholder messages in the same render batch as the\n // threadId change, so `messages` there is never empty at effect time.\n useEffect(() => {\n if (!effectiveThreadId || isStreaming) {\n chatLogger.trace(\"auto-load skipped\", { threadId: effectiveThreadId, isStreaming });\n return;\n }\n if (loadedThreadIdRef.current === effectiveThreadId) {\n chatLogger.trace(\"auto-load already loaded\", { threadId: effectiveThreadId });\n return;\n }\n if (messages.length > 0) {\n chatLogger.trace(\"auto-load has messages\", {\n threadId: effectiveThreadId,\n count: messages.length,\n });\n return;\n }\n chatLogger.info(\"auto-load thread history\", { threadId: effectiveThreadId });\n chatLogger.debug(\"loadThreadMessages trigger\", { threadId: effectiveThreadId });\n void loadThreadMessages(effectiveThreadId);\n }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);\n\n // Internal stream executor — shared by sendMessage and reload so reload can\n // supply a truncated base (mirrors useChat's doSend). Caller has already\n // validated prompt/isStreaming.\n const doSend = useCallback(\n async (\n prompt: string,\n baseMessages: PersonaMessage[],\n overrideOptions?: SendArchitectMessageOverride,\n ): Promise<boolean> => {\n chatLogger.debug(\"sendMessage start\", {\n promptPreview: prompt.slice(0, 100),\n threadId: effectiveThreadId ?? (overrideOptions?.threadId as string | undefined),\n hasResume: !!overrideOptions?.resume,\n messageCount: baseMessages.length,\n });\n chatLogger.trace(\"sendMessage details\", {\n promptPreview: prompt.slice(0, 200),\n hasResume: !!overrideOptions?.resume,\n });\n\n const userMessage: PersonaMessage = {\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n role: \"user\",\n content: prompt,\n createdAt: new Date(),\n };\n\n const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const placeholderAssistant: PersonaMessage = {\n id: assistantMessageId,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date(),\n isStreaming: true,\n toolCalls: [],\n };\n\n const nextMessages = [...baseMessages, userMessage];\n setMessages([...nextMessages, placeholderAssistant]);\n setInput(\"\");\n setIsStreaming(true);\n setError(null);\n setInterrupt(null);\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n const finalizeReasoning = () => {\n setMessages((prev) =>\n prev.map((m) => (m.role === \"reasoning\" && m.isStreaming ? { ...m, isStreaming: false } : m)),\n );\n };\n\n try {\n const payloadMessages = nextMessages\n .filter((m) => m.role !== \"reasoning\")\n .map((m) => ({\n role: m.role === \"assistant\" ? (\"assistant\" as const) : (\"user\" as const),\n content: m.content,\n }));\n\n let resolvedThreadId: string | undefined = (await (overrideOptions?.threadId as string | undefined)) ?? effectiveThreadId;\n if (!resolvedThreadId) {\n chatLogger.info(\"minting real thread for ephemeral architect chat\", {});\n const createRes = await fetchWithAuth(\"/threads\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ agentId: ARCHITECT_AGENT_ID }),\n });\n if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);\n const createBody = await createRes.json();\n const created = (createBody?.data ?? createBody) as { _id?: string; id?: string };\n resolvedThreadId = created._id ?? created.id;\n if (!resolvedThreadId) throw new Error(\"Thread creation returned no id\");\n setInternalThreadId(resolvedThreadId);\n loadedThreadIdRef.current = resolvedThreadId;\n options.onThreadCreated?.(resolvedThreadId);\n chatLogger.info(\"ephemeral architect chat minted\", { threadId: resolvedThreadId });\n }\n chatLogger.trace(\"resolved threadId\", { threadId: resolvedThreadId });\n\n const token = getAuthToken ? await getAuthToken() : null;\n chatLogger.debug(\"opening SSE stream\", {\n hasToken: !!token,\n hasThreadId: !!resolvedThreadId,\n });\n const stream = await openSSEStream({\n url: `${baseUrl}/architect`,\n headers: {\n \"Content-Type\": \"application/json\",\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({\n messages: payloadMessages,\n threadId: resolvedThreadId,\n resume: overrideOptions?.resume,\n }),\n signal: controller.signal,\n });\n\n if (!stream.ok) {\n chatLogger.warn(\"SSE stream not ok\", { status: stream.status, errorText: stream.errorText });\n chatLogger.error(\"architect stream failed\", { status: stream.status, error: stream.errorText });\n throw new Error(`Architect error (${stream.status}): ${stream.errorText ?? \"Stream failed\"}`);\n }\n chatLogger.debug(\"SSE stream opened\", { status: stream.status });\n chatLogger.info(\"architect stream started\", { threadId: resolvedThreadId });\n\n const reader = stream.reader;\n let buffer = \"\";\n let accumulatedText = \"\";\n const toolCallsMap = new Map<string, PersonaToolCall>();\n let streamSeq = 0;\n let activeReasoningId: string | null = null;\n const reasoningById = new Map<string, { content: string }>();\n\n const patchAssistant = (patch: Partial<PersonaMessage>) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch } : msg,\n ),\n );\n };\n\n const insertReasoningMessage = (id: string, seq: number) => {\n const msg: PersonaMessage = { id, role: \"reasoning\", content: \"\", createdAt: new Date(), isStreaming: true, seq };\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === assistantMessageId);\n if (idx === -1) return [...prev, msg];\n const next = [...prev];\n next.splice(idx, 0, msg);\n return next;\n });\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += value ?? \"\";\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith(\"data:\")) continue;\n const raw = trimmed.replace(/^data:\\s*/, \"\");\n if (raw === \"[DONE]\") break;\n try {\n const event = JSON.parse(raw) as PersonaStreamingEvent;\n chatLogger.trace(\"stream event\", { type: event.type, event });\n options.onEvent?.(event);\n if (event.type === \"TEXT_MESSAGE_CHUNK\" && event.delta) {\n chatLogger.debug(\"text chunk\", { deltaLength: event.delta.length });\n accumulatedText += event.delta;\n patchAssistant({ content: accumulatedText, isStreaming: true });\n } else if (event.type === \"TOOL_CALL_CHUNK\" && event.toolCallId) {\n chatLogger.debug(\"tool call chunk\", { toolCallId: event.toolCallId, toolCallName: event.toolCallName });\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.args = (existing.args || \"\") + (event.delta || \"\");\n } else {\n toolCallsMap.set(event.toolCallId, {\n toolCallId: event.toolCallId,\n toolName: event.toolCallName || \"\",\n args: event.delta || \"\",\n seq: streamSeq++,\n });\n }\n patchAssistant({});\n } else if (event.type === \"TOOL_CALL_RESULT\") {\n chatLogger.debug(\"tool call result\", { toolCallId: event.toolCallId });\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.result = event.content;\n existing.isError = isErrorToolContent(event.content);\n if (existing.isError) chatLogger.warn(\"tool call error\", { toolCallId: event.toolCallId });\n if (existing.toolName === \"present_file\" && !existing.isError) {\n const presented = parsePresentedFile(event.content);\n if (presented) {\n chatLogger.info(\"present_file\", { path: presented.path });\n setPresentedFile(presented);\n }\n }\n patchAssistant({});\n }\n } else if (event.type === \"STATE_SNAPSHOT\") {\n chatLogger.debug(\"state snapshot\", {\n fileCount: Object.keys(event.snapshot.files ?? {}).length,\n todoCount: event.snapshot.todos?.length ?? 0,\n });\n setFiles(normalizeWorkspaceFiles(event.snapshot.files ?? {}));\n setTodos(event.snapshot.todos ?? []);\n } else if (event.type === \"REASONING_MESSAGE_START\" && event.messageId) {\n chatLogger.debug(\"reasoning start\", { messageId: event.messageId });\n activeReasoningId = event.messageId;\n reasoningById.set(event.messageId, { content: \"\" });\n insertReasoningMessage(event.messageId, streamSeq++);\n } else if (event.type === \"REASONING_MESSAGE_CONTENT\") {\n let rid: string = event.messageId || activeReasoningId || \"\";\n if (!rid || !reasoningById.has(rid)) {\n rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n activeReasoningId = rid;\n reasoningById.set(rid, { content: \"\" });\n insertReasoningMessage(rid, streamSeq++);\n chatLogger.debug(\"reasoning lazy start\", { messageId: rid });\n }\n const entry = reasoningById.get(rid)!;\n entry.content += event.delta;\n chatLogger.trace(\"reasoning content\", { messageId: rid, deltaLength: event.delta?.length ?? 0 });\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m)));\n } else if (event.type === \"REASONING_END\") {\n chatLogger.debug(\"reasoning end\", { messageId: activeReasoningId });\n const rid = activeReasoningId;\n activeReasoningId = null;\n if (rid) {\n setMessages((prev) => prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m)));\n }\n } else if (event.type === \"CUSTOM\") {\n chatLogger.debug(\"custom event\", { name: event.name });\n if (event.name === \"hitl_request\") {\n const value = event.value as Extract<PersonaInterrupt, { kind: \"hitl\" }>;\n chatLogger.info(\"hitl interrupt\", { actionCount: value.actionRequests?.length ?? 0 });\n setInterrupt({ kind: \"hitl\", actionRequests: value.actionRequests, reviewConfigs: value.reviewConfigs });\n } else if (event.name === \"clarification_request\") {\n const value = event.value as Extract<PersonaInterrupt, { kind: \"clarification\" }>;\n chatLogger.info(\"clarification interrupt\", { questionCount: value.questions?.length ?? 0 });\n setInterrupt({ kind: \"clarification\", questions: value.questions });\n } else if (event.name === \"subagent_activity\") {\n const { toolCallId, ...entry } = event.value as { toolCallId: string } & PersonaSubagentActivityEntry;\n chatLogger.trace(\"subagent activity\", { toolCallId, kind: entry.kind });\n const existing = toolCallsMap.get(toolCallId);\n if (existing) {\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\n patchAssistant({});\n }\n } else if (event.name === \"mcp_app\") {\n const val = event.value as { toolCallId?: string; resourceUri?: string; mcpId?: string } | undefined;\n if (val?.toolCallId && val?.resourceUri && val?.mcpId) {\n const existing = toolCallsMap.get(val.toolCallId);\n if (existing) {\n existing.mcpApp = { resourceUri: val.resourceUri, mcpId: val.mcpId };\n patchAssistant({});\n }\n }\n }\n } else if ((event as { type: string; title?: string }).type === \"title\") {\n const title = (event as { title?: string }).title;\n if (typeof title === \"string\" && title.trim()) {\n chatLogger.info(\"auto title\", { title });\n options.onTitle?.(title);\n }\n } else if (event.type === \"RUN_ERROR\") {\n chatLogger.warn(\"run error\", { message: event.message, code: event.code });\n chatLogger.error(\"stream run error\", { code: event.code, message: event.message });\n throw new Error(event.message || \"Stream error from agent\");\n } else {\n chatLogger.trace(\"unhandled event\", { type: event.type });\n }\n } catch (e) {\n if (e instanceof Error && e.message.startsWith(\"Stream error\")) throw e;\n chatLogger.warn(\"event parse error\", { raw: raw.slice(0, 200), error: e instanceof Error ? e.message : String(e) });\n }\n }\n }\n\n const finalMessage: PersonaMessage = {\n id: assistantMessageId,\n role: \"assistant\",\n content: accumulatedText,\n createdAt: new Date(),\n isStreaming: false,\n toolCalls: Array.from(toolCallsMap.values()),\n };\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg)));\n chatLogger.info(\"sendMessage succeeded\", { textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });\n chatLogger.debug(\"sendMessage completed\", { textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });\n options.onFinish?.(finalMessage);\n return true;\n } catch (err) {\n if (controller.signal.aborted) {\n chatLogger.info(\"sendMessage aborted\", {});\n chatLogger.debug(\"stream aborted\", {});\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg)));\n return false;\n }\n const errorObj = err instanceof Error ? err : new Error(String(err));\n chatLogger.warn(\"sendMessage failed\", { error: errorObj.message });\n chatLogger.error(\"sendMessage error\", { error: errorObj.message });\n setError(errorObj);\n options.onError?.(errorObj);\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId\n ? { ...msg, content: msg.content || `⚠️ Error: ${errorObj.message || \"Failed to get response.\"}`, isStreaming: false }\n : msg,\n ),\n );\n return false;\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n finalizeReasoning();\n chatLogger.debug(\"sendMessage finally\", { isStreaming: false });\n chatLogger.trace(\"sendMessage end\", {});\n }\n },\n [baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId],\n );\n\n const sendMessage = useCallback(\n async (contentToSend?: string, overrideOptions?: SendArchitectMessageOverride): Promise<boolean> => {\n const prompt = (contentToSend ?? input).trim();\n if (!prompt || isStreaming) {\n chatLogger.trace(\"sendMessage skipped\", {\n hasPrompt: !!prompt,\n isStreaming,\n });\n if (isStreaming) {\n chatLogger.warn(\"sendMessage dropped while streaming — caller should queue or disable send\", {});\n }\n return false;\n }\n return doSend(prompt, messages, overrideOptions);\n },\n [input, isStreaming, messages, doSend, chatLogger],\n );\n\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n chatLogger.trace(\"handleInputChange\", { length: e.target.value.length });\n setInput(e.target.value);\n },\n [chatLogger],\n );\n\n const handleSubmit = useCallback(\n (e?: React.FormEvent) => {\n if (e) e.preventDefault();\n chatLogger.debug(\"handleSubmit\", {});\n void sendMessage();\n },\n [sendMessage, chatLogger],\n );\n\n const reload = useCallback(async (): Promise<boolean> => {\n if (messages.length === 0 || isStreaming) {\n chatLogger.trace(\"reload skipped\", {\n messageCount: messages.length,\n isStreaming,\n });\n return false;\n }\n let lastUserIndex = -1;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === \"user\") {\n lastUserIndex = i;\n break;\n }\n }\n if (lastUserIndex === -1) {\n chatLogger.warn(\"reload no user message\", {});\n return false;\n }\n\n const lastUserMessage = messages[lastUserIndex];\n const truncated = messages.slice(0, lastUserIndex);\n chatLogger.info(\"reload\", { messageId: lastUserMessage.id });\n chatLogger.debug(\"reload last user\", {\n preview: lastUserMessage.content.slice(0, 100),\n });\n return doSend(lastUserMessage.content, truncated);\n }, [isStreaming, messages, doSend, chatLogger]);\n\n // Unpauses a paused HITL/clarification run. `displayContent` becomes the\n // visible user-turn bubble (e.g. \"Approved\", or the typed clarification\n // answer) — the server resolves the actual resume value from `resume`\n // itself, `displayContent` is only ever used for its own transcript text.\n const resumeInterrupt = useCallback(\n (resume: PersonaResumeValue, displayContent: string) => {\n chatLogger.info(\"resumeInterrupt\", {\n kind: (resume as { decisions?: unknown[] }).decisions\n ? \"hitl\"\n : \"clarification\",\n preview: displayContent.slice(0, 50),\n });\n return sendMessage(displayContent, { resume });\n },\n [sendMessage, chatLogger],\n );\n\n const dismissPresentedFile = useCallback(() => {\n chatLogger.debug(\"dismissPresentedFile\", {});\n setPresentedFile(null);\n }, [chatLogger]);\n\n // Manually re-open a workspace file — e.g. a present_file tool card's\n // \"Open\" button, after the auto-opened drawer was closed or a different\n // file was selected since.\n const openWorkspaceFile = useCallback(\n (path: string) => {\n chatLogger.debug(\"openWorkspaceFile\", { path });\n setPresentedFile({\n path,\n title: path.split(\"/\").pop() || path,\n description: \"\",\n });\n },\n [chatLogger],\n );\n\n return {\n messages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n sendMessage,\n isStreaming,\n isLoading: isStreaming,\n isLoadingHistory,\n error,\n interrupt,\n resumeInterrupt,\n files,\n todos,\n presentedFile,\n dismissPresentedFile,\n openWorkspaceFile,\n stop,\n reload,\n clear,\n startNewChat,\n currentThreadId: effectiveThreadId,\n isEphemeral: !effectiveThreadId,\n setMessages,\n loadThreadMessages,\n };\n}\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport type { PersonaMemoryFile, PersonaMemoryList } from \"../types.js\";\r\n\r\nexport function useMemory(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [memory, setMemory] = useState<PersonaMemoryList>({\r\n userFiles: [],\r\n agentMemories: [],\r\n });\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchMemory = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/memory\");\r\n if (!res.ok) {\r\n throw new Error(`Failed to fetch memory: ${res.statusText}`);\r\n }\r\n const data = (await res.json()) as PersonaMemoryList;\r\n setMemory(data);\r\n return data;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return { userFiles: [], agentMemories: [] };\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n const getFile = useCallback(\r\n async (params: {\r\n path: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const query = new URLSearchParams({ path: params.path });\r\n if (params.scope) query.set(\"scope\", params.scope);\r\n if (params.agentId) query.set(\"agentId\", params.agentId);\r\n\r\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`);\r\n if (!res.ok)\r\n throw new Error(`Failed to get memory file: ${res.statusText}`);\r\n return (await res.json()) as PersonaMemoryFile;\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const writeFile = useCallback(\r\n async (params: {\r\n path: string;\r\n content: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const res = await fetchWithAuth(\"/memory/file\", {\r\n method: \"PUT\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify(params),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to write memory file: ${res.statusText}`);\r\n const updated = (await res.json()) as PersonaMemoryFile;\r\n void fetchMemory();\r\n return updated;\r\n },\r\n [fetchWithAuth, fetchMemory],\r\n );\r\n\r\n const deleteFile = useCallback(\r\n async (params: {\r\n path: string;\r\n scope?: \"user\" | \"agent\";\r\n agentId?: string;\r\n }) => {\r\n const query = new URLSearchParams({ path: params.path });\r\n if (params.scope) query.set(\"scope\", params.scope);\r\n if (params.agentId) query.set(\"agentId\", params.agentId);\r\n\r\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`, {\r\n method: \"DELETE\",\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to delete memory file: ${res.statusText}`);\r\n void fetchMemory();\r\n },\r\n [fetchWithAuth, fetchMemory],\r\n );\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchMemory();\r\n }\r\n }, [autoFetch, fetchMemory]);\r\n\r\n return {\r\n memory,\r\n isLoading,\r\n error,\r\n refetch: fetchMemory,\r\n getFile,\r\n writeFile,\r\n deleteFile,\r\n };\r\n}\r\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport type { PersonaThread } from \"../types.js\";\n\nexport function useThreads(autoFetch = true) {\n const { fetchWithAuth, defaultAgentId } = usePersonaContext();\n const [threads, setThreads] = useState<PersonaThread[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchThreads = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth(\"/threads\");\n if (!res.ok) throw new Error(`Failed to list threads: ${res.statusText}`);\n const data = await res.json();\n // Real shape is { items, pagination }. Bare array / `.data` / `.threads`\n // are defensive fallbacks for other deployments, not the actual contract.\n const items: PersonaThread[] = Array.isArray(data)\n ? data\n : data?.items ||\n data?.threads ||\n (Array.isArray(data?.data) ? data.data : undefined) ||\n [];\n setThreads(items);\n return items;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth]);\n\n const createThread = useCallback(\n async (agentId?: string) => {\n const targetAgentId = agentId || defaultAgentId;\n const res = await fetchWithAuth(\"/threads\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ agentId: targetAgentId }),\n });\n if (!res.ok)\n throw new Error(`Failed to create thread: ${res.statusText}`);\n const data = await res.json();\n const created = (data?.data ?? data) as PersonaThread;\n void fetchThreads();\n return created;\n },\n [fetchWithAuth, defaultAgentId, fetchThreads],\n );\n\n const deleteThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}`, {\n method: \"DELETE\",\n });\n if (!res.ok)\n throw new Error(`Failed to delete thread: ${res.statusText}`);\n setThreads((prev) => prev.filter((t) => t._id !== threadId));\n },\n [fetchWithAuth],\n );\n\n // Best-effort batch delete — no not-found id aborts the rest. Up to 100\n // ids per call, matching the server's own limit.\n const bulkDeleteThreads = useCallback(\n async (threadIds: string[]) => {\n const res = await fetchWithAuth(\"/threads/bulk-delete\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ ids: threadIds }),\n });\n if (!res.ok)\n throw new Error(`Failed to bulk-delete threads: ${res.statusText}`);\n const data = await res.json();\n const result = (data?.data ?? data) as {\n deleted: string[];\n failed: Array<{ id: string; reason: string }>;\n };\n const deletedSet = new Set(result.deleted);\n setThreads((prev) => prev.filter((t) => !deletedSet.has(t._id)));\n return result;\n },\n [fetchWithAuth],\n );\n\n // Convenience wrapper: there is no server-side \"delete everything\"\n // endpoint, only bulk-delete-by-id — so this bulk-deletes every\n // currently-loaded thread (up to 100 per call, chunked if there are more).\n const deleteAllThreads = useCallback(async () => {\n const ids = threads.map((t) => t._id);\n for (let i = 0; i < ids.length; i += 100) {\n await bulkDeleteThreads(ids.slice(i, i + 100));\n }\n }, [threads, bulkDeleteThreads]);\n\n // General-purpose update — { title?, isArchived? }.\n const updateThread = useCallback(\n async (\n threadId: string,\n input: { title?: string; isArchived?: boolean },\n ) => {\n const res = await fetchWithAuth(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input),\n });\n if (!res.ok)\n throw new Error(`Failed to update thread: ${res.statusText}`);\n const data = await res.json();\n const updated = (data?.data ?? data) as PersonaThread;\n setThreads((prev) =>\n prev.map((t) => (t._id === threadId ? { ...t, ...updated } : t)),\n );\n return updated;\n },\n [fetchWithAuth],\n );\n\n const renameThread = useCallback(\n (threadId: string, title: string) => updateThread(threadId, { title }),\n [updateThread],\n );\n\n // Clears a thread's conversation content in place (message history, files/\n // todos, subagent traces) while keeping the same thread id/title — unlike\n // deleteThread, nothing about the thread's identity changes, so callers\n // can reuse it as a fresh conversation instead of creating a new one.\n const resetThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}/reset`, {\n method: \"POST\",\n });\n if (!res.ok) throw new Error(`Failed to reset thread: ${res.statusText}`);\n const data = await res.json();\n const reset = (data?.data ?? data) as PersonaThread;\n setThreads((prev) =>\n prev.map((t) => (t._id === threadId ? { ...t, ...reset } : t)),\n );\n return reset;\n },\n [fetchWithAuth],\n );\n\n const getThread = useCallback(\n async (threadId: string) => {\n const res = await fetchWithAuth(`/threads/${threadId}`);\n if (!res.ok) throw new Error(`Failed to fetch thread: ${res.statusText}`);\n const data = await res.json();\n return (data?.data ?? data) as PersonaThread;\n },\n [fetchWithAuth],\n );\n\n useEffect(() => {\n if (autoFetch) {\n void fetchThreads();\n }\n }, [autoFetch, fetchThreads]);\n\n return {\n threads,\n isLoading,\n error,\n refetch: fetchThreads,\n createThread,\n deleteThread,\n bulkDeleteThreads,\n deleteAllThreads,\n updateThread,\n renameThread,\n resetThread,\n getThread,\n };\n}\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport { recorderWorkletUrl, playerWorkletUrl } from \"./voiceWorklets.js\";\r\nimport type {\r\n PersonaVoiceEndReason,\r\n PersonaVoiceState,\r\n PersonaVoiceToolCall,\r\n PersonaVoiceTranscriptLine,\r\n UseVoiceOptions,\r\n UseVoiceResult,\r\n} from \"../types.js\";\r\n\r\ninterface VoiceSessionTicket {\r\n ticket: string;\r\n wsUrl: string;\r\n expiresAt: string;\r\n session: {\r\n model: string;\r\n voice: string;\r\n inputSampleRate: number;\r\n outputSampleRate: number;\r\n maxDurationMs: number;\r\n };\r\n}\r\n\r\n// Gemini Live delivers an agent utterance's output transcription as SEVERAL\r\n// incremental fragments (one serverContent message per fragment) inside a\r\n// single model turn — there is no per-fragment \"finished\" flag; only\r\n// turnComplete closes the turn. The gateway forwards each fragment as its own\r\n// isFinal:true voice_transcript event, so without merging here every fragment\r\n// would render as its own stacked bubble even though the concatenated text is\r\n// one sentence. Fragments arrive as EITHER a cumulative full snapshot OR\r\n// incremental new words (Gemini does both), so handle both:\r\n// - cumulative: next already contains prev from the start -> take next\r\n// - incremental: append next, inserting a space only at a clean word seam\r\nfunction mergeTranscriptText(prev: string, next: string): string {\r\n if (!prev) return next;\r\n if (!next) return prev;\r\n if (next === prev || prev.endsWith(next)) return prev; // no-op / dup tail\r\n if (next.startsWith(prev)) return next; // cumulative snapshot\r\n const needSpace = !/\\s$/.test(prev) && !/^\\s/.test(next);\r\n return prev + (needSpace ? \" \" : \"\") + next;\r\n}\r\n\r\ninterface VoiceTranscriptValue {\r\n speaker: \"user\" | \"agent\";\r\n text: string;\r\n isFinal: boolean;\r\n turnSeq?: number;\r\n}\r\n\r\n/**\r\n * Drives a real-time voice call with an Agent (powered by Gemini Live).\r\n *\r\n * Ticket minting goes through YOUR OWN backend (`POST /voice/sessions` on\r\n * whichever `@personaai/runtime`-based adapter you've mounted) via\r\n * `fetchWithAuth` — same as every other hook in this package. The actual\r\n * call does NOT: once a ticket comes back, this hook opens a WebSocket\r\n * DIRECTLY to Persona (`ticket.wsUrl`), bypassing your backend entirely for\r\n * the live audio. This is deliberate — see the package README's Voice\r\n * section for why (short version: a multi-minute relay would not survive\r\n * on a serverless deployment the way `POST /chat`'s bounded SSE relay\r\n * does), and it means your backend never has to become a WebSocket relay.\r\n *\r\n * Requires a browser with `AudioWorklet` support (all current evergreen\r\n * browsers). The processor code itself needs no `/public` file of your\r\n * own — it's embedded and loaded via a Blob URL (see `voiceWorklets.ts`).\r\n */\r\nexport function useVoice(options: UseVoiceOptions = {}): UseVoiceResult {\r\n const { defaultAgentId, fetchWithAuth, logger } = usePersonaContext();\r\n const voiceLogger = useMemo(() => logger.child(\"voice\"), [logger]);\r\n const agentId = options.agentId || defaultAgentId;\r\n const threadId = options.threadId;\r\n const contextOverride = options.contextOverride;\r\n const context = options.context;\r\n\r\n const [state, setState] = useState<PersonaVoiceState>(\"idle\");\r\n const [isMuted, setIsMuted] = useState(false);\r\n const [transcript, setTranscript] = useState<PersonaVoiceTranscriptLine[]>(\r\n [],\r\n );\r\n const [partial, setPartial] = useState<PersonaVoiceTranscriptLine | null>(\r\n null,\r\n );\r\n const [toolCalls, setToolCalls] = useState<PersonaVoiceToolCall[]>([]);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [endReason, setEndReason] = useState<PersonaVoiceEndReason | null>(\r\n null,\r\n );\r\n\r\n const wsRef = useRef<WebSocket | null>(null);\r\n const streamRef = useRef<MediaStream | null>(null);\r\n const inputCtxRef = useRef<AudioContext | null>(null);\r\n const outputCtxRef = useRef<AudioContext | null>(null);\r\n const recorderNodeRef = useRef<AudioWorkletNode | null>(null);\r\n const playerNodeRef = useRef<AudioWorkletNode | null>(null);\r\n const acceptedTurnSeqRef = useRef(0);\r\n const mountedRef = useRef(true);\r\n // Speaker + turnSeq of the last committed transcript line. Consecutive\r\n // finals with the same speaker AND turnSeq are fragments of one utterance\r\n // (the server bumps turnSeq only at turnComplete), so they merge into the\r\n // line they created instead of spawning a new bubble.\r\n const lastFinalTurnRef = useRef<{ speaker: string; turnSeq?: number } | null>(\r\n null,\r\n );\r\n\r\n useEffect(() => {\r\n mountedRef.current = true;\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n const teardownAudio = useCallback(() => {\r\n try {\r\n streamRef.current?.getTracks().forEach((track) => track.stop());\r\n } catch {\r\n // ignore\r\n }\r\n streamRef.current = null;\r\n\r\n try {\r\n recorderNodeRef.current?.disconnect();\r\n } catch {\r\n // ignore\r\n }\r\n recorderNodeRef.current = null;\r\n\r\n try {\r\n playerNodeRef.current?.disconnect();\r\n } catch {\r\n // ignore\r\n }\r\n playerNodeRef.current = null;\r\n\r\n try {\r\n void inputCtxRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n inputCtxRef.current = null;\r\n\r\n try {\r\n void outputCtxRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n outputCtxRef.current = null;\r\n }, []);\r\n\r\n const stop = useCallback(() => {\r\n voiceLogger.debug(\"stop() called\");\r\n try {\r\n wsRef.current?.close(1000, \"client_stop\");\r\n } catch {\r\n // ignore\r\n }\r\n wsRef.current = null;\r\n teardownAudio();\r\n if (mountedRef.current) setState(\"idle\");\r\n }, [teardownAudio, voiceLogger]);\r\n\r\n useEffect(() => stop, [stop]);\r\n\r\n const startCapture = useCallback(async (inputSampleRate: number) => {\r\n const stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n channelCount: 1,\r\n },\r\n });\r\n streamRef.current = stream;\r\n\r\n const inputCtx = new AudioContext({ sampleRate: inputSampleRate });\r\n inputCtxRef.current = inputCtx;\r\n await inputCtx.audioWorklet.addModule(recorderWorkletUrl());\r\n\r\n const source = inputCtx.createMediaStreamSource(stream);\r\n const recorderNode = new AudioWorkletNode(\r\n inputCtx,\r\n \"pcm-recorder-processor\",\r\n );\r\n recorderNode.port.onmessage = (event: MessageEvent<ArrayBuffer>) => {\r\n if (wsRef.current?.readyState === WebSocket.OPEN) {\r\n wsRef.current.send(event.data);\r\n }\r\n };\r\n recorderNodeRef.current = recorderNode;\r\n source.connect(recorderNode);\r\n }, []);\r\n\r\n const setupPlayback = useCallback(async (outputSampleRate: number) => {\r\n const outputCtx = new AudioContext({ sampleRate: outputSampleRate });\r\n outputCtxRef.current = outputCtx;\r\n await outputCtx.audioWorklet.addModule(playerWorkletUrl());\r\n\r\n const playerNode = new AudioWorkletNode(outputCtx, \"pcm-player-processor\");\r\n playerNode.connect(outputCtx.destination);\r\n playerNodeRef.current = playerNode;\r\n }, []);\r\n\r\n const upsertToolCall = useCallback(\r\n (id: string, patch: Partial<PersonaVoiceToolCall>) => {\r\n setToolCalls((prev) => {\r\n const idx = prev.findIndex((t) => t.id === id);\r\n if (idx === -1) return [...prev, { id, status: \"running\", ...patch }];\r\n const next = [...prev];\r\n next[idx] = { ...next[idx], ...patch } as PersonaVoiceToolCall;\r\n return next;\r\n });\r\n },\r\n [],\r\n );\r\n\r\n const handleTranscript = useCallback((value: VoiceTranscriptValue) => {\r\n const { speaker, text, isFinal, turnSeq } = value;\r\n if (!isFinal) {\r\n setPartial({ id: \"partial\", speaker, text });\r\n return;\r\n }\r\n\r\n // A final may land while a partial of the same speaker is showing (the\r\n // last interim is superseded by the final) — clear it only for that case.\r\n setPartial((prev) => (prev?.speaker === speaker ? null : prev));\r\n\r\n const last = lastFinalTurnRef.current;\r\n const sameUserBurst =\r\n speaker === \"user\" &&\r\n last &&\r\n last.speaker === speaker &&\r\n last.turnSeq === turnSeq;\r\n\r\n setTranscript((prev) => {\r\n const tail = prev[prev.length - 1];\r\n // An agent \"answer\" can arrive as several separate finals: per-fragment\r\n // finals of one utterance, or distinct spoken segments split by a tool\r\n // call mid-answer. Keep them as ONE bubble while no user line has\r\n // intervened — this is exactly how the thread reads the same turns back\r\n // (checkpoint.service normalizeMessages merges consecutive assistant\r\n // messages) and how text chat shows one assistant message per answer.\r\n // A committed user line between two agent lines separates answers, so\r\n // the merge only applies when the open line is also agent.\r\n const agentContinues = speaker === \"agent\" && tail?.speaker === \"agent\";\r\n if (agentContinues || (sameUserBurst && tail?.speaker === \"user\")) {\r\n const merged = mergeTranscriptText(tail.text, text);\r\n if (merged === tail.text) return prev;\r\n return prev.map((l, i) =>\r\n i === prev.length - 1 ? { ...l, text: merged } : l,\r\n );\r\n }\r\n return [...prev, { id: `${speaker}-${prev.length}`, speaker, text }];\r\n });\r\n lastFinalTurnRef.current = { speaker, turnSeq };\r\n }, []);\r\n\r\n const handleCustomEvent = useCallback(\r\n (name: string, value: Record<string, unknown>) => {\r\n switch (name) {\r\n case \"voice_session_ready\":\r\n voiceLogger.debug(\"voice_session_ready\", value);\r\n Promise.all([\r\n setupPlayback(value.outputSampleRate as number),\r\n startCapture(value.inputSampleRate as number),\r\n ])\r\n .then(() => {\r\n if (mountedRef.current) setState(\"listening\");\r\n })\r\n .catch((err) => {\r\n voiceLogger.error(\"audio graph setup failed\", {\r\n error: err instanceof Error ? err.message : String(err),\r\n });\r\n if (mountedRef.current) {\r\n setError(err instanceof Error ? err : new Error(String(err)));\r\n setState(\"error\");\r\n }\r\n });\r\n break;\r\n case \"voice_activity\":\r\n if (value.speaker === \"user\" && value.state === \"start\") {\r\n setState(\"listening\");\r\n } else if (value.speaker === \"user\" && value.state === \"end\") {\r\n setState(\"thinking\");\r\n } else if (value.speaker === \"agent\" && value.state === \"start\") {\r\n setState(\"speaking\");\r\n } else if (value.speaker === \"agent\" && value.state === \"end\") {\r\n setState(\"listening\");\r\n }\r\n break;\r\n case \"voice_transcript\":\r\n handleTranscript(value as unknown as VoiceTranscriptValue);\r\n break;\r\n case \"voice_interrupted\":\r\n acceptedTurnSeqRef.current = value.turnSeq as number;\r\n playerNodeRef.current?.port.postMessage({ type: \"flush\" });\r\n break;\r\n case \"voice_session_resumed\":\r\n voiceLogger.info(\"session transparently resumed\");\r\n break;\r\n case \"voice_session_ended\":\r\n voiceLogger.info(\"session ended\", { reason: value.reason });\r\n setState(\"ended\");\r\n setEndReason((value.reason as PersonaVoiceEndReason) ?? null);\r\n teardownAudio();\r\n try {\r\n wsRef.current?.close();\r\n } catch {\r\n // ignore\r\n }\r\n wsRef.current = null;\r\n break;\r\n default:\r\n break;\r\n }\r\n },\r\n [handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger],\r\n );\r\n\r\n const handleMessage = useCallback(\r\n (event: MessageEvent<ArrayBuffer | string>) => {\r\n if (typeof event.data !== \"string\") {\r\n const buf = event.data;\r\n const view = new DataView(buf);\r\n const turnSeq = view.getUint32(0, true);\r\n // Accept (and adopt) anything >= the last accepted value rather\r\n // than an exact match — the server bumps turnSeq on EVERY new\r\n // agent turn, not only on a barge-in. WebSocket delivers messages\r\n // in send order on one connection, so a voice_interrupted event\r\n // always arrives before any frame from the generation it\r\n // announces — nothing stale can arrive after it.\r\n if (turnSeq >= acceptedTurnSeqRef.current) {\r\n acceptedTurnSeqRef.current = turnSeq;\r\n const pcmBytes = buf.slice(4);\r\n playerNodeRef.current?.port.postMessage(pcmBytes, [pcmBytes]);\r\n }\r\n return;\r\n }\r\n\r\n let msg: Record<string, unknown>;\r\n try {\r\n msg = JSON.parse(event.data);\r\n } catch {\r\n return;\r\n }\r\n\r\n switch (msg.type) {\r\n case \"CUSTOM\":\r\n handleCustomEvent(\r\n msg.name as string,\r\n msg.value as Record<string, unknown>,\r\n );\r\n break;\r\n case \"TOOL_CALL_CHUNK\":\r\n upsertToolCall(msg.toolCallId as string, {\r\n name: msg.toolCallName as string | undefined,\r\n status: \"running\",\r\n });\r\n break;\r\n case \"TOOL_CALL_RESULT\": {\r\n let parsed: { output?: unknown; error?: string } | null = null;\r\n try {\r\n parsed = JSON.parse(msg.content as string);\r\n } catch {\r\n parsed = { output: msg.content };\r\n }\r\n upsertToolCall(msg.toolCallId as string, {\r\n status: parsed?.error ? \"error\" : \"done\",\r\n summary:\r\n parsed?.error ||\r\n (typeof parsed?.output === \"string\"\r\n ? parsed.output\r\n : JSON.stringify(parsed?.output ?? \"\")),\r\n });\r\n break;\r\n }\r\n case \"RUN_ERROR\":\r\n voiceLogger.warn(\"RUN_ERROR\", { message: msg.message });\r\n setError(\r\n new Error((msg.message as string) || \"The agent run failed.\"),\r\n );\r\n setState(\"error\");\r\n break;\r\n default:\r\n break;\r\n }\r\n },\r\n [handleCustomEvent, upsertToolCall, voiceLogger],\r\n );\r\n\r\n const start = useCallback(async () => {\r\n if (!agentId) {\r\n const err = new Error(\r\n \"useVoice: no agentId provided and no defaultAgentId set on PersonaProvider\",\r\n );\r\n setError(err);\r\n setState(\"error\");\r\n return;\r\n }\r\n\r\n setError(null);\r\n setEndReason(null);\r\n setTranscript([]);\r\n setPartial(null);\r\n setToolCalls([]);\r\n acceptedTurnSeqRef.current = 0;\r\n setState(\"connecting\");\r\n voiceLogger.debug(\"start() called\", {\r\n agentId,\r\n threadId,\r\n hasContextOverride: !!contextOverride,\r\n hasContext: !!context,\r\n });\r\n\r\n try {\r\n const res = await fetchWithAuth(\"/voice/sessions\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n agentId,\r\n ...(threadId ? { threadId } : {}),\r\n ...(contextOverride ? { contextOverride } : {}),\r\n ...(context ? { context } : {}),\r\n }),\r\n });\r\n if (!res.ok) {\r\n throw new Error(`Failed to start voice session: ${res.statusText}`);\r\n }\r\n const data = await res.json();\r\n const ticket = (data?.data ?? data) as VoiceSessionTicket;\r\n if (!ticket?.wsUrl) {\r\n throw new Error(\"Server did not return a voice session URL.\");\r\n }\r\n\r\n const ws = new WebSocket(ticket.wsUrl);\r\n ws.binaryType = \"arraybuffer\";\r\n wsRef.current = ws;\r\n\r\n ws.onmessage = handleMessage;\r\n ws.onerror = () => {\r\n voiceLogger.warn(\"WebSocket error\");\r\n if (mountedRef.current) {\r\n setError(new Error(\"Voice connection error.\"));\r\n setState(\"error\");\r\n }\r\n };\r\n ws.onclose = () => {\r\n if (mountedRef.current && wsRef.current === ws) {\r\n setState((prev) => (prev === \"error\" ? prev : \"idle\"));\r\n }\r\n };\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n voiceLogger.error(\"start() failed\", { error: errorObj.message });\r\n if (mountedRef.current) {\r\n setError(errorObj);\r\n setState(\"error\");\r\n }\r\n teardownAudio();\r\n }\r\n }, [agentId, threadId, contextOverride, context, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);\r\n\r\n const mute = useCallback((muted: boolean) => {\r\n setIsMuted(muted);\r\n streamRef.current?.getAudioTracks().forEach((track) => {\r\n track.enabled = !muted;\r\n });\r\n }, []);\r\n\r\n const sendText = useCallback((text: string) => {\r\n if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;\r\n wsRef.current.send(JSON.stringify({ type: \"voice.text\", text }));\r\n }, []);\r\n\r\n // Live refresh for the rest of an already-open call — the backend merges\r\n // this into whatever turnContext it already has (the start() seed, or an\r\n // earlier updateContext() call), so callers only need to send what\r\n // actually changed. A no-op while there's no open socket, same guard\r\n // sendText uses — nothing queues for \"once connected.\"\r\n const updateContext = useCallback((newContext: Record<string, unknown>) => {\r\n if (wsRef.current?.readyState !== WebSocket.OPEN) return;\r\n wsRef.current.send(JSON.stringify({ type: \"voice.context\", context: newContext }));\r\n }, []);\r\n\r\n return {\r\n state,\r\n isMuted,\r\n transcript,\r\n partial,\r\n toolCalls,\r\n error,\r\n endReason,\r\n start,\r\n stop,\r\n mute,\r\n sendText,\r\n updateContext,\r\n };\r\n}\r\n","/**\n * AudioWorklet processor source for `useVoice`, embedded as strings rather\n * than shipped as separate static files. A consumer app has no `/public`\n * directory we can rely on being copied into (unlike our own first-party\n * frontend, which loads these from `/voice/*.js`) — `URL.createObjectURL`\n * + a Blob is the standard way to hand `audioWorklet.addModule()` a module\n * with zero setup required from the host app.\n */\n\nconst RECORDER_WORKLET_SOURCE = `\nclass PCMRecorderProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this._buffer = [];\n this._chunkSamples = 320; // 20ms @ 16kHz\n }\n\n process(inputs) {\n const input = inputs[0];\n const channel = input && input[0];\n if (channel) {\n for (let i = 0; i < channel.length; i++) {\n this._buffer.push(channel[i]);\n }\n while (this._buffer.length >= this._chunkSamples) {\n const chunk = this._buffer.splice(0, this._chunkSamples);\n const int16 = new Int16Array(chunk.length);\n for (let i = 0; i < chunk.length; i++) {\n const s = Math.max(-1, Math.min(1, chunk[i]));\n int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff;\n }\n this.port.postMessage(int16.buffer, [int16.buffer]);\n }\n }\n return true;\n }\n}\n\nregisterProcessor('pcm-recorder-processor', PCMRecorderProcessor);\n`;\n\nconst PLAYER_WORKLET_SOURCE = `\nclass PCMPlayerProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this._queue = [];\n this._readOffset = 0;\n this.port.onmessage = (event) => {\n const msg = event.data;\n if (msg && msg.type === 'flush') {\n this._queue = [];\n this._readOffset = 0;\n return;\n }\n const int16 = new Int16Array(msg);\n const float32 = new Float32Array(int16.length);\n for (let i = 0; i < int16.length; i++) {\n float32[i] = int16[i] / 0x8000;\n }\n this._queue.push(float32);\n };\n }\n\n process(_inputs, outputs) {\n const output = outputs[0][0];\n let outIdx = 0;\n while (outIdx < output.length) {\n if (this._queue.length === 0) {\n output[outIdx++] = 0;\n continue;\n }\n const current = this._queue[0];\n const remaining = current.length - this._readOffset;\n const toCopy = Math.min(remaining, output.length - outIdx);\n output.set(current.subarray(this._readOffset, this._readOffset + toCopy), outIdx);\n outIdx += toCopy;\n this._readOffset += toCopy;\n if (this._readOffset >= current.length) {\n this._queue.shift();\n this._readOffset = 0;\n }\n }\n return true;\n }\n}\n\nregisterProcessor('pcm-player-processor', PCMPlayerProcessor);\n`;\n\nfunction toModuleUrl(source: string): string {\n const blob = new Blob([source], { type: \"application/javascript\" });\n return URL.createObjectURL(blob);\n}\n\nexport function recorderWorkletUrl(): string {\n return toModuleUrl(RECORDER_WORKLET_SOURCE);\n}\n\nexport function playerWorkletUrl(): string {\n return toModuleUrl(PLAYER_WORKLET_SOURCE);\n}\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport type { PersonaFileItem } from \"../types.js\";\r\n\r\nexport type { PersonaFileItem };\r\n\r\nexport function useFiles(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [files, setFiles] = useState<PersonaFileItem[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [isUploading, setIsUploading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchFiles = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/files\");\r\n if (!res.ok) throw new Error(`Failed to list files: ${res.statusText}`);\r\n const data = await res.json();\r\n // Real shape is { items, pagination } — bare array/`.files` are\r\n // defensive fallbacks, not the actual wire contract.\r\n const items: PersonaFileItem[] = Array.isArray(data)\r\n ? data\r\n : data?.items || data?.files || [];\r\n setFiles(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n const uploadFile = useCallback(\r\n async (\r\n fileOrFormData: FormData | { name: string; uri: string; type?: string },\r\n ) => {\r\n setIsUploading(true);\r\n setError(null);\r\n try {\r\n let body: FormData;\r\n if (fileOrFormData instanceof FormData) {\r\n body = fileOrFormData;\r\n } else {\r\n // React Native FormData support\r\n body = new FormData();\r\n body.append(\"file\", fileOrFormData as unknown as Blob);\r\n }\r\n\r\n const res = await fetchWithAuth(\"/files\", {\r\n method: \"POST\",\r\n body,\r\n });\r\n\r\n if (!res.ok) {\r\n const errText = await res.text().catch(() => \"Upload failed\");\r\n throw new Error(`Upload error (${res.status}): ${errText}`);\r\n }\r\n\r\n const uploaded = (await res.json()) as PersonaFileItem;\r\n void fetchFiles();\r\n return uploaded;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n throw errorObj;\r\n } finally {\r\n setIsUploading(false);\r\n }\r\n },\r\n [fetchWithAuth, fetchFiles],\r\n );\r\n\r\n const deleteFile = useCallback(\r\n async (fileId: string) => {\r\n const res = await fetchWithAuth(`/files/${fileId}`, { method: \"DELETE\" });\r\n if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);\r\n setFiles((prev) => prev.filter((f) => f.id !== fileId));\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const bulkDeleteFiles = useCallback(\r\n async (fileIds: string[]) => {\r\n const res = await fetchWithAuth(\"/files/bulk-delete\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ ids: fileIds }),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to bulk-delete files: ${res.statusText}`);\r\n const idSet = new Set(fileIds);\r\n setFiles((prev) => prev.filter((f) => !idSet.has(f.id)));\r\n return (await res.json()) as {\r\n deleted: string[];\r\n failed: Array<{ id: string; reason: string }>;\r\n };\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const getDownloadUrl = useCallback((fileId: string) => {\r\n return `/files/${fileId}`;\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchFiles();\r\n }\r\n }, [autoFetch, fetchFiles]);\r\n\r\n return {\r\n files,\r\n isLoading,\r\n isUploading,\r\n error,\r\n refetch: fetchFiles,\r\n uploadFile,\r\n deleteFile,\r\n bulkDeleteFiles,\r\n getDownloadUrl,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\nexport interface PersonaAgentSummary {\r\n _id: string;\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n tagline?: string;\r\n avatar?: string;\r\n}\r\n\r\nexport function useAgents(autoFetch = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [agents, setAgents] = useState<PersonaAgentSummary[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchAgents = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/agents\");\r\n if (!res.ok) throw new Error(`Failed to list agents: ${res.statusText}`);\r\n const data = await res.json();\r\n // Real shape is { items, pagination }.\r\n const items: PersonaAgentSummary[] = Array.isArray(data)\r\n ? data\r\n : data?.items || data?.agents || [];\r\n setAgents(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchAgents();\r\n }\r\n }, [autoFetch, fetchAgents]);\r\n\r\n return {\r\n agents,\r\n isLoading,\r\n error,\r\n refetch: fetchAgents,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\nexport interface PersonaHealthInfo {\r\n status: string;\r\n version?: string;\r\n capabilities?: Record<string, boolean>;\r\n}\r\n\r\nexport function useConnection(autoCheck = true) {\r\n const { fetchWithAuth } = usePersonaContext();\r\n const [health, setHealth] = useState<PersonaHealthInfo | null>(null);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const checkHealth = useCallback(async () => {\r\n setIsLoading(true);\r\n try {\r\n const res = await fetchWithAuth(\"/health\");\r\n if (res.ok) {\r\n const data = (await res.json()) as PersonaHealthInfo;\r\n setHealth(data);\r\n setIsConnected(true);\r\n return data;\r\n }\r\n setIsConnected(false);\r\n return null;\r\n } catch {\r\n setIsConnected(false);\r\n return null;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [fetchWithAuth]);\r\n\r\n useEffect(() => {\r\n if (autoCheck) {\r\n void checkHealth();\r\n }\r\n }, [autoCheck, checkHealth]);\r\n\r\n return {\r\n isConnected,\r\n health,\r\n isLoading,\r\n checkHealth,\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\n\r\n/**\r\n * One `authType: 'oauth', authMode: 'user'` MCP an Agent has attached, and\r\n * whether the current end user has connected it yet. `authorizeUrl` is only\r\n * present when `connected` is `false` — navigate the browser there (a\r\n * same-tab redirect is fine; it's a real OAuth authorization URL) to start\r\n * the consent flow.\r\n */\r\nexport interface PersonaMcpConnection {\r\n mcpId: string;\r\n name: string;\r\n description: string;\r\n connected: boolean;\r\n authorizeUrl: string | null;\r\n}\r\n\r\nexport interface UseMcpConnectionsOptions {\r\n /** @default the PersonaProvider's defaultAgentId */\r\n agentId?: string;\r\n /** Where the browser lands after OAuth consent completes. @default window.location.href */\r\n returnTo?: string;\r\n /** @default true */\r\n autoFetch?: boolean;\r\n}\r\n\r\n/**\r\n * Surfaces the gap that used to be invisible entirely: a user-mode MCP tool\r\n * call for a user who hasn't connected yet is silently dropped from the\r\n * Agent's toolset server-side, with no signal in the chat stream at all.\r\n * Check this before (or alongside) a chat session to show a real \"Connect\r\n * your account\" affordance instead of a capability that just quietly isn't\r\n * there.\r\n */\r\nexport function useMcpConnections(options: UseMcpConnectionsOptions = {}) {\r\n const { defaultAgentId, fetchWithAuth } = usePersonaContext();\r\n const agentId = options.agentId ?? defaultAgentId;\r\n const autoFetch = options.autoFetch ?? true;\r\n\r\n const [connections, setConnections] = useState<PersonaMcpConnection[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchConnections = useCallback(async () => {\r\n if (!agentId) return [];\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const returnTo =\r\n options.returnTo ??\r\n (typeof window !== \"undefined\" ? window.location.href : undefined);\r\n const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : \"\";\r\n const res = await fetchWithAuth(\r\n `/agents/${agentId}/mcp-connections${query}`,\r\n );\r\n if (!res.ok)\r\n throw new Error(`Failed to load MCP connections: ${res.statusText}`);\r\n const data = await res.json();\r\n const items: PersonaMcpConnection[] = Array.isArray(data)\r\n ? data\r\n : data?.items || [];\r\n setConnections(items);\r\n return items;\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n return [];\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [agentId, fetchWithAuth, options.returnTo]);\r\n\r\n useEffect(() => {\r\n if (autoFetch) void fetchConnections();\r\n }, [autoFetch, fetchConnections]);\r\n\r\n return {\r\n connections,\r\n /** Convenience filter for the common \"show a banner for what's missing\" case. */\r\n unconnected: connections.filter((c) => !c.connected),\r\n isLoading,\r\n error,\r\n refetch: fetchConnections,\r\n };\r\n}\r\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\n\nexport interface UseMcpOptions {\n /** Default MCP server ID for resource reads and tool calls */\n mcpId?: string;\n}\n\n/**\n * Hook for interacting with MCP servers connected via the Persona runtime.\n * Provides helper functions for reading UI/data resources and calling server tools.\n */\nexport function useMcp(options: UseMcpOptions = {}) {\n const { fetchWithAuth } = usePersonaContext();\n const defaultMcpId = options.mcpId;\n\n /**\n * Reads a resource by URI from an MCP server.\n * @param uri - The resource URI (e.g. `ui://...` or data resource URI).\n * @param mcpId - Optional MCP ID to override the hook's default.\n */\n const readResource = useCallback(\n async (uri: string, mcpId?: string) => {\n const id = mcpId ?? defaultMcpId;\n if (!id) throw new Error(\"MCP server ID is required to read resource\");\n const res = await fetchWithAuth(\n `/mcps/${id}/resource?uri=${encodeURIComponent(uri)}`\n );\n if (!res.ok) {\n throw new Error(`Failed to read MCP resource: ${res.statusText}`);\n }\n return await res.json();\n },\n [fetchWithAuth, defaultMcpId]\n );\n\n /**\n * Invokes a tool exposed by an MCP server.\n * @param name - Tool name.\n * @param args - Arguments matching the tool's schema.\n * @param mcpId - Optional MCP ID to override the hook's default.\n */\n const callTool = useCallback(\n async (\n name: string,\n args?: Record<string, unknown>,\n mcpId?: string\n ) => {\n const id = mcpId ?? defaultMcpId;\n if (!id) throw new Error(\"MCP server ID is required to call tool\");\n const res = await fetchWithAuth(`/mcps/${id}/call-tool`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name, arguments: args }),\n });\n if (!res.ok) {\n throw new Error(`Failed to call MCP tool: ${res.statusText}`);\n }\n return await res.json();\n },\n [fetchWithAuth, defaultMcpId]\n );\n\n return {\n readResource,\n callTool,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport type {\n CreateWorkflowInput,\n PersonaWorkflow,\n PersonaWorkflowSummary,\n UseWorkflowsOptions,\n} from \"../types.js\";\n\nexport interface WorkflowsPagination {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n}\n\nexport function useWorkflows(options?: UseWorkflowsOptions | boolean) {\n const opts: UseWorkflowsOptions =\n typeof options === \"boolean\" ? { autoFetch: options } : options ?? {};\n const { autoFetch = true, search, status, page, limit } = opts;\n\n const { fetchWithAuth } = usePersonaContext();\n const [workflows, setWorkflows] = useState<PersonaWorkflowSummary[]>([]);\n const [pagination, setPagination] = useState<WorkflowsPagination>({\n page: page ?? 1,\n limit: limit ?? 20,\n total: 0,\n totalPages: 0,\n });\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchWorkflows = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const params = new URLSearchParams();\n if (search) params.set(\"search\", search);\n if (status) params.set(\"status\", status);\n if (page) params.set(\"page\", String(page));\n if (limit) params.set(\"limit\", String(limit));\n\n const queryStr = params.toString() ? `?${params.toString()}` : \"\";\n const res = await fetchWithAuth(`/workflows${queryStr}`);\n if (!res.ok) {\n throw new Error(`Failed to list workflows: ${res.statusText}`);\n }\n const data = await res.json();\n const items: PersonaWorkflowSummary[] = Array.isArray(data)\n ? data\n : data?.items || data?.workflows || [];\n setWorkflows(items);\n\n if (data?.pagination) {\n setPagination({\n page: data.pagination.page ?? 1,\n limit: data.pagination.limit ?? items.length,\n total: data.pagination.total ?? items.length,\n totalPages: data.pagination.totalPages ?? 1,\n });\n } else {\n setPagination({\n page: 1,\n limit: items.length,\n total: items.length,\n totalPages: 1,\n });\n }\n return items;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth, search, status, page, limit]);\n\n const createWorkflow = useCallback(\n async (input: CreateWorkflowInput): Promise<PersonaWorkflow> => {\n setError(null);\n try {\n const res = await fetchWithAuth(\"/workflows\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input),\n });\n if (!res.ok) {\n const errText = await res.text().catch(() => res.statusText);\n throw new Error(`Failed to create workflow (${res.status}): ${errText}`);\n }\n const created = (await res.json()) as PersonaWorkflow;\n setWorkflows((prev) => [created, ...prev]);\n return created;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n }\n },\n [fetchWithAuth],\n );\n\n useEffect(() => {\n if (autoFetch) {\n void fetchWorkflows();\n }\n }, [autoFetch, fetchWorkflows]);\n\n return {\n workflows,\n pagination,\n isLoading,\n error,\n refetch: fetchWorkflows,\n createWorkflow,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport type {\n PersonaWorkflow,\n PersonaWorkflowDraft,\n PersonaWorkflowVersionSummary,\n UseWorkflowOptions,\n} from \"../types.js\";\n\nexport function useWorkflow(\n workflowId: string,\n options?: UseWorkflowOptions | boolean,\n) {\n const opts: UseWorkflowOptions =\n typeof options === \"boolean\" ? { autoFetch: options } : options ?? {};\n const { autoFetch = true } = opts;\n\n const { fetchWithAuth } = usePersonaContext();\n const [workflow, setWorkflow] = useState<PersonaWorkflow | null>(null);\n const [versions, setVersions] = useState<PersonaWorkflowVersionSummary[]>([]);\n const [mermaid, setMermaid] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchWorkflow = useCallback(async () => {\n if (!workflowId) return null;\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth(`/workflows/${workflowId}`);\n if (!res.ok) {\n throw new Error(`Failed to fetch workflow (${res.status}): ${res.statusText}`);\n }\n const data = (await res.json()) as PersonaWorkflow;\n setWorkflow(data);\n return data;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth, workflowId]);\n\n const fetchVersions = useCallback(async () => {\n if (!workflowId) return [];\n try {\n const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);\n if (!res.ok) return [];\n const data = await res.json();\n const items: PersonaWorkflowVersionSummary[] = Array.isArray(data)\n ? data\n : data?.items || [];\n setVersions(items);\n return items;\n } catch {\n return [];\n }\n }, [fetchWithAuth, workflowId]);\n\n const fetchMermaid = useCallback(async () => {\n if (!workflowId) return \"\";\n try {\n const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);\n if (!res.ok) return \"\";\n const data = await res.json();\n const code = typeof data?.mermaid === \"string\" ? data.mermaid : String(data ?? \"\");\n setMermaid(code);\n return code;\n } catch {\n return \"\";\n }\n }, [fetchWithAuth, workflowId]);\n\n const saveDraft = useCallback(\n async (draft: PersonaWorkflowDraft) => {\n if (!workflowId) throw new Error(\"Workflow ID is required\");\n setError(null);\n const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ draft }),\n });\n if (!res.ok) {\n const errText = await res.text().catch(() => res.statusText);\n throw new Error(`Failed to save draft (${res.status}): ${errText}`);\n }\n const updated = (await res.json()) as PersonaWorkflow;\n setWorkflow(updated);\n return updated;\n },\n [fetchWithAuth, workflowId],\n );\n\n const publish = useCallback(\n async (summary?: string): Promise<PersonaWorkflowVersionSummary> => {\n if (!workflowId) throw new Error(\"Workflow ID is required\");\n setError(null);\n const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(summary ? { summary } : {}),\n });\n if (!res.ok) {\n const errText = await res.text().catch(() => res.statusText);\n throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);\n }\n const versionResult = (await res.json()) as PersonaWorkflowVersionSummary;\n void fetchWorkflow();\n void fetchVersions();\n return versionResult;\n },\n [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions],\n );\n\n const deleteWorkflow = useCallback(async () => {\n if (!workflowId) throw new Error(\"Workflow ID is required\");\n setError(null);\n const res = await fetchWithAuth(`/workflows/${workflowId}`, {\n method: \"DELETE\",\n });\n if (!res.ok) {\n throw new Error(`Failed to delete workflow (${res.status}): ${res.statusText}`);\n }\n setWorkflow(null);\n }, [fetchWithAuth, workflowId]);\n\n useEffect(() => {\n if (autoFetch && workflowId) {\n void fetchWorkflow();\n }\n }, [autoFetch, workflowId, fetchWorkflow]);\n\n return {\n workflow,\n versions,\n mermaid,\n isLoading,\n error,\n refetch: fetchWorkflow,\n fetchVersions,\n fetchMermaid,\n saveDraft,\n publish,\n deleteWorkflow,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport { openSSEStream } from \"../streaming.js\";\nimport type {\n PersonaNodeRunState,\n PersonaStreamingEvent,\n UseWorkflowStreamOptions,\n UseWorkflowStreamResult,\n} from \"../types.js\";\n\nexport function useWorkflowStream(\n workflowId?: string,\n options?: UseWorkflowStreamOptions,\n): UseWorkflowStreamResult {\n const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();\n\n const [status, setStatus] = useState<\n \"idle\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\"\n >(\"idle\");\n const [runId, setRunId] = useState<string | null>(null);\n const [activeNodeId, setActiveNodeId] = useState<string | null>(null);\n const [nodeRuns, setNodeRuns] = useState<Record<string, PersonaNodeRunState>>(\n {},\n );\n const [text, setText] = useState<string>(\"\");\n const [output, setOutput] = useState<unknown>(null);\n const [error, setError] = useState<Error | null>(null);\n const [events, setEvents] = useState<PersonaStreamingEvent[]>([]);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const currentRunIdRef = useRef<string | null>(null);\n currentRunIdRef.current = runId;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const cancel = useCallback(async () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n const currentRun = currentRunIdRef.current;\n if (currentRun) {\n try {\n await fetchWithAuth(`/workflows/runs/${currentRun}/cancel`, {\n method: \"POST\",\n });\n } catch (err) {\n logger.warn(\"Failed to send cancel request to workflow run\", {\n runId: currentRun,\n error: String(err),\n });\n }\n }\n setStatus(\"cancelled\");\n setActiveNodeId(null);\n }, [fetchWithAuth, logger]);\n\n const reset = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n setStatus(\"idle\");\n setRunId(null);\n setActiveNodeId(null);\n setNodeRuns({});\n setText(\"\");\n setOutput(null);\n setError(null);\n setEvents([]);\n }, []);\n\n const processStream = useCallback(\n async (\n url: string,\n method: \"GET\" | \"POST\",\n body?: string,\n targetRunId?: string,\n ) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n setStatus(\"running\");\n setError(null);\n\n const token = getAuthToken ? await getAuthToken() : null;\n const headers: Record<string, string> = {\n Accept: \"text/event-stream\",\n };\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n if (method === \"POST\") {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n let assignedRunId = targetRunId ?? null;\n let accumulatedText = \"\";\n let finalOutput: unknown = null;\n\n try {\n const stream = await openSSEStream({\n url,\n method,\n headers,\n body,\n signal: controller.signal,\n });\n\n if (!stream.ok) {\n throw new Error(\n stream.errorText || `Stream request failed with status ${stream.status}`,\n );\n }\n\n const runIdHeader = stream.getHeader(\"x-persona-run-id\");\n if (runIdHeader) {\n assignedRunId = runIdHeader;\n setRunId(runIdHeader);\n }\n\n let buffer = \"\";\n while (true) {\n const { done, value } = await stream.reader.read();\n if (done) break;\n if (!value) continue;\n\n buffer += value;\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\":\")) continue; // heartbeats or comments\n if (trimmed.startsWith(\"data:\")) {\n const rawData = trimmed.slice(5).trim();\n if (!rawData || rawData === \"[DONE]\") continue;\n\n try {\n const event = JSON.parse(rawData) as PersonaStreamingEvent;\n setEvents((prev) => [...prev, event]);\n optionsRef.current?.onEvent?.(event);\n\n if (\"runId\" in event && typeof event.runId === \"string\" && !assignedRunId) {\n assignedRunId = event.runId;\n setRunId(event.runId);\n }\n\n if (event.type === \"TEXT_MESSAGE_CHUNK\") {\n accumulatedText += event.delta;\n setText((prev) => prev + event.delta);\n } else if (event.type === \"CUSTOM\") {\n if (event.name === \"workflow_node_started\") {\n const val = event.value as {\n nodeId: string;\n nodeType: string;\n nodeLabel: string;\n input?: unknown;\n };\n setActiveNodeId(val.nodeId);\n setNodeRuns((prev) => ({\n ...prev,\n [val.nodeId]: {\n nodeId: val.nodeId,\n nodeType: val.nodeType,\n nodeLabel: val.nodeLabel,\n status: \"running\",\n startedAt: new Date().toISOString(),\n input: val.input,\n },\n }));\n optionsRef.current?.onNodeStarted?.(val);\n } else if (event.name === \"workflow_node_completed\") {\n const val = event.value as {\n nodeId: string;\n output: unknown;\n };\n setNodeRuns((prev) => {\n const existing = prev[val.nodeId];\n return {\n ...prev,\n [val.nodeId]: {\n nodeId: val.nodeId,\n nodeType: existing?.nodeType ?? \"unknown\",\n nodeLabel: existing?.nodeLabel ?? val.nodeId,\n status: \"completed\",\n startedAt: existing?.startedAt,\n finishedAt: new Date().toISOString(),\n input: existing?.input,\n output: val.output,\n },\n };\n });\n setActiveNodeId((curr) => (curr === val.nodeId ? null : curr));\n finalOutput = val.output;\n setOutput(val.output);\n optionsRef.current?.onNodeCompleted?.(val);\n } else if (event.name === \"workflow_node_failed\") {\n const val = event.value as {\n nodeId: string;\n error: string;\n };\n setNodeRuns((prev) => {\n const existing = prev[val.nodeId];\n return {\n ...prev,\n [val.nodeId]: {\n nodeId: val.nodeId,\n nodeType: existing?.nodeType ?? \"unknown\",\n nodeLabel: existing?.nodeLabel ?? val.nodeId,\n status: \"failed\",\n startedAt: existing?.startedAt,\n finishedAt: new Date().toISOString(),\n input: existing?.input,\n error: val.error,\n },\n };\n });\n setActiveNodeId((curr) => (curr === val.nodeId ? null : curr));\n optionsRef.current?.onNodeFailed?.(val);\n }\n } else if (event.type === \"RUN_FINISHED\") {\n setStatus(\"completed\");\n setActiveNodeId(null);\n optionsRef.current?.onFinish?.({\n runId: assignedRunId || \"\",\n output: finalOutput,\n text: accumulatedText,\n });\n } else if (event.type === \"RUN_ERROR\") {\n const runErr = new Error(event.message || event.code || \"Workflow run error\");\n setStatus(\"failed\");\n setError(runErr);\n setActiveNodeId(null);\n optionsRef.current?.onError?.(runErr);\n }\n } catch {\n // Ignore parse errors on partial frames\n }\n }\n }\n }\n\n setStatus((prev) => (prev === \"running\" ? \"completed\" : prev));\n return finalOutput;\n } catch (err) {\n if (controller.signal.aborted) {\n setStatus(\"cancelled\");\n return null;\n }\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setStatus(\"failed\");\n setError(errorObj);\n setActiveNodeId(null);\n optionsRef.current?.onError?.(errorObj);\n throw errorObj;\n } finally {\n if (abortControllerRef.current === controller) {\n abortControllerRef.current = null;\n }\n }\n },\n [getAuthToken],\n );\n\n const start = useCallback(\n async (\n input?: unknown,\n opts?: { dryRun?: boolean; workflowId?: string },\n ): Promise<unknown> => {\n const targetWfId = opts?.workflowId || workflowId;\n if (!targetWfId) {\n throw new Error(\"Workflow ID must be provided to start execution\");\n }\n\n setNodeRuns({});\n setText(\"\");\n setOutput(null);\n setEvents([]);\n setActiveNodeId(null);\n\n const cleanBase = baseUrl.replace(/\\/+$/, \"\");\n const url = `${cleanBase}/workflows/${targetWfId}/stream`;\n const body = JSON.stringify({\n input: input ?? {},\n dryRun: opts?.dryRun ?? false,\n });\n\n return processStream(url, \"POST\", body);\n },\n [workflowId, baseUrl, processStream],\n );\n\n const resume = useCallback(\n async (targetRunId: string, sinceSeq?: number): Promise<void> => {\n if (!targetRunId) {\n throw new Error(\"Run ID is required to resume stream\");\n }\n setRunId(targetRunId);\n const cleanBase = baseUrl.replace(/\\/+$/, \"\");\n const query = sinceSeq !== undefined ? `?since=${sinceSeq}` : \"\";\n const url = `${cleanBase}/workflows/runs/${targetRunId}/resume${query}`;\n\n await processStream(url, \"GET\", undefined, targetRunId);\n },\n [baseUrl, processStream],\n );\n\n useEffect(() => {\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return {\n runId,\n status,\n isRunning: status === \"running\",\n activeNodeId,\n nodeRuns,\n text,\n output,\n error,\n events,\n start,\n cancel,\n resume,\n reset,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\nimport type {\n PersonaWorkflowRunSummary,\n UseWorkflowRunsOptions,\n} from \"../types.js\";\n\nexport function useWorkflowRuns(\n workflowId?: string,\n options?: UseWorkflowRunsOptions | boolean,\n) {\n const opts: UseWorkflowRunsOptions =\n typeof options === \"boolean\" ? { autoFetch: options } : options ?? {};\n const { autoFetch = true, page = 1, limit = 20 } = opts;\n\n const { fetchWithAuth } = usePersonaContext();\n const [runs, setRuns] = useState<PersonaWorkflowRunSummary[]>([]);\n const [pagination, setPagination] = useState({\n page,\n limit,\n total: 0,\n totalPages: 0,\n });\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchRuns = useCallback(async () => {\n if (!workflowId) return [];\n setIsLoading(true);\n setError(null);\n try {\n const query = `?page=${page}&limit=${limit}`;\n const res = await fetchWithAuth(`/workflows/${workflowId}/runs${query}`);\n if (!res.ok) {\n throw new Error(`Failed to list workflow runs: ${res.statusText}`);\n }\n const data = await res.json();\n const items: PersonaWorkflowRunSummary[] = Array.isArray(data)\n ? data\n : data?.items || data?.runs || [];\n setRuns(items);\n\n if (data?.pagination) {\n setPagination({\n page: data.pagination.page ?? page,\n limit: data.pagination.limit ?? limit,\n total: data.pagination.total ?? items.length,\n totalPages: data.pagination.totalPages ?? 1,\n });\n }\n return items;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth, workflowId, page, limit]);\n\n const getRun = useCallback(\n async (runId: string): Promise<PersonaWorkflowRunSummary> => {\n if (!runId) throw new Error(\"Run ID is required\");\n const res = await fetchWithAuth(`/workflows/runs/${runId}`);\n if (!res.ok) {\n throw new Error(`Failed to fetch workflow run (${res.status}): ${res.statusText}`);\n }\n return (await res.json()) as PersonaWorkflowRunSummary;\n },\n [fetchWithAuth],\n );\n\n const cancelRun = useCallback(\n async (runId: string): Promise<void> => {\n if (!runId) throw new Error(\"Run ID is required\");\n const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {\n method: \"POST\",\n });\n if (!res.ok) {\n throw new Error(`Failed to cancel workflow run (${res.status}): ${res.statusText}`);\n }\n setRuns((prev) =>\n prev.map((r) => (r._id === runId ? { ...r, status: \"cancelled\" } : r)),\n );\n },\n [fetchWithAuth],\n );\n\n useEffect(() => {\n if (autoFetch && workflowId) {\n void fetchRuns();\n }\n }, [autoFetch, workflowId, fetchRuns]);\n\n return {\n runs,\n pagination,\n isLoading,\n error,\n refetch: fetchRuns,\n getRun,\n cancelRun,\n };\n}\n","export * from \"./types.js\";\r\nexport * from \"./context/PersonaContext.js\";\r\nexport * from \"./hooks/useChat.js\";\r\nexport * from \"./hooks/useArchitectChat.js\";\r\nexport * from \"./hooks/useMemory.js\";\r\nexport * from \"./hooks/useThreads.js\";\r\nexport * from \"./hooks/useVoice.js\";\r\nexport * from \"./hooks/useFiles.js\";\r\nexport * from \"./hooks/useAgents.js\";\r\nexport * from \"./hooks/useConnection.js\";\r\nexport * from \"./hooks/useMcpConnections.js\";\r\nexport * from \"./hooks/useMcp.js\";\r\nexport * from \"./hooks/useWorkflows.js\";\r\nexport * from \"./hooks/useWorkflow.js\";\r\nexport * from \"./hooks/useWorkflowStream.js\";\r\nexport * from \"./hooks/useWorkflowRuns.js\";\r\nexport * from \"./streaming.js\";\r\nexport {\r\n createLogger,\r\n createNoopLogger,\r\n setLogLevel,\r\n getLogLevel,\r\n isLevelEnabled,\r\n} from \"@personaai/logger\";\r\nexport type {\r\n Logger,\r\n LogLevel,\r\n LogTransport,\r\n CreateLoggerOptions,\r\n} from \"@personaai/logger\";\r\n\r\nexport const VERSION = \"0.10.0\";\r\n"],"mappings":"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","names":["useMemo","useMemo","value","useCallback","useEffect","useMemo","useRef","useState","useMemo","useState","useEffect","useRef","useCallback","value","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useMemo","useRef","useState","useMemo","useState","useRef","useEffect","useCallback","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useCallback","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","createLogger"]}