@personaai/react 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +420 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -27
- package/dist/index.d.ts +34 -27
- package/dist/index.js +422 -66
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts"],"sourcesContent":["export * from './types.js';\nexport * from './context/PersonaContext.js';\nexport * from './hooks/useChat.js';\nexport * from './hooks/useMemory.js';\nexport * from './hooks/useThreads.js';\nexport * from './hooks/useFiles.js';\nexport * from './hooks/useAgents.js';\nexport * from './hooks/useConnection.js';\nexport * from './hooks/useMcpConnections.js';\nexport * from './streaming.js';\n\nexport const VERSION = '0.4.0';\n","'use client';\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { PersonaProviderProps } from '../types.js';\n\ninterface PersonaContextValue {\n baseUrl: string;\n getAuthToken?: () => Promise<string | null | undefined> | string | null | undefined;\n defaultAgentId?: string;\n fetchWithAuth: (path: string, init?: RequestInit) => Promise<Response>;\n}\n\nconst PersonaContext = createContext<PersonaContextValue | null>(null);\n\nexport function PersonaProvider({\n baseUrl,\n getAuthToken,\n defaultAgentId,\n children,\n}: PersonaProviderProps) {\n const normalizedBaseUrl = useMemo(() => baseUrl.replace(/\\/+$/, ''), [baseUrl]);\n\n const value = useMemo<PersonaContextValue>(() => {\n async function fetchWithAuth(path: string, init: RequestInit = {}): Promise<Response> {\n const token = getAuthToken ? await getAuthToken() : null;\n const headers = new Headers(init.headers || {});\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n const url = `${normalizedBaseUrl}${cleanPath}`;\n\n return fetch(url, {\n ...init,\n headers,\n });\n }\n\n return {\n baseUrl: normalizedBaseUrl,\n getAuthToken,\n defaultAgentId,\n fetchWithAuth,\n };\n }, [normalizedBaseUrl, getAuthToken, defaultAgentId]);\n\n return <PersonaContext.Provider value={value}>{children}</PersonaContext.Provider>;\n}\n\nexport function usePersonaContext(): PersonaContextValue {\n const context = useContext(PersonaContext);\n if (!context) {\n throw new Error('usePersonaContext must be used within a <PersonaProvider>');\n }\n return context;\n}\n","'use client';\r\n\r\nimport { useCallback, useEffect, 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 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('{')) 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 | { type: 'tool'; name: string; argsText: string; resultText: string; status: 'running' | 'completed' };\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(items: PersistedSubagentTraceItem[]): 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({ kind: 'tool_start', toolName: item.name, args: item.argsText });\r\n if (item.status === 'completed') {\r\n entries.push({ kind: 'tool_result', toolName: item.name, result: item.resultText });\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') return null;\r\n return {\r\n path: parsed.filePath,\r\n title: typeof parsed.title === 'string' ? parsed.title : parsed.filePath,\r\n description: typeof parsed.description === 'string' ? parsed.description : '',\r\n };\r\n } catch {\r\n return null;\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<string, { content: string; size: number; created_at: string | null; modified_at: string | null }>\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<PersonaInterrupt, { kind: 'clarification' }>['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 } = usePersonaContext();\r\n const agentId = options.agentId || defaultAgentId;\r\n const threadId = options.threadId;\r\n\r\n const [messages, setMessages] = useState<PersonaMessage[]>(options.initialMessages || []);\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] = useState<PersonaPresentedFile | null>(null);\r\n\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\r\n\r\n const stop = useCallback(() => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n abortControllerRef.current = null;\r\n setIsStreaming(false);\r\n }\r\n }, []);\r\n\r\n const clear = useCallback(() => {\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 }, [stop]);\r\n\r\n const loadThreadMessages = useCallback(\r\n async (id: string) => {\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) 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<string, PersistedSubagentTraceItem[]>;\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 ? { ...tc, subagentActivity: persistedTraceToActivityEntries(trace) }\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 return loaded;\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 setIsLoadingHistory(false);\r\n }\r\n },\r\n [fetchWithAuth]\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 (!threadId || isStreaming) return;\r\n if (loadedThreadIdRef.current === threadId) return;\r\n if (messages.length > 0) return;\r\n loadedThreadIdRef.current = threadId;\r\n void loadThreadMessages(threadId);\r\n }, [threadId, isStreaming, messages.length, loadThreadMessages]);\r\n\r\n const sendMessage = useCallback(\r\n async (contentToSend?: string, overrideOptions?: SendMessageOverride) => {\r\n const prompt = (contentToSend ?? input).trim();\r\n if (!prompt || isStreaming) return;\r\n\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 setError(err);\r\n options.onError?.(err);\r\n return;\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 = [...messages, 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 // Marks any reasoning message still flagged streaming as done — for\r\n // runs that end (abort/error) without a final REASONING_END. Declared\r\n // outside the try so the finally block can reach it.\r\n const finalizeReasoning = () => {\r\n setMessages((prev) =>\r\n prev.map((m) =>\r\n m.role === 'reasoning' && m.isStreaming ? { ...m, isStreaming: false } : m\r\n )\r\n );\r\n };\r\n\r\n try {\r\n // Reasoning messages are ephemeral client-side thoughts — never part\r\n // of the transcript sent back to the server (the backend already has\r\n // its own persisted copy and would treat them as user turns).\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 // Resolved here, not earlier — everything above this line (the\r\n // optimistic message + placeholder, clearing input, etc.) already\r\n // ran synchronously, so a caller passing an in-flight thread-creation\r\n // promise gets an instant UI update without the message send itself\r\n // waiting on it any longer than the network call already would.\r\n const resolvedThreadId = await (overrideOptions?.threadId ?? options.threadId);\r\n\r\n // openSSEStream, not fetchWithAuth: the transport has to be chosen\r\n // before the request goes out. React Native's fetch never populates\r\n // response.body and only settles once the whole response has arrived,\r\n // so discovering the missing body afterwards would already have cost\r\n // us the stream. See src/streaming.ts.\r\n const token = getAuthToken ? await getAuthToken() : null;\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 }),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!stream.ok) {\r\n throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? 'Stream failed'}`);\r\n }\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 // Reasoning streams as its own `role: 'reasoning'` message per phase\r\n // (REASONING_MESSAGE_START … CONTENT … REASONING_END), never merged\r\n // into the assistant message or into a single accumulated blob —\r\n // mirrors the web timeline where each phase is a separate \"Thoughts\"\r\n // bubble. Each phase's message is inserted directly above the assistant\r\n // message so thoughts render above the answer, not underneath it.\r\n //\r\n // A monotonic counter shared by reasoning phases AND tool calls stamps\r\n // each with a `seq` in stream order (the backend emits REASONING_END\r\n // right before the next TOOL_CALL_CHUNK, then the next phase after the\r\n // result). Clients sort by it to interleave thoughts and tool calls\r\n // chronologically instead of stacking all thoughts above the answer.\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\r\n ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch }\r\n : msg\r\n )\r\n );\r\n };\r\n\r\n const insertReasoningMessage = (id: string, seq: number) => {\r\n const msg: PersonaMessage = {\r\n id,\r\n role: 'reasoning',\r\n content: '',\r\n createdAt: new Date(),\r\n isStreaming: true,\r\n seq,\r\n };\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\r\n buffer += value ?? '';\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() ?? '';\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || !trimmed.startsWith('data:')) continue;\r\n\r\n const raw = trimmed.replace(/^data:\\s*/, '');\r\n if (raw === '[DONE]') break;\r\n\r\n try {\r\n const event = JSON.parse(raw) as PersonaStreamingEvent;\r\n options.onEvent?.(event);\r\n\r\n if (event.type === 'TEXT_MESSAGE_CHUNK' && event.delta) {\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 // The backend streams tool calls as accumulating chunks\r\n // (id/name arrive on the first chunk, args stream in pieces\r\n // across subsequent ones) rather than separate start/args\r\n // events.\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 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.toolName === 'present_file' && !existing.isError) {\r\n const presented = parsePresentedFile(event.content);\r\n if (presented) setPresentedFile(presented);\r\n }\r\n patchAssistant({});\r\n }\r\n } else if (event.type === 'STATE_SNAPSHOT') {\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 // A fresh reasoning phase — its own message, regardless of how\r\n // many phases this run produces. seq stamps it into stream\r\n // order against the tool calls it brackets.\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 // Defensive: if the backend ever skips REASONING_MESSAGE_START,\r\n // lazily open the message on the first content chunk.\r\n let rid: string = event.messageId || activeReasoningId || '';\r\n if (!rid || !reasoningById.has(rid)) {\r\n rid =\r\n 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 }\r\n const entry = reasoningById.get(rid)!;\r\n entry.content += event.delta;\r\n setMessages((prev) =>\r\n prev.map((m) =>\r\n m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m\r\n )\r\n );\r\n } else if (event.type === 'REASONING_END') {\r\n const rid = activeReasoningId;\r\n activeReasoningId = null;\r\n if (rid) {\r\n setMessages((prev) =>\r\n prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m))\r\n );\r\n }\r\n } else if (event.type === 'CUSTOM') {\r\n if (event.name === 'hitl_request') {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: 'hitl' }>;\r\n setInterrupt({\r\n kind: 'hitl',\r\n actionRequests: value.actionRequests,\r\n reviewConfigs: value.reviewConfigs,\r\n });\r\n } else if (event.name === 'clarification_request') {\r\n const value = event.value as Extract<PersonaInterrupt, { kind: 'clarification' }>;\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 const existing = toolCallsMap.get(toolCallId);\r\n if (existing) {\r\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\r\n patchAssistant({});\r\n }\r\n }\r\n // 'mcp_app' custom events carry no chat-transcript UI here —\r\n // consumers that render MCP widgets read them via onEvent.\r\n } else if (event.type === 'RUN_ERROR') {\r\n throw new Error(event.message || 'Stream error from agent');\r\n }\r\n } catch (e) {\r\n if (e instanceof Error && e.message.startsWith('Stream error')) {\r\n throw e;\r\n }\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\r\n setMessages((prev) =>\r\n prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg))\r\n );\r\n\r\n options.onFinish?.(finalMessage);\r\n } catch (err) {\r\n if (controller.signal.aborted) {\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg\r\n )\r\n );\r\n return;\r\n }\r\n\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n options.onError?.(errorObj);\r\n\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId\r\n ? {\r\n ...msg,\r\n content:\r\n msg.content || `⚠️ Error: ${errorObj.message || 'Failed to get response.'}`,\r\n isStreaming: false,\r\n }\r\n : msg\r\n )\r\n );\r\n } finally {\r\n setIsStreaming(false);\r\n abortControllerRef.current = null;\r\n // A run that ends without a final REASONING_END (abort, error) must\r\n // still flip its in-flight reasoning messages to done.\r\n finalizeReasoning();\r\n }\r\n },\r\n [agentId, baseUrl, getAuthToken, input, isStreaming, messages, options]\r\n );\r\n\r\n const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n setInput(e.target.value);\r\n }, []);\r\n\r\n const handleSubmit = useCallback(\r\n (e?: React.FormEvent) => {\r\n if (e) e.preventDefault();\r\n void sendMessage();\r\n },\r\n [sendMessage]\r\n );\r\n\r\n const reload = useCallback(() => {\r\n if (messages.length === 0 || isStreaming) return;\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) return;\r\n\r\n const lastUserMessage = messages[lastUserIndex];\r\n setMessages(messages.slice(0, lastUserIndex));\r\n void sendMessage(lastUserMessage.content);\r\n }, [isStreaming, messages, sendMessage]);\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) => sendMessage(displayContent, { resume }),\r\n [sendMessage]\r\n );\r\n\r\n const dismissPresentedFile = useCallback(() => setPresentedFile(null), []);\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) => setPresentedFile({ path, title: path.split('/').pop() || path, description: '' }),\r\n []\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 stop,\r\n reload,\r\n clear,\r\n setMessages,\r\n loadThreadMessages,\r\n };\r\n}\r\n","/**\n * SSE transport for chat streams, with a React Native fallback.\n *\n * On the web, `fetch` gives a streaming `response.body` and we read it with a\n * ReadableStream reader. React Native's `fetch` is the whatwg-fetch polyfill\n * over XMLHttpRequest: `response.body` is `undefined`, and the promise only\n * settles once the entire response has arrived. That means the check cannot be\n * \"call fetch, then see whether body exists\" - by that point the whole stream\n * has already been buffered and the chance to stream is gone. The transport has\n * to be chosen *before* the request is made.\n *\n * XMLHttpRequest itself does stream everywhere React Native runs: it appends to\n * `responseText` and fires `readyState === 3` (LOADING) on every chunk, which is\n * all an SSE consumer needs. So the RN path issues the request over raw XHR and\n * hands back the same reader interface the fetch path does, leaving callers\n * unaware of which one they got.\n */\n\n/** Minimal reader interface, mirroring the shape of a ReadableStream reader. */\nexport interface SSEReader {\n /** Resolves with the next decoded chunk, or `{ done: true }` at end of stream. */\n read(): Promise<{ done: boolean; value?: string }>;\n /** Aborts the underlying request. */\n cancel(): void;\n}\n\nexport interface SSEStream {\n status: number;\n ok: boolean;\n getHeader(name: string): string | null;\n /** Present only when `ok` is false, so callers can surface the server's message. */\n errorText?: string;\n reader: SSEReader;\n}\n\nexport interface OpenSSEOptions {\n url: string;\n headers: Record<string, string>;\n body: string;\n signal?: AbortSignal;\n}\n\n/**\n * Whether `fetch` on this platform yields a streaming body.\n *\n * `navigator.product === 'ReactNative'` is the long-standing marker React\n * Native sets, and is checked rather than feature-detecting `ReadableStream`:\n * newer RN versions do expose a global `ReadableStream` while still leaving\n * `response.body` undefined, so the presence of the type says nothing about\n * whether fetch will populate it.\n */\nexport function supportsStreamingFetch(): boolean {\n if (typeof navigator !== 'undefined' && (navigator as { product?: string }).product === 'ReactNative') {\n return false;\n }\n return typeof fetch !== 'undefined' && typeof ReadableStream !== 'undefined';\n}\n\n/** Wraps a whatwg ReadableStream reader so it decodes to strings. */\nfunction fetchReader(response: Response, controller: AbortController): SSEReader {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder('utf-8');\n\n return {\n async read() {\n const { done, value } = await reader.read();\n if (done) return { done: true };\n return { done: false, value: decoder.decode(value, { stream: true }) };\n },\n cancel() {\n controller.abort();\n void reader.cancel().catch(() => {});\n },\n };\n}\n\n/**\n * Issues the request over XMLHttpRequest and exposes new text as it arrives.\n *\n * XHR keeps the whole response in `responseText` and only ever appends, so each\n * chunk is the slice past what has already been handed out.\n */\nfunction xhrStream(opts: OpenSSEOptions): Promise<SSEStream> {\n return new Promise<SSEStream>((resolveStream, rejectStream) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', opts.url);\n for (const [key, val] of Object.entries(opts.headers)) xhr.setRequestHeader(key, val);\n\n let consumed = 0;\n let finished = false;\n let failure: Error | null = null;\n // Chunks that arrived before the consumer asked for them, and the pending\n // read waiting for one - only one of the two is ever non-empty.\n const queue: string[] = [];\n let waiting: ((r: { done: boolean; value?: string }) => void) | null = null;\n let waitingReject: ((e: Error) => void) | null = null;\n let headersResolved = false;\n\n const pump = () => {\n const text = xhr.responseText;\n if (text.length <= consumed) return;\n const chunk = text.slice(consumed);\n consumed = text.length;\n\n if (waiting) {\n const resolve = waiting;\n waiting = null;\n waitingReject = null;\n resolve({ done: false, value: chunk });\n } else {\n queue.push(chunk);\n }\n };\n\n const finish = (err?: Error) => {\n if (finished) return;\n finished = true;\n failure = err ?? null;\n if (waiting) {\n const resolve = waiting;\n const reject = waitingReject;\n waiting = null;\n waitingReject = null;\n if (err && reject) reject(err);\n else resolve({ done: true });\n }\n };\n\n const reader: SSEReader = {\n read() {\n if (queue.length > 0) {\n return Promise.resolve({ done: false, value: queue.shift() });\n }\n if (finished) {\n return failure ? Promise.reject(failure) : Promise.resolve({ done: true });\n }\n return new Promise((resolve, reject) => {\n waiting = resolve;\n waitingReject = reject;\n });\n },\n cancel() {\n finish();\n xhr.abort();\n },\n };\n\n // Headers are available from readyState 2, which is what lets a non-2xx\n // response be reported without waiting for the body to finish.\n const resolveHeaders = () => {\n if (headersResolved) return;\n headersResolved = true;\n const ok = xhr.status >= 200 && xhr.status < 300;\n resolveStream({\n status: xhr.status,\n ok,\n getHeader: (name: string) => xhr.getResponseHeader(name),\n reader,\n });\n };\n\n xhr.onreadystatechange = () => {\n if (xhr.readyState === 2) {\n resolveHeaders();\n } else if (xhr.readyState === 3) {\n resolveHeaders();\n pump();\n } else if (xhr.readyState === 4) {\n resolveHeaders();\n pump();\n finish();\n }\n };\n\n xhr.onerror = () => {\n const err = new Error('Network request failed');\n if (!headersResolved) rejectStream(err);\n finish(err);\n };\n xhr.ontimeout = () => {\n const err = new Error('Network request timed out');\n if (!headersResolved) rejectStream(err);\n finish(err);\n };\n\n if (opts.signal) {\n if (opts.signal.aborted) {\n xhr.abort();\n finish();\n } else {\n opts.signal.addEventListener('abort', () => {\n finish();\n xhr.abort();\n });\n }\n }\n\n xhr.send(opts.body);\n });\n}\n\n/**\n * Opens an SSE stream, using whichever transport this platform can stream over.\n */\nexport async function openSSEStream(opts: OpenSSEOptions): Promise<SSEStream> {\n if (!supportsStreamingFetch()) {\n return xhrStream(opts);\n }\n\n const controller = new AbortController();\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort();\n else opts.signal.addEventListener('abort', () => controller.abort());\n }\n\n const response = await fetch(opts.url, {\n method: 'POST',\n headers: opts.headers,\n body: opts.body,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Stream failed');\n return {\n status: response.status,\n ok: false,\n errorText,\n getHeader: (name: string) => response.headers.get(name),\n reader: { read: async () => ({ done: true }), cancel: () => controller.abort() },\n };\n }\n\n if (!response.body) {\n // A streaming-capable platform that still gave no body - fall back to the\n // buffered text rather than failing outright.\n const text = await response.text();\n let handed = false;\n return {\n status: response.status,\n ok: true,\n getHeader: (name: string) => response.headers.get(name),\n reader: {\n read: async () => (handed ? { done: true } : ((handed = true), { done: false, value: text })),\n cancel: () => controller.abort(),\n },\n };\n }\n\n return {\n status: response.status,\n ok: true,\n getHeader: (name: string) => response.headers.get(name),\n reader: fetchReader(response, controller),\n };\n}\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\nimport type { PersonaMemoryFile, PersonaMemoryList } from '../types.js';\n\nexport function useMemory(autoFetch = true) {\n const { fetchWithAuth } = usePersonaContext();\n const [memory, setMemory] = useState<PersonaMemoryList>({ userFiles: [], agentMemories: [] });\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchMemory = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth('/memory');\n if (!res.ok) {\n throw new Error(`Failed to fetch memory: ${res.statusText}`);\n }\n const data = (await res.json()) as PersonaMemoryList;\n setMemory(data);\n return data;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return { userFiles: [], agentMemories: [] };\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth]);\n\n const getFile = useCallback(\n async (params: { path: string; scope?: 'user' | 'agent'; agentId?: string }) => {\n const query = new URLSearchParams({ path: params.path });\n if (params.scope) query.set('scope', params.scope);\n if (params.agentId) query.set('agentId', params.agentId);\n\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`);\n if (!res.ok) throw new Error(`Failed to get memory file: ${res.statusText}`);\n return (await res.json()) as PersonaMemoryFile;\n },\n [fetchWithAuth]\n );\n\n const writeFile = useCallback(\n async (params: { path: string; content: string; scope?: 'user' | 'agent'; agentId?: string }) => {\n const res = await fetchWithAuth('/memory/file', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(params),\n });\n if (!res.ok) throw new Error(`Failed to write memory file: ${res.statusText}`);\n const updated = (await res.json()) as PersonaMemoryFile;\n void fetchMemory();\n return updated;\n },\n [fetchWithAuth, fetchMemory]\n );\n\n const deleteFile = useCallback(\n async (params: { path: string; scope?: 'user' | 'agent'; agentId?: string }) => {\n const query = new URLSearchParams({ path: params.path });\n if (params.scope) query.set('scope', params.scope);\n if (params.agentId) query.set('agentId', params.agentId);\n\n const res = await fetchWithAuth(`/memory/file?${query.toString()}`, {\n method: 'DELETE',\n });\n if (!res.ok) throw new Error(`Failed to delete memory file: ${res.statusText}`);\n void fetchMemory();\n },\n [fetchWithAuth, fetchMemory]\n );\n\n useEffect(() => {\n if (autoFetch) {\n void fetchMemory();\n }\n }, [autoFetch, fetchMemory]);\n\n return {\n memory,\n isLoading,\n error,\n refetch: fetchMemory,\n getFile,\n writeFile,\n deleteFile,\n };\n}\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 || data?.threads || (Array.isArray(data?.data) ? data.data : undefined) || [];\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) 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}`, { method: 'DELETE' });\n if (!res.ok) 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) throw new Error(`Failed to bulk-delete threads: ${res.statusText}`);\n const data = await res.json();\n const result = (data?.data ?? data) as { deleted: string[]; failed: Array<{ id: string; reason: string }> };\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 (threadId: string, input: { title?: string; isArchived?: boolean }) => {\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) 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) => prev.map((t) => (t._id === threadId ? { ...t, ...updated } : t)));\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 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 getThread,\n };\n}\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\nimport type { PersonaFileItem } from '../types.js';\n\nexport type { PersonaFileItem };\n\nexport function useFiles(autoFetch = true) {\n const { fetchWithAuth } = usePersonaContext();\n const [files, setFiles] = useState<PersonaFileItem[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchFiles = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth('/files');\n if (!res.ok) throw new Error(`Failed to list files: ${res.statusText}`);\n const data = await res.json();\n // Real shape is { items, pagination } — bare array/`.files` are\n // defensive fallbacks, not the actual wire contract.\n const items: PersonaFileItem[] = Array.isArray(data)\n ? data\n : data?.items || data?.files || [];\n setFiles(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 uploadFile = useCallback(\n async (fileOrFormData: FormData | { name: string; uri: string; type?: string }) => {\n setIsUploading(true);\n setError(null);\n try {\n let body: FormData;\n if (fileOrFormData instanceof FormData) {\n body = fileOrFormData;\n } else {\n // React Native FormData support\n body = new FormData();\n body.append('file', fileOrFormData as unknown as Blob);\n }\n\n const res = await fetchWithAuth('/files', {\n method: 'POST',\n body,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => 'Upload failed');\n throw new Error(`Upload error (${res.status}): ${errText}`);\n }\n\n const uploaded = (await res.json()) as PersonaFileItem;\n void fetchFiles();\n return uploaded;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsUploading(false);\n }\n },\n [fetchWithAuth, fetchFiles]\n );\n\n const deleteFile = useCallback(\n async (fileId: string) => {\n const res = await fetchWithAuth(`/files/${fileId}`, { method: 'DELETE' });\n if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);\n setFiles((prev) => prev.filter((f) => f.id !== fileId));\n },\n [fetchWithAuth]\n );\n\n const bulkDeleteFiles = useCallback(\n async (fileIds: string[]) => {\n const res = await fetchWithAuth('/files/bulk-delete', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ ids: fileIds }),\n });\n if (!res.ok) throw new Error(`Failed to bulk-delete files: ${res.statusText}`);\n const idSet = new Set(fileIds);\n setFiles((prev) => prev.filter((f) => !idSet.has(f.id)));\n return (await res.json()) as { deleted: string[]; failed: Array<{ id: string; reason: string }> };\n },\n [fetchWithAuth]\n );\n\n const getDownloadUrl = useCallback(\n (fileId: string) => {\n return `/files/${fileId}`;\n },\n []\n );\n\n useEffect(() => {\n if (autoFetch) {\n void fetchFiles();\n }\n }, [autoFetch, fetchFiles]);\n\n return {\n files,\n isLoading,\n isUploading,\n error,\n refetch: fetchFiles,\n uploadFile,\n deleteFile,\n bulkDeleteFiles,\n getDownloadUrl,\n };\n}\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\n\nexport interface PersonaAgentSummary {\n _id: string;\n name: string;\n slug: string;\n description?: string;\n tagline?: string;\n avatar?: string;\n}\n\nexport function useAgents(autoFetch = true) {\n const { fetchWithAuth } = usePersonaContext();\n const [agents, setAgents] = useState<PersonaAgentSummary[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchAgents = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetchWithAuth('/agents');\n if (!res.ok) throw new Error(`Failed to list agents: ${res.statusText}`);\n const data = await res.json();\n // Real shape is { items, pagination }.\n const items: PersonaAgentSummary[] = Array.isArray(data)\n ? data\n : data?.items || data?.agents || [];\n setAgents(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 useEffect(() => {\n if (autoFetch) {\n void fetchAgents();\n }\n }, [autoFetch, fetchAgents]);\n\n return {\n agents,\n isLoading,\n error,\n refetch: fetchAgents,\n };\n}\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\n\nexport interface PersonaHealthInfo {\n status: string;\n version?: string;\n capabilities?: Record<string, boolean>;\n}\n\nexport function useConnection(autoCheck = true) {\n const { fetchWithAuth } = usePersonaContext();\n const [health, setHealth] = useState<PersonaHealthInfo | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n\n const checkHealth = useCallback(async () => {\n setIsLoading(true);\n try {\n const res = await fetchWithAuth('/health');\n if (res.ok) {\n const data = (await res.json()) as PersonaHealthInfo;\n setHealth(data);\n setIsConnected(true);\n return data;\n }\n setIsConnected(false);\n return null;\n } catch {\n setIsConnected(false);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [fetchWithAuth]);\n\n useEffect(() => {\n if (autoCheck) {\n void checkHealth();\n }\n }, [autoCheck, checkHealth]);\n\n return {\n isConnected,\n health,\n isLoading,\n checkHealth,\n };\n}\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\n\n/**\n * One `authType: 'oauth', authMode: 'user'` MCP an Agent has attached, and\n * whether the current end user has connected it yet. `authorizeUrl` is only\n * present when `connected` is `false` — navigate the browser there (a\n * same-tab redirect is fine; it's a real OAuth authorization URL) to start\n * the consent flow.\n */\nexport interface PersonaMcpConnection {\n mcpId: string;\n name: string;\n description: string;\n connected: boolean;\n authorizeUrl: string | null;\n}\n\nexport interface UseMcpConnectionsOptions {\n /** @default the PersonaProvider's defaultAgentId */\n agentId?: string;\n /** Where the browser lands after OAuth consent completes. @default window.location.href */\n returnTo?: string;\n /** @default true */\n autoFetch?: boolean;\n}\n\n/**\n * Surfaces the gap that used to be invisible entirely: a user-mode MCP tool\n * call for a user who hasn't connected yet is silently dropped from the\n * Agent's toolset server-side, with no signal in the chat stream at all.\n * Check this before (or alongside) a chat session to show a real \"Connect\n * your account\" affordance instead of a capability that just quietly isn't\n * there.\n */\nexport function useMcpConnections(options: UseMcpConnectionsOptions = {}) {\n const { defaultAgentId, fetchWithAuth } = usePersonaContext();\n const agentId = options.agentId ?? defaultAgentId;\n const autoFetch = options.autoFetch ?? true;\n\n const [connections, setConnections] = useState<PersonaMcpConnection[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchConnections = useCallback(async () => {\n if (!agentId) return [];\n setIsLoading(true);\n setError(null);\n try {\n const returnTo =\n options.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : '';\n const res = await fetchWithAuth(`/agents/${agentId}/mcp-connections${query}`);\n if (!res.ok) throw new Error(`Failed to load MCP connections: ${res.statusText}`);\n const data = await res.json();\n const items: PersonaMcpConnection[] = Array.isArray(data) ? data : data?.items || [];\n setConnections(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 }, [agentId, fetchWithAuth, options.returnTo]);\n\n useEffect(() => {\n if (autoFetch) void fetchConnections();\n }, [autoFetch, fetchConnections]);\n\n return {\n connections,\n /** Convenience filter for the common \"show a banner for what's missing\" case. */\n unconnected: connections.filter((c) => !c.connected),\n isLoading,\n error,\n refetch: fetchConnections,\n };\n}\n"],"mappings":"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","names":["import_react","value","import_react","import_react","import_react","import_react","import_react","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts"],"sourcesContent":["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/useFiles.js\";\r\nexport * from \"./hooks/useAgents.js\";\r\nexport * from \"./hooks/useConnection.js\";\r\nexport * from \"./hooks/useMcpConnections.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.5.4\";\r\n","\"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 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// 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\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 const abortControllerRef = useRef<AbortController | null>(null);\r\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\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 }, [stop, chatLogger, messages.length]);\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 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 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 (!threadId || isStreaming) {\r\n chatLogger.trace(\"auto-load skipped\", { threadId, isStreaming });\r\n return;\r\n }\r\n if (loadedThreadIdRef.current === threadId) {\r\n chatLogger.trace(\"auto-load already loaded\", { threadId });\r\n return;\r\n }\r\n if (messages.length > 0) {\r\n chatLogger.trace(\"auto-load has messages\", {\r\n threadId,\r\n count: messages.length,\r\n });\r\n return;\r\n }\r\n loadedThreadIdRef.current = threadId;\r\n chatLogger.info(\"auto-load thread history\", { threadId });\r\n chatLogger.debug(\"loadThreadMessages trigger\", { threadId });\r\n void loadThreadMessages(threadId);\r\n }, [threadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);\r\n\r\n const sendMessage = useCallback(\r\n async (contentToSend?: string, overrideOptions?: SendMessageOverride) => {\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 return;\r\n }\r\n\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\", {\r\n error: err.message,\r\n });\r\n setError(err);\r\n options.onError?.(err);\r\n return;\r\n }\r\n\r\n chatLogger.debug(\"sendMessage start\", {\r\n promptPreview: prompt.slice(0, 100),\r\n agentId: targetAgentId,\r\n threadId: threadId ?? (overrideOptions?.threadId as string | undefined),\r\n hasResume: !!overrideOptions?.resume,\r\n messageCount: messages.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 });\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 = [...messages, 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 // Marks any reasoning message still flagged streaming as done — for\r\n // runs that end (abort/error) without a final REASONING_END. Declared\r\n // outside the try so the finally block can reach it.\r\n const finalizeReasoning = () => {\r\n setMessages((prev) =>\r\n prev.map((m) =>\r\n m.role === \"reasoning\" && m.isStreaming\r\n ? { ...m, isStreaming: false }\r\n : m,\r\n ),\r\n );\r\n };\r\n\r\n try {\r\n // Reasoning messages are ephemeral client-side thoughts — never part\r\n // of the transcript sent back to the server (the backend already has\r\n // its own persisted copy and would treat them as user turns).\r\n const payloadMessages = nextMessages\r\n .filter((m) => m.role !== \"reasoning\")\r\n .map((m) => ({\r\n role:\r\n m.role === \"assistant\"\r\n ? (\"assistant\" as const)\r\n : (\"user\" as const),\r\n content: m.content,\r\n }));\r\n\r\n // Resolved here, not earlier — everything above this line (the\r\n // optimistic message + placeholder, clearing input, etc.) already\r\n // ran synchronously, so a caller passing an in-flight thread-creation\r\n // promise gets an instant UI update without the message send itself\r\n // waiting on it any longer than the network call already would.\r\n const resolvedThreadId = await (overrideOptions?.threadId ??\r\n options.threadId);\r\n chatLogger.trace(\"resolved threadId\", { threadId: resolvedThreadId });\r\n\r\n // openSSEStream, not fetchWithAuth: the transport has to be chosen\r\n // before the request goes out. React Native's fetch never populates\r\n // response.body and only settles once the whole response has arrived,\r\n // so discovering the missing body afterwards would already have cost\r\n // us the stream. See src/streaming.ts.\r\n const token = getAuthToken ? await getAuthToken() : null;\r\n chatLogger.debug(\"opening SSE stream\", {\r\n agentId: targetAgentId,\r\n hasToken: !!token,\r\n hasThreadId: !!resolvedThreadId,\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 }),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!stream.ok) {\r\n chatLogger.warn(\"SSE stream not ok\", {\r\n status: stream.status,\r\n errorText: stream.errorText,\r\n });\r\n chatLogger.error(\"chat stream failed\", {\r\n agentId: targetAgentId,\r\n status: stream.status,\r\n error: stream.errorText,\r\n });\r\n throw new Error(\r\n `Chat error (${stream.status}): ${stream.errorText ?? \"Stream failed\"}`,\r\n );\r\n }\r\n chatLogger.debug(\"SSE stream opened\", {\r\n agentId: targetAgentId,\r\n status: stream.status,\r\n });\r\n chatLogger.info(\"chat stream started\", {\r\n agentId: targetAgentId,\r\n threadId: resolvedThreadId,\r\n });\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 // Reasoning streams as its own `role: 'reasoning'` message per phase\r\n // (REASONING_MESSAGE_START … CONTENT … REASONING_END), never merged\r\n // into the assistant message or into a single accumulated blob —\r\n // mirrors the web timeline where each phase is a separate \"Thoughts\"\r\n // bubble. Each phase's message is inserted directly above the assistant\r\n // message so thoughts render above the answer, not underneath it.\r\n //\r\n // A monotonic counter shared by reasoning phases AND tool calls stamps\r\n // each with a `seq` in stream order (the backend emits REASONING_END\r\n // right before the next TOOL_CALL_CHUNK, then the next phase after the\r\n // result). Clients sort by it to interleave thoughts and tool calls\r\n // chronologically instead of stacking all thoughts above the answer.\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\r\n ? {\r\n ...msg,\r\n toolCalls: Array.from(toolCallsMap.values()),\r\n ...patch,\r\n }\r\n : msg,\r\n ),\r\n );\r\n };\r\n\r\n const insertReasoningMessage = (id: string, seq: number) => {\r\n const msg: PersonaMessage = {\r\n id,\r\n role: \"reasoning\",\r\n content: \"\",\r\n createdAt: new Date(),\r\n isStreaming: true,\r\n seq,\r\n };\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\r\n buffer += value ?? \"\";\r\n const lines = buffer.split(\"\\n\");\r\n buffer = lines.pop() ?? \"\";\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || !trimmed.startsWith(\"data:\")) continue;\r\n\r\n const raw = trimmed.replace(/^data:\\s*/, \"\");\r\n if (raw === \"[DONE]\") break;\r\n\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\r\n if (event.type === \"TEXT_MESSAGE_CHUNK\" && event.delta) {\r\n chatLogger.debug(\"text chunk\", {\r\n deltaLength: event.delta.length,\r\n });\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\", {\r\n toolCallId: event.toolCallId,\r\n toolCallName: event.toolCallName,\r\n });\r\n // The backend streams tool calls as accumulating chunks\r\n // (id/name arrive on the first chunk, args stream in pieces\r\n // across subsequent ones) rather than separate start/args\r\n // events.\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\", {\r\n toolCallId: event.toolCallId,\r\n });\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)\r\n chatLogger.warn(\"tool call error\", {\r\n toolCallId: event.toolCallId,\r\n });\r\n if (\r\n existing.toolName === \"present_file\" &&\r\n !existing.isError\r\n ) {\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 (\r\n event.type === \"REASONING_MESSAGE_START\" &&\r\n event.messageId\r\n ) {\r\n chatLogger.debug(\"reasoning start\", {\r\n messageId: event.messageId,\r\n });\r\n // A fresh reasoning phase — its own message, regardless of how\r\n // many phases this run produces. seq stamps it into stream\r\n // order against the tool calls it brackets.\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 // Defensive: if the backend ever skips REASONING_MESSAGE_START,\r\n // lazily open the message on the first content chunk.\r\n let rid: string = event.messageId || activeReasoningId || \"\";\r\n if (!rid || !reasoningById.has(rid)) {\r\n rid =\r\n rid ||\r\n `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\", {\r\n messageId: rid,\r\n deltaLength: event.delta?.length ?? 0,\r\n });\r\n setMessages((prev) =>\r\n prev.map((m) =>\r\n m.id === rid\r\n ? { ...m, content: entry.content, isStreaming: true }\r\n : m,\r\n ),\r\n );\r\n } else if (event.type === \"REASONING_END\") {\r\n chatLogger.debug(\"reasoning end\", {\r\n messageId: activeReasoningId,\r\n });\r\n const rid = activeReasoningId;\r\n activeReasoningId = null;\r\n if (rid) {\r\n setMessages((prev) =>\r\n prev.map((m) =>\r\n m.id === rid ? { ...m, isStreaming: false } : m,\r\n ),\r\n );\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<\r\n PersonaInterrupt,\r\n { kind: \"hitl\" }\r\n >;\r\n chatLogger.info(\"hitl interrupt\", {\r\n actionCount: value.actionRequests?.length ?? 0,\r\n });\r\n setInterrupt({\r\n kind: \"hitl\",\r\n actionRequests: value.actionRequests,\r\n reviewConfigs: value.reviewConfigs,\r\n });\r\n } else if (event.name === \"clarification_request\") {\r\n const value = event.value as Extract<\r\n PersonaInterrupt,\r\n { kind: \"clarification\" }\r\n >;\r\n chatLogger.info(\"clarification interrupt\", {\r\n questionCount: value.questions?.length ?? 0,\r\n });\r\n setInterrupt({\r\n kind: \"clarification\",\r\n questions: value.questions,\r\n });\r\n } else if (event.name === \"subagent_activity\") {\r\n const { toolCallId, ...entry } = event.value as {\r\n toolCallId: string;\r\n } & PersonaSubagentActivityEntry;\r\n chatLogger.trace(\"subagent activity\", {\r\n toolCallId,\r\n kind: entry.kind,\r\n });\r\n const existing = toolCallsMap.get(toolCallId);\r\n if (existing) {\r\n existing.subagentActivity = [\r\n ...(existing.subagentActivity || []),\r\n entry,\r\n ];\r\n patchAssistant({});\r\n }\r\n }\r\n // 'mcp_app' custom events carry no chat-transcript UI here —\r\n // consumers that render MCP widgets read them via onEvent.\r\n } else if (event.type === \"RUN_ERROR\") {\r\n chatLogger.warn(\"run error\", {\r\n message: event.message,\r\n code: event.code,\r\n });\r\n chatLogger.error(\"stream run error\", {\r\n code: event.code,\r\n message: event.message,\r\n });\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\")) {\r\n throw e;\r\n }\r\n chatLogger.warn(\"event parse error\", {\r\n raw: raw.slice(0, 200),\r\n error: e instanceof Error ? e.message : String(e),\r\n });\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\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId ? finalMessage : msg,\r\n ),\r\n );\r\n\r\n chatLogger.info(\"sendMessage succeeded\", {\r\n agentId: targetAgentId,\r\n textLength: accumulatedText.length,\r\n toolCallCount: toolCallsMap.size,\r\n });\r\n chatLogger.debug(\"sendMessage completed\", {\r\n agentId: targetAgentId,\r\n textLength: accumulatedText.length,\r\n eventCount: toolCallsMap.size + 1,\r\n });\r\n options.onFinish?.(finalMessage);\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) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId\r\n ? { ...msg, isStreaming: false }\r\n : msg,\r\n ),\r\n );\r\n return;\r\n }\r\n\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n chatLogger.warn(\"sendMessage failed\", {\r\n agentId: targetAgentId,\r\n error: errorObj.message,\r\n });\r\n chatLogger.error(\"sendMessage error\", {\r\n agentId: targetAgentId,\r\n error: errorObj.message,\r\n });\r\n setError(errorObj);\r\n options.onError?.(errorObj);\r\n\r\n setMessages((prev) =>\r\n prev.map((msg) =>\r\n msg.id === assistantMessageId\r\n ? {\r\n ...msg,\r\n content:\r\n msg.content ||\r\n `⚠️ Error: ${errorObj.message || \"Failed to get response.\"}`,\r\n isStreaming: false,\r\n }\r\n : msg,\r\n ),\r\n );\r\n } finally {\r\n setIsStreaming(false);\r\n abortControllerRef.current = null;\r\n // A run that ends without a final REASONING_END (abort, error) must\r\n // still flip its in-flight reasoning messages to done.\r\n finalizeReasoning();\r\n chatLogger.debug(\"sendMessage finally\", {\r\n agentId: targetAgentId,\r\n isStreaming: false,\r\n });\r\n chatLogger.trace(\"sendMessage end\", { agentId: targetAgentId });\r\n }\r\n },\r\n [\r\n agentId,\r\n baseUrl,\r\n getAuthToken,\r\n input,\r\n isStreaming,\r\n messages,\r\n options,\r\n chatLogger,\r\n threadId,\r\n ],\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(() => {\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;\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;\r\n }\r\n\r\n const lastUserMessage = messages[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 setMessages(messages.slice(0, lastUserIndex));\r\n void sendMessage(lastUserMessage.content);\r\n }, [isStreaming, messages, sendMessage, 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 stop,\r\n reload,\r\n clear,\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\";\r\n\r\nimport { useCallback, useEffect, useState } from \"react\";\r\nimport { usePersonaContext } from \"../context/PersonaContext.js\";\r\nimport type { PersonaThread } from \"../types.js\";\r\n\r\nexport function useThreads(autoFetch = true) {\r\n const { fetchWithAuth, defaultAgentId } = usePersonaContext();\r\n const [threads, setThreads] = useState<PersonaThread[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchThreads = useCallback(async () => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n const res = await fetchWithAuth(\"/threads\");\r\n if (!res.ok) throw new Error(`Failed to list threads: ${res.statusText}`);\r\n const data = await res.json();\r\n // Real shape is { items, pagination }. Bare array / `.data` / `.threads`\r\n // are defensive fallbacks for other deployments, not the actual contract.\r\n const items: PersonaThread[] = Array.isArray(data)\r\n ? data\r\n : data?.items ||\r\n data?.threads ||\r\n (Array.isArray(data?.data) ? data.data : undefined) ||\r\n [];\r\n setThreads(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 createThread = useCallback(\r\n async (agentId?: string) => {\r\n const targetAgentId = agentId || defaultAgentId;\r\n const res = 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 (!res.ok)\r\n throw new Error(`Failed to create thread: ${res.statusText}`);\r\n const data = await res.json();\r\n const created = (data?.data ?? data) as PersonaThread;\r\n void fetchThreads();\r\n return created;\r\n },\r\n [fetchWithAuth, defaultAgentId, fetchThreads],\r\n );\r\n\r\n const deleteThread = useCallback(\r\n async (threadId: string) => {\r\n const res = await fetchWithAuth(`/threads/${threadId}`, {\r\n method: \"DELETE\",\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to delete thread: ${res.statusText}`);\r\n setThreads((prev) => prev.filter((t) => t._id !== threadId));\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n // Best-effort batch delete — no not-found id aborts the rest. Up to 100\r\n // ids per call, matching the server's own limit.\r\n const bulkDeleteThreads = useCallback(\r\n async (threadIds: string[]) => {\r\n const res = await fetchWithAuth(\"/threads/bulk-delete\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ ids: threadIds }),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to bulk-delete threads: ${res.statusText}`);\r\n const data = await res.json();\r\n const result = (data?.data ?? data) as {\r\n deleted: string[];\r\n failed: Array<{ id: string; reason: string }>;\r\n };\r\n const deletedSet = new Set(result.deleted);\r\n setThreads((prev) => prev.filter((t) => !deletedSet.has(t._id)));\r\n return result;\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n // Convenience wrapper: there is no server-side \"delete everything\"\r\n // endpoint, only bulk-delete-by-id — so this bulk-deletes every\r\n // currently-loaded thread (up to 100 per call, chunked if there are more).\r\n const deleteAllThreads = useCallback(async () => {\r\n const ids = threads.map((t) => t._id);\r\n for (let i = 0; i < ids.length; i += 100) {\r\n await bulkDeleteThreads(ids.slice(i, i + 100));\r\n }\r\n }, [threads, bulkDeleteThreads]);\r\n\r\n // General-purpose update — { title?, isArchived? }.\r\n const updateThread = useCallback(\r\n async (\r\n threadId: string,\r\n input: { title?: string; isArchived?: boolean },\r\n ) => {\r\n const res = await fetchWithAuth(`/threads/${threadId}`, {\r\n method: \"PATCH\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify(input),\r\n });\r\n if (!res.ok)\r\n throw new Error(`Failed to update thread: ${res.statusText}`);\r\n const data = await res.json();\r\n const updated = (data?.data ?? data) as PersonaThread;\r\n setThreads((prev) =>\r\n prev.map((t) => (t._id === threadId ? { ...t, ...updated } : t)),\r\n );\r\n return updated;\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n const renameThread = useCallback(\r\n (threadId: string, title: string) => updateThread(threadId, { title }),\r\n [updateThread],\r\n );\r\n\r\n const getThread = useCallback(\r\n async (threadId: string) => {\r\n const res = await fetchWithAuth(`/threads/${threadId}`);\r\n if (!res.ok) throw new Error(`Failed to fetch thread: ${res.statusText}`);\r\n const data = await res.json();\r\n return (data?.data ?? data) as PersonaThread;\r\n },\r\n [fetchWithAuth],\r\n );\r\n\r\n useEffect(() => {\r\n if (autoFetch) {\r\n void fetchThreads();\r\n }\r\n }, [autoFetch, fetchThreads]);\r\n\r\n return {\r\n threads,\r\n isLoading,\r\n error,\r\n refetch: fetchThreads,\r\n createThread,\r\n deleteThread,\r\n bulkDeleteThreads,\r\n deleteAllThreads,\r\n updateThread,\r\n renameThread,\r\n getThread,\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 { 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"],"mappings":"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","names":["import_react","value","import_react","import_react","import_react","import_react","import_react","import_react","import_logger"]}
|