@personaai/react 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -462,6 +462,7 @@ function useChat(options = {}) {
462
462
  let buffer = "";
463
463
  let accumulatedText = "";
464
464
  const toolCallsMap = /* @__PURE__ */ new Map();
465
+ let streamSeq = 0;
465
466
  let activeReasoningId = null;
466
467
  const reasoningById = /* @__PURE__ */ new Map();
467
468
  const patchAssistant = (patch) => {
@@ -471,13 +472,14 @@ function useChat(options = {}) {
471
472
  )
472
473
  );
473
474
  };
474
- const insertReasoningMessage = (id) => {
475
+ const insertReasoningMessage = (id, seq) => {
475
476
  const msg = {
476
477
  id,
477
478
  role: "reasoning",
478
479
  content: "",
479
480
  createdAt: /* @__PURE__ */ new Date(),
480
- isStreaming: true
481
+ isStreaming: true,
482
+ seq
481
483
  };
482
484
  setMessages((prev) => {
483
485
  const idx = prev.findIndex((m) => m.id === assistantMessageId);
@@ -512,7 +514,8 @@ function useChat(options = {}) {
512
514
  toolCallsMap.set(event.toolCallId, {
513
515
  toolCallId: event.toolCallId,
514
516
  toolName: event.toolCallName || "",
515
- args: event.delta || ""
517
+ args: event.delta || "",
518
+ seq: streamSeq++
516
519
  });
517
520
  }
518
521
  patchAssistant({});
@@ -533,14 +536,14 @@ function useChat(options = {}) {
533
536
  } else if (event.type === "REASONING_MESSAGE_START" && event.messageId) {
534
537
  activeReasoningId = event.messageId;
535
538
  reasoningById.set(event.messageId, { content: "" });
536
- insertReasoningMessage(event.messageId);
539
+ insertReasoningMessage(event.messageId, streamSeq++);
537
540
  } else if (event.type === "REASONING_MESSAGE_CONTENT") {
538
541
  let rid = event.messageId || activeReasoningId || "";
539
542
  if (!rid || !reasoningById.has(rid)) {
540
543
  rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
541
544
  activeReasoningId = rid;
542
545
  reasoningById.set(rid, { content: "" });
543
- insertReasoningMessage(rid);
546
+ insertReasoningMessage(rid, streamSeq++);
544
547
  }
545
548
  const entry = reasoningById.get(rid);
546
549
  entry.content += event.delta;
@@ -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';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\nimport { openSSEStream } from '../streaming.js';\nimport type {\n PersonaInterrupt,\n PersonaMessage,\n PersonaPresentedFile,\n PersonaResumeValue,\n PersonaStreamingEvent,\n PersonaSubagentActivityEntry,\n PersonaTodo,\n PersonaToolCall,\n PersonaWorkspaceFile,\n SendMessageOverride,\n UseChatOptions,\n} from '../types.js';\n\n// A failed tool call's TOOL_CALL_RESULT content is a JSON envelope\n// (`{status:'error',message}`, see aguiTranslator.js's buildToolErrorContent)\n// rather than a separate boolean field on the event itself.\nfunction isErrorToolContent(content: string): boolean {\n if (typeof content !== 'string' || !content.trim().startsWith('{')) return false;\n try {\n return JSON.parse(content)?.status === 'error';\n } catch {\n return false;\n }\n}\n\n// Persisted subagent trace item shape (agent-backend's foldSubagentEvent/\n// subagentTrace.js) — already folded/paired server-side for compact storage,\n// DIFFERENT from the raw per-event `PersonaSubagentActivityEntry` shape the\n// live SSE stream sends (kind: 'text'|'tool_start'|'tool_result'). Reloading\n// a thread previously never read `data.subagentTraces` at all — a completed\n// subagent's activity (its own text/tool timeline) was silently dropped on\n// reload even though the backend already persists and returns it, keyed by\n// the owning `task` tool call's toolCallId (see agui.controller.js's\n// `subagentTraces[callId]`, matching `PersonaToolCall.toolCallId` exactly).\ntype PersistedSubagentTraceItem =\n | { type: 'text'; text: string }\n | { type: 'tool'; name: string; argsText: string; resultText: string; status: 'running' | 'completed' };\n\n// Re-expands the folded/paired persisted shape back into the raw kind-based\n// entries `PersonaSubagentActivityEntry` (and everything downstream that\n// consumes it — buildSubagentTimeline, the live-preview row, the activity\n// dialog) already knows how to render, so no sdk/ui changes are needed.\nfunction persistedTraceToActivityEntries(items: PersistedSubagentTraceItem[]): PersonaSubagentActivityEntry[] {\n const entries: PersonaSubagentActivityEntry[] = [];\n for (const item of items) {\n if (item.type === 'text') {\n if (item.text) entries.push({ kind: 'text', delta: item.text });\n } else {\n entries.push({ kind: 'tool_start', toolName: item.name, args: item.argsText });\n if (item.status === 'completed') {\n entries.push({ kind: 'tool_result', toolName: item.name, result: item.resultText });\n }\n }\n }\n return entries;\n}\n\n// present_file's result is `{status:'success', filePath, title, description}`\n// (see present.tool.js) — a signal to highlight that path in the workspace\n// files panel, not something meant to render as a generic tool-result blob.\nfunction parsePresentedFile(content: string): PersonaPresentedFile | null {\n try {\n const parsed = JSON.parse(content);\n if (parsed?.status !== 'success' || typeof parsed.filePath !== 'string') return null;\n return {\n path: parsed.filePath,\n title: typeof parsed.title === 'string' ? parsed.title : parsed.filePath,\n description: typeof parsed.description === 'string' ? parsed.description : '',\n };\n } catch {\n return null;\n }\n}\n\n// buildFilesTodosSnapshot (aguiTranslator.js) emits snake_case\n// created_at/modified_at on the wire — both from the live STATE_SNAPSHOT\n// event and from a reloaded thread's persisted state (checkpoint.service.js\n// runs the same function). Normalize to the SDK's usual camelCase shape.\nfunction normalizeWorkspaceFiles(\n raw: Record<string, { content: string; size: number; created_at: string | null; modified_at: string | null }>\n): Record<string, PersonaWorkspaceFile> {\n const normalized: Record<string, PersonaWorkspaceFile> = {};\n for (const [path, file] of Object.entries(raw || {})) {\n normalized[path] = {\n content: file.content,\n size: file.size,\n createdAt: file.created_at,\n modifiedAt: file.modified_at,\n };\n }\n return normalized;\n}\n\n// checkpointService.getMessages() wraps a paused thread's interrupt as\n// `{ kind, value }` (see checkpoint.service.js) — the same envelope shape\n// the live hitl_request/clarification_request CUSTOM events carry, just\n// nested one level deeper. Flatten both into the same PersonaInterrupt shape.\nfunction normalizePendingInterrupt(pending: unknown): PersonaInterrupt | null {\n if (!pending || typeof pending !== 'object') return null;\n const p = pending as { kind?: string; value?: Record<string, unknown> };\n if (p.kind === 'hitl') {\n return {\n kind: 'hitl',\n actionRequests: (p.value?.actionRequests ?? []) as Extract<\n PersonaInterrupt,\n { kind: 'hitl' }\n >['actionRequests'],\n reviewConfigs: (p.value?.reviewConfigs ?? []) as unknown[],\n };\n }\n if (p.kind === 'clarification') {\n return {\n kind: 'clarification',\n questions: (p.value?.questions ?? []) as Extract<PersonaInterrupt, { kind: 'clarification' }>['questions'],\n };\n }\n return null;\n}\n\nexport function useChat(options: UseChatOptions = {}) {\n const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken } = usePersonaContext();\n const agentId = options.agentId || defaultAgentId;\n const threadId = options.threadId;\n\n const [messages, setMessages] = useState<PersonaMessage[]>(options.initialMessages || []);\n const [input, setInput] = useState('');\n const [isStreaming, setIsStreaming] = useState(false);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [interrupt, setInterrupt] = useState<PersonaInterrupt | null>(null);\n const [files, setFiles] = useState<Record<string, PersonaWorkspaceFile>>({});\n const [todos, setTodos] = useState<PersonaTodo[]>([]);\n const [presentedFile, setPresentedFile] = useState<PersonaPresentedFile | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n }\n }, []);\n\n const clear = useCallback(() => {\n stop();\n setMessages([]);\n setError(null);\n setInterrupt(null);\n setFiles({});\n setTodos([]);\n setPresentedFile(null);\n }, [stop]);\n\n const loadThreadMessages = useCallback(\n async (id: string) => {\n setIsLoadingHistory(true);\n setError(null);\n try {\n const res = await fetchWithAuth(`/threads/${id}/messages`);\n if (!res.ok) throw new Error(`Failed to load thread history: ${res.statusText}`);\n const body = await res.json();\n const data = body?.data ?? body;\n const raw = (data?.messages ?? []) as Array<{\n id?: string;\n role: PersonaMessage['role'];\n content: string;\n toolCalls?: PersonaToolCall[];\n }>;\n const subagentTraces = (data?.subagentTraces ?? {}) as Record<string, PersistedSubagentTraceItem[]>;\n const loaded: PersonaMessage[] = raw.map((m, i) => ({\n id: m.id || `history-${id}-${i}`,\n role: m.role,\n content: m.content,\n createdAt: new Date(),\n toolCalls: m.toolCalls?.map((tc) => {\n const trace = subagentTraces[tc.toolCallId];\n return Array.isArray(trace) && trace.length > 0\n ? { ...tc, subagentActivity: persistedTraceToActivityEntries(trace) }\n : tc;\n }),\n }));\n setMessages(loaded);\n // Re-show the approval/clarification card on reload if this thread\n // is currently paused — otherwise it wouldn't reappear until the\n // next live stream re-surfaces it.\n setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));\n // Restore the workspace files/todos this thread already had (same\n // cleaned shape checkpoint.service.js now derives via\n // buildFilesTodosSnapshot, matching the live STATE_SNAPSHOT event).\n setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));\n setTodos((data?.state?.todos ?? []) as PersonaTodo[]);\n return loaded;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoadingHistory(false);\n }\n },\n [fetchWithAuth]\n );\n\n // Auto-load history the first time a thread with no in-memory messages is\n // selected (switching threads in the sidebar). Skipped for a thread whose\n // messages already live in state — e.g. one just created by handleSend,\n // which sets its placeholder messages in the same render batch as the\n // threadId change, so `messages` there is never empty at effect time.\n useEffect(() => {\n if (!threadId || isStreaming) return;\n if (loadedThreadIdRef.current === threadId) return;\n if (messages.length > 0) return;\n loadedThreadIdRef.current = threadId;\n void loadThreadMessages(threadId);\n }, [threadId, isStreaming, messages.length, loadThreadMessages]);\n\n const sendMessage = useCallback(\n async (contentToSend?: string, overrideOptions?: SendMessageOverride) => {\n const prompt = (contentToSend ?? input).trim();\n if (!prompt || isStreaming) return;\n\n const targetAgentId = overrideOptions?.agentId || agentId;\n if (!targetAgentId) {\n const err = new Error('No Agent ID specified for useChat.');\n setError(err);\n options.onError?.(err);\n return;\n }\n\n const userMessage: PersonaMessage = {\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n role: 'user',\n content: prompt,\n createdAt: new Date(),\n };\n\n const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const placeholderAssistant: PersonaMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n createdAt: new Date(),\n isStreaming: true,\n toolCalls: [],\n };\n\n const nextMessages = [...messages, userMessage];\n setMessages([...nextMessages, placeholderAssistant]);\n setInput('');\n setIsStreaming(true);\n setError(null);\n setInterrupt(null);\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n // Marks any reasoning message still flagged streaming as done — for\n // runs that end (abort/error) without a final REASONING_END. Declared\n // outside the try so the finally block can reach it.\n const finalizeReasoning = () => {\n setMessages((prev) =>\n prev.map((m) =>\n m.role === 'reasoning' && m.isStreaming ? { ...m, isStreaming: false } : m\n )\n );\n };\n\n try {\n // Reasoning messages are ephemeral client-side thoughts — never part\n // of the transcript sent back to the server (the backend already has\n // its own persisted copy and would treat them as user turns).\n const payloadMessages = nextMessages\n .filter((m) => m.role !== 'reasoning')\n .map((m) => ({\n role: m.role === 'assistant' ? ('assistant' as const) : ('user' as const),\n content: m.content,\n }));\n\n // Resolved here, not earlier — everything above this line (the\n // optimistic message + placeholder, clearing input, etc.) already\n // ran synchronously, so a caller passing an in-flight thread-creation\n // promise gets an instant UI update without the message send itself\n // waiting on it any longer than the network call already would.\n const resolvedThreadId = await (overrideOptions?.threadId ?? options.threadId);\n\n // openSSEStream, not fetchWithAuth: the transport has to be chosen\n // before the request goes out. React Native's fetch never populates\n // response.body and only settles once the whole response has arrived,\n // so discovering the missing body afterwards would already have cost\n // us the stream. See src/streaming.ts.\n const token = getAuthToken ? await getAuthToken() : null;\n const stream = await openSSEStream({\n url: `${baseUrl}/chat`,\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({\n agentId: targetAgentId,\n messages: payloadMessages,\n threadId: resolvedThreadId,\n resume: overrideOptions?.resume,\n }),\n signal: controller.signal,\n });\n\n if (!stream.ok) {\n throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? 'Stream failed'}`);\n }\n\n const reader = stream.reader;\n let buffer = '';\n let accumulatedText = '';\n const toolCallsMap = new Map<string, PersonaToolCall>();\n // Reasoning streams as its own `role: 'reasoning'` message per phase\n // (REASONING_MESSAGE_START … CONTENT … REASONING_END), never merged\n // into the assistant message or into a single accumulated blob —\n // mirrors the web timeline where each phase is a separate \"Thoughts\"\n // bubble. Each phase's message is inserted directly above the assistant\n // message so thoughts render above the answer, not underneath it.\n let activeReasoningId: string | null = null;\n const reasoningById = new Map<string, { content: string }>();\n\n const patchAssistant = (patch: Partial<PersonaMessage>) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId\n ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch }\n : msg\n )\n );\n };\n\n const insertReasoningMessage = (id: string) => {\n const msg: PersonaMessage = {\n id,\n role: 'reasoning',\n content: '',\n createdAt: new Date(),\n isStreaming: true,\n };\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === assistantMessageId);\n if (idx === -1) return [...prev, msg];\n const next = [...prev];\n next.splice(idx, 0, msg);\n return next;\n });\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += value ?? '';\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith('data:')) continue;\n\n const raw = trimmed.replace(/^data:\\s*/, '');\n if (raw === '[DONE]') break;\n\n try {\n const event = JSON.parse(raw) as PersonaStreamingEvent;\n options.onEvent?.(event);\n\n if (event.type === 'TEXT_MESSAGE_CHUNK' && event.delta) {\n accumulatedText += event.delta;\n patchAssistant({ content: accumulatedText, isStreaming: true });\n } else if (event.type === 'TOOL_CALL_CHUNK' && event.toolCallId) {\n // The backend streams tool calls as accumulating chunks\n // (id/name arrive on the first chunk, args stream in pieces\n // across subsequent ones) rather than separate start/args\n // events.\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.args = (existing.args || '') + (event.delta || '');\n } else {\n toolCallsMap.set(event.toolCallId, {\n toolCallId: event.toolCallId,\n toolName: event.toolCallName || '',\n args: event.delta || '',\n });\n }\n patchAssistant({});\n } else if (event.type === 'TOOL_CALL_RESULT') {\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.result = event.content;\n existing.isError = isErrorToolContent(event.content);\n if (existing.toolName === 'present_file' && !existing.isError) {\n const presented = parsePresentedFile(event.content);\n if (presented) setPresentedFile(presented);\n }\n patchAssistant({});\n }\n } else if (event.type === 'STATE_SNAPSHOT') {\n setFiles(normalizeWorkspaceFiles(event.snapshot.files));\n setTodos(event.snapshot.todos);\n } else if (event.type === 'REASONING_MESSAGE_START' && event.messageId) {\n // A fresh reasoning phase — its own message, regardless of how\n // many phases this run produces.\n activeReasoningId = event.messageId;\n reasoningById.set(event.messageId, { content: '' });\n insertReasoningMessage(event.messageId);\n } else if (event.type === 'REASONING_MESSAGE_CONTENT') {\n // Defensive: if the backend ever skips REASONING_MESSAGE_START,\n // lazily open the message on the first content chunk.\n let rid: string = event.messageId || activeReasoningId || '';\n if (!rid || !reasoningById.has(rid)) {\n rid =\n rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n activeReasoningId = rid;\n reasoningById.set(rid, { content: '' });\n insertReasoningMessage(rid);\n }\n const entry = reasoningById.get(rid)!;\n entry.content += event.delta;\n setMessages((prev) =>\n prev.map((m) =>\n m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m\n )\n );\n } else if (event.type === 'REASONING_END') {\n const rid = activeReasoningId;\n activeReasoningId = null;\n if (rid) {\n setMessages((prev) =>\n prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m))\n );\n }\n } else if (event.type === 'CUSTOM') {\n if (event.name === 'hitl_request') {\n const value = event.value as Extract<PersonaInterrupt, { kind: 'hitl' }>;\n setInterrupt({\n kind: 'hitl',\n actionRequests: value.actionRequests,\n reviewConfigs: value.reviewConfigs,\n });\n } else if (event.name === 'clarification_request') {\n const value = event.value as Extract<PersonaInterrupt, { kind: 'clarification' }>;\n setInterrupt({ kind: 'clarification', questions: value.questions });\n } else if (event.name === 'subagent_activity') {\n const { toolCallId, ...entry } = event.value as { toolCallId: string } & PersonaSubagentActivityEntry;\n const existing = toolCallsMap.get(toolCallId);\n if (existing) {\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\n patchAssistant({});\n }\n }\n // 'mcp_app' custom events carry no chat-transcript UI here —\n // consumers that render MCP widgets read them via onEvent.\n } else if (event.type === 'RUN_ERROR') {\n throw new Error(event.message || 'Stream error from agent');\n }\n } catch (e) {\n if (e instanceof Error && e.message.startsWith('Stream error')) {\n throw e;\n }\n }\n }\n }\n\n const finalMessage: PersonaMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: accumulatedText,\n createdAt: new Date(),\n isStreaming: false,\n toolCalls: Array.from(toolCallsMap.values()),\n };\n\n setMessages((prev) =>\n prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg))\n );\n\n options.onFinish?.(finalMessage);\n } catch (err) {\n if (controller.signal.aborted) {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg\n )\n );\n return;\n }\n\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n options.onError?.(errorObj);\n\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId\n ? {\n ...msg,\n content:\n msg.content || `⚠️ Error: ${errorObj.message || 'Failed to get response.'}`,\n isStreaming: false,\n }\n : msg\n )\n );\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n // A run that ends without a final REASONING_END (abort, error) must\n // still flip its in-flight reasoning messages to done.\n finalizeReasoning();\n }\n },\n [agentId, baseUrl, getAuthToken, input, isStreaming, messages, options]\n );\n\n const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setInput(e.target.value);\n }, []);\n\n const handleSubmit = useCallback(\n (e?: React.FormEvent) => {\n if (e) e.preventDefault();\n void sendMessage();\n },\n [sendMessage]\n );\n\n const reload = useCallback(() => {\n if (messages.length === 0 || isStreaming) return;\n let lastUserIndex = -1;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === 'user') {\n lastUserIndex = i;\n break;\n }\n }\n if (lastUserIndex === -1) return;\n\n const lastUserMessage = messages[lastUserIndex];\n setMessages(messages.slice(0, lastUserIndex));\n void sendMessage(lastUserMessage.content);\n }, [isStreaming, messages, sendMessage]);\n\n // Unpauses a paused HITL/clarification run. `displayContent` becomes the\n // visible user-turn bubble (e.g. \"Approved\", or the typed clarification\n // answer) — the server resolves the actual resume value from `resume`\n // itself, `displayContent` is only ever used for its own transcript text.\n const resumeInterrupt = useCallback(\n (resume: PersonaResumeValue, displayContent: string) => sendMessage(displayContent, { resume }),\n [sendMessage]\n );\n\n const dismissPresentedFile = useCallback(() => setPresentedFile(null), []);\n\n // Manually re-open a workspace file — e.g. a present_file tool card's\n // \"Open\" button, after the auto-opened drawer was closed or a different\n // file was selected since.\n const openWorkspaceFile = useCallback(\n (path: string) => setPresentedFile({ path, title: path.split('/').pop() || path, description: '' }),\n []\n );\n\n return {\n messages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n sendMessage,\n isStreaming,\n isLoading: isStreaming,\n isLoadingHistory,\n error,\n interrupt,\n resumeInterrupt,\n files,\n todos,\n presentedFile,\n dismissPresentedFile,\n openWorkspaceFile,\n stop,\n reload,\n clear,\n setMessages,\n loadThreadMessages,\n };\n}\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';\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"]}
package/dist/index.d.cts CHANGED
@@ -22,6 +22,13 @@ interface PersonaToolCall {
22
22
  args?: string;
23
23
  result?: string;
24
24
  isError?: boolean;
25
+ /**
26
+ * Monotonic stream-order index, assigned when the call's first chunk
27
+ * arrives. Reasoning phases and tool calls share the same counter, so a
28
+ * client can interleave them chronologically (thought → tool → thought →
29
+ * tool → answer). Absent on calls loaded from history.
30
+ */
31
+ seq?: number;
25
32
  /** Nested activity timeline — only present on `task` (subagent) tool calls. */
26
33
  subagentActivity?: PersonaSubagentActivityEntry[];
27
34
  }
@@ -32,6 +39,12 @@ interface PersonaMessage {
32
39
  createdAt: Date;
33
40
  isStreaming?: boolean;
34
41
  toolCalls?: PersonaToolCall[];
42
+ /**
43
+ * Monotonic stream-order index for `role: 'reasoning'` messages, from the
44
+ * same counter as `PersonaToolCall.seq` — lets clients place each reasoning
45
+ * phase in its chronological spot relative to the tool calls that bracket it.
46
+ */
47
+ seq?: number;
35
48
  /**
36
49
  * @deprecated Model reasoning now streams as its own `role: 'reasoning'`
37
50
  * messages (one per phase, never merged). These fields are retained for
package/dist/index.d.ts CHANGED
@@ -22,6 +22,13 @@ interface PersonaToolCall {
22
22
  args?: string;
23
23
  result?: string;
24
24
  isError?: boolean;
25
+ /**
26
+ * Monotonic stream-order index, assigned when the call's first chunk
27
+ * arrives. Reasoning phases and tool calls share the same counter, so a
28
+ * client can interleave them chronologically (thought → tool → thought →
29
+ * tool → answer). Absent on calls loaded from history.
30
+ */
31
+ seq?: number;
25
32
  /** Nested activity timeline — only present on `task` (subagent) tool calls. */
26
33
  subagentActivity?: PersonaSubagentActivityEntry[];
27
34
  }
@@ -32,6 +39,12 @@ interface PersonaMessage {
32
39
  createdAt: Date;
33
40
  isStreaming?: boolean;
34
41
  toolCalls?: PersonaToolCall[];
42
+ /**
43
+ * Monotonic stream-order index for `role: 'reasoning'` messages, from the
44
+ * same counter as `PersonaToolCall.seq` — lets clients place each reasoning
45
+ * phase in its chronological spot relative to the tool calls that bracket it.
46
+ */
47
+ seq?: number;
35
48
  /**
36
49
  * @deprecated Model reasoning now streams as its own `role: 'reasoning'`
37
50
  * messages (one per phase, never merged). These fields are retained for
package/dist/index.js CHANGED
@@ -425,6 +425,7 @@ function useChat(options = {}) {
425
425
  let buffer = "";
426
426
  let accumulatedText = "";
427
427
  const toolCallsMap = /* @__PURE__ */ new Map();
428
+ let streamSeq = 0;
428
429
  let activeReasoningId = null;
429
430
  const reasoningById = /* @__PURE__ */ new Map();
430
431
  const patchAssistant = (patch) => {
@@ -434,13 +435,14 @@ function useChat(options = {}) {
434
435
  )
435
436
  );
436
437
  };
437
- const insertReasoningMessage = (id) => {
438
+ const insertReasoningMessage = (id, seq) => {
438
439
  const msg = {
439
440
  id,
440
441
  role: "reasoning",
441
442
  content: "",
442
443
  createdAt: /* @__PURE__ */ new Date(),
443
- isStreaming: true
444
+ isStreaming: true,
445
+ seq
444
446
  };
445
447
  setMessages((prev) => {
446
448
  const idx = prev.findIndex((m) => m.id === assistantMessageId);
@@ -475,7 +477,8 @@ function useChat(options = {}) {
475
477
  toolCallsMap.set(event.toolCallId, {
476
478
  toolCallId: event.toolCallId,
477
479
  toolName: event.toolCallName || "",
478
- args: event.delta || ""
480
+ args: event.delta || "",
481
+ seq: streamSeq++
479
482
  });
480
483
  }
481
484
  patchAssistant({});
@@ -496,14 +499,14 @@ function useChat(options = {}) {
496
499
  } else if (event.type === "REASONING_MESSAGE_START" && event.messageId) {
497
500
  activeReasoningId = event.messageId;
498
501
  reasoningById.set(event.messageId, { content: "" });
499
- insertReasoningMessage(event.messageId);
502
+ insertReasoningMessage(event.messageId, streamSeq++);
500
503
  } else if (event.type === "REASONING_MESSAGE_CONTENT") {
501
504
  let rid = event.messageId || activeReasoningId || "";
502
505
  if (!rid || !reasoningById.has(rid)) {
503
506
  rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
504
507
  activeReasoningId = rid;
505
508
  reasoningById.set(rid, { content: "" });
506
- insertReasoningMessage(rid);
509
+ insertReasoningMessage(rid, streamSeq++);
507
510
  }
508
511
  const entry = reasoningById.get(rid);
509
512
  entry.content += event.delta;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts","../src/index.ts"],"sourcesContent":["'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';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { usePersonaContext } from '../context/PersonaContext.js';\nimport { openSSEStream } from '../streaming.js';\nimport type {\n PersonaInterrupt,\n PersonaMessage,\n PersonaPresentedFile,\n PersonaResumeValue,\n PersonaStreamingEvent,\n PersonaSubagentActivityEntry,\n PersonaTodo,\n PersonaToolCall,\n PersonaWorkspaceFile,\n SendMessageOverride,\n UseChatOptions,\n} from '../types.js';\n\n// A failed tool call's TOOL_CALL_RESULT content is a JSON envelope\n// (`{status:'error',message}`, see aguiTranslator.js's buildToolErrorContent)\n// rather than a separate boolean field on the event itself.\nfunction isErrorToolContent(content: string): boolean {\n if (typeof content !== 'string' || !content.trim().startsWith('{')) return false;\n try {\n return JSON.parse(content)?.status === 'error';\n } catch {\n return false;\n }\n}\n\n// Persisted subagent trace item shape (agent-backend's foldSubagentEvent/\n// subagentTrace.js) — already folded/paired server-side for compact storage,\n// DIFFERENT from the raw per-event `PersonaSubagentActivityEntry` shape the\n// live SSE stream sends (kind: 'text'|'tool_start'|'tool_result'). Reloading\n// a thread previously never read `data.subagentTraces` at all — a completed\n// subagent's activity (its own text/tool timeline) was silently dropped on\n// reload even though the backend already persists and returns it, keyed by\n// the owning `task` tool call's toolCallId (see agui.controller.js's\n// `subagentTraces[callId]`, matching `PersonaToolCall.toolCallId` exactly).\ntype PersistedSubagentTraceItem =\n | { type: 'text'; text: string }\n | { type: 'tool'; name: string; argsText: string; resultText: string; status: 'running' | 'completed' };\n\n// Re-expands the folded/paired persisted shape back into the raw kind-based\n// entries `PersonaSubagentActivityEntry` (and everything downstream that\n// consumes it — buildSubagentTimeline, the live-preview row, the activity\n// dialog) already knows how to render, so no sdk/ui changes are needed.\nfunction persistedTraceToActivityEntries(items: PersistedSubagentTraceItem[]): PersonaSubagentActivityEntry[] {\n const entries: PersonaSubagentActivityEntry[] = [];\n for (const item of items) {\n if (item.type === 'text') {\n if (item.text) entries.push({ kind: 'text', delta: item.text });\n } else {\n entries.push({ kind: 'tool_start', toolName: item.name, args: item.argsText });\n if (item.status === 'completed') {\n entries.push({ kind: 'tool_result', toolName: item.name, result: item.resultText });\n }\n }\n }\n return entries;\n}\n\n// present_file's result is `{status:'success', filePath, title, description}`\n// (see present.tool.js) — a signal to highlight that path in the workspace\n// files panel, not something meant to render as a generic tool-result blob.\nfunction parsePresentedFile(content: string): PersonaPresentedFile | null {\n try {\n const parsed = JSON.parse(content);\n if (parsed?.status !== 'success' || typeof parsed.filePath !== 'string') return null;\n return {\n path: parsed.filePath,\n title: typeof parsed.title === 'string' ? parsed.title : parsed.filePath,\n description: typeof parsed.description === 'string' ? parsed.description : '',\n };\n } catch {\n return null;\n }\n}\n\n// buildFilesTodosSnapshot (aguiTranslator.js) emits snake_case\n// created_at/modified_at on the wire — both from the live STATE_SNAPSHOT\n// event and from a reloaded thread's persisted state (checkpoint.service.js\n// runs the same function). Normalize to the SDK's usual camelCase shape.\nfunction normalizeWorkspaceFiles(\n raw: Record<string, { content: string; size: number; created_at: string | null; modified_at: string | null }>\n): Record<string, PersonaWorkspaceFile> {\n const normalized: Record<string, PersonaWorkspaceFile> = {};\n for (const [path, file] of Object.entries(raw || {})) {\n normalized[path] = {\n content: file.content,\n size: file.size,\n createdAt: file.created_at,\n modifiedAt: file.modified_at,\n };\n }\n return normalized;\n}\n\n// checkpointService.getMessages() wraps a paused thread's interrupt as\n// `{ kind, value }` (see checkpoint.service.js) — the same envelope shape\n// the live hitl_request/clarification_request CUSTOM events carry, just\n// nested one level deeper. Flatten both into the same PersonaInterrupt shape.\nfunction normalizePendingInterrupt(pending: unknown): PersonaInterrupt | null {\n if (!pending || typeof pending !== 'object') return null;\n const p = pending as { kind?: string; value?: Record<string, unknown> };\n if (p.kind === 'hitl') {\n return {\n kind: 'hitl',\n actionRequests: (p.value?.actionRequests ?? []) as Extract<\n PersonaInterrupt,\n { kind: 'hitl' }\n >['actionRequests'],\n reviewConfigs: (p.value?.reviewConfigs ?? []) as unknown[],\n };\n }\n if (p.kind === 'clarification') {\n return {\n kind: 'clarification',\n questions: (p.value?.questions ?? []) as Extract<PersonaInterrupt, { kind: 'clarification' }>['questions'],\n };\n }\n return null;\n}\n\nexport function useChat(options: UseChatOptions = {}) {\n const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken } = usePersonaContext();\n const agentId = options.agentId || defaultAgentId;\n const threadId = options.threadId;\n\n const [messages, setMessages] = useState<PersonaMessage[]>(options.initialMessages || []);\n const [input, setInput] = useState('');\n const [isStreaming, setIsStreaming] = useState(false);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [interrupt, setInterrupt] = useState<PersonaInterrupt | null>(null);\n const [files, setFiles] = useState<Record<string, PersonaWorkspaceFile>>({});\n const [todos, setTodos] = useState<PersonaTodo[]>([]);\n const [presentedFile, setPresentedFile] = useState<PersonaPresentedFile | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const loadedThreadIdRef = useRef<string | undefined>(undefined);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n }\n }, []);\n\n const clear = useCallback(() => {\n stop();\n setMessages([]);\n setError(null);\n setInterrupt(null);\n setFiles({});\n setTodos([]);\n setPresentedFile(null);\n }, [stop]);\n\n const loadThreadMessages = useCallback(\n async (id: string) => {\n setIsLoadingHistory(true);\n setError(null);\n try {\n const res = await fetchWithAuth(`/threads/${id}/messages`);\n if (!res.ok) throw new Error(`Failed to load thread history: ${res.statusText}`);\n const body = await res.json();\n const data = body?.data ?? body;\n const raw = (data?.messages ?? []) as Array<{\n id?: string;\n role: PersonaMessage['role'];\n content: string;\n toolCalls?: PersonaToolCall[];\n }>;\n const subagentTraces = (data?.subagentTraces ?? {}) as Record<string, PersistedSubagentTraceItem[]>;\n const loaded: PersonaMessage[] = raw.map((m, i) => ({\n id: m.id || `history-${id}-${i}`,\n role: m.role,\n content: m.content,\n createdAt: new Date(),\n toolCalls: m.toolCalls?.map((tc) => {\n const trace = subagentTraces[tc.toolCallId];\n return Array.isArray(trace) && trace.length > 0\n ? { ...tc, subagentActivity: persistedTraceToActivityEntries(trace) }\n : tc;\n }),\n }));\n setMessages(loaded);\n // Re-show the approval/clarification card on reload if this thread\n // is currently paused — otherwise it wouldn't reappear until the\n // next live stream re-surfaces it.\n setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));\n // Restore the workspace files/todos this thread already had (same\n // cleaned shape checkpoint.service.js now derives via\n // buildFilesTodosSnapshot, matching the live STATE_SNAPSHOT event).\n setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));\n setTodos((data?.state?.todos ?? []) as PersonaTodo[]);\n return loaded;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n return [];\n } finally {\n setIsLoadingHistory(false);\n }\n },\n [fetchWithAuth]\n );\n\n // Auto-load history the first time a thread with no in-memory messages is\n // selected (switching threads in the sidebar). Skipped for a thread whose\n // messages already live in state — e.g. one just created by handleSend,\n // which sets its placeholder messages in the same render batch as the\n // threadId change, so `messages` there is never empty at effect time.\n useEffect(() => {\n if (!threadId || isStreaming) return;\n if (loadedThreadIdRef.current === threadId) return;\n if (messages.length > 0) return;\n loadedThreadIdRef.current = threadId;\n void loadThreadMessages(threadId);\n }, [threadId, isStreaming, messages.length, loadThreadMessages]);\n\n const sendMessage = useCallback(\n async (contentToSend?: string, overrideOptions?: SendMessageOverride) => {\n const prompt = (contentToSend ?? input).trim();\n if (!prompt || isStreaming) return;\n\n const targetAgentId = overrideOptions?.agentId || agentId;\n if (!targetAgentId) {\n const err = new Error('No Agent ID specified for useChat.');\n setError(err);\n options.onError?.(err);\n return;\n }\n\n const userMessage: PersonaMessage = {\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n role: 'user',\n content: prompt,\n createdAt: new Date(),\n };\n\n const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const placeholderAssistant: PersonaMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n createdAt: new Date(),\n isStreaming: true,\n toolCalls: [],\n };\n\n const nextMessages = [...messages, userMessage];\n setMessages([...nextMessages, placeholderAssistant]);\n setInput('');\n setIsStreaming(true);\n setError(null);\n setInterrupt(null);\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n // Marks any reasoning message still flagged streaming as done — for\n // runs that end (abort/error) without a final REASONING_END. Declared\n // outside the try so the finally block can reach it.\n const finalizeReasoning = () => {\n setMessages((prev) =>\n prev.map((m) =>\n m.role === 'reasoning' && m.isStreaming ? { ...m, isStreaming: false } : m\n )\n );\n };\n\n try {\n // Reasoning messages are ephemeral client-side thoughts — never part\n // of the transcript sent back to the server (the backend already has\n // its own persisted copy and would treat them as user turns).\n const payloadMessages = nextMessages\n .filter((m) => m.role !== 'reasoning')\n .map((m) => ({\n role: m.role === 'assistant' ? ('assistant' as const) : ('user' as const),\n content: m.content,\n }));\n\n // Resolved here, not earlier — everything above this line (the\n // optimistic message + placeholder, clearing input, etc.) already\n // ran synchronously, so a caller passing an in-flight thread-creation\n // promise gets an instant UI update without the message send itself\n // waiting on it any longer than the network call already would.\n const resolvedThreadId = await (overrideOptions?.threadId ?? options.threadId);\n\n // openSSEStream, not fetchWithAuth: the transport has to be chosen\n // before the request goes out. React Native's fetch never populates\n // response.body and only settles once the whole response has arrived,\n // so discovering the missing body afterwards would already have cost\n // us the stream. See src/streaming.ts.\n const token = getAuthToken ? await getAuthToken() : null;\n const stream = await openSSEStream({\n url: `${baseUrl}/chat`,\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({\n agentId: targetAgentId,\n messages: payloadMessages,\n threadId: resolvedThreadId,\n resume: overrideOptions?.resume,\n }),\n signal: controller.signal,\n });\n\n if (!stream.ok) {\n throw new Error(`Chat error (${stream.status}): ${stream.errorText ?? 'Stream failed'}`);\n }\n\n const reader = stream.reader;\n let buffer = '';\n let accumulatedText = '';\n const toolCallsMap = new Map<string, PersonaToolCall>();\n // Reasoning streams as its own `role: 'reasoning'` message per phase\n // (REASONING_MESSAGE_START … CONTENT … REASONING_END), never merged\n // into the assistant message or into a single accumulated blob —\n // mirrors the web timeline where each phase is a separate \"Thoughts\"\n // bubble. Each phase's message is inserted directly above the assistant\n // message so thoughts render above the answer, not underneath it.\n let activeReasoningId: string | null = null;\n const reasoningById = new Map<string, { content: string }>();\n\n const patchAssistant = (patch: Partial<PersonaMessage>) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId\n ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch }\n : msg\n )\n );\n };\n\n const insertReasoningMessage = (id: string) => {\n const msg: PersonaMessage = {\n id,\n role: 'reasoning',\n content: '',\n createdAt: new Date(),\n isStreaming: true,\n };\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === assistantMessageId);\n if (idx === -1) return [...prev, msg];\n const next = [...prev];\n next.splice(idx, 0, msg);\n return next;\n });\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += value ?? '';\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith('data:')) continue;\n\n const raw = trimmed.replace(/^data:\\s*/, '');\n if (raw === '[DONE]') break;\n\n try {\n const event = JSON.parse(raw) as PersonaStreamingEvent;\n options.onEvent?.(event);\n\n if (event.type === 'TEXT_MESSAGE_CHUNK' && event.delta) {\n accumulatedText += event.delta;\n patchAssistant({ content: accumulatedText, isStreaming: true });\n } else if (event.type === 'TOOL_CALL_CHUNK' && event.toolCallId) {\n // The backend streams tool calls as accumulating chunks\n // (id/name arrive on the first chunk, args stream in pieces\n // across subsequent ones) rather than separate start/args\n // events.\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.args = (existing.args || '') + (event.delta || '');\n } else {\n toolCallsMap.set(event.toolCallId, {\n toolCallId: event.toolCallId,\n toolName: event.toolCallName || '',\n args: event.delta || '',\n });\n }\n patchAssistant({});\n } else if (event.type === 'TOOL_CALL_RESULT') {\n const existing = toolCallsMap.get(event.toolCallId);\n if (existing) {\n existing.result = event.content;\n existing.isError = isErrorToolContent(event.content);\n if (existing.toolName === 'present_file' && !existing.isError) {\n const presented = parsePresentedFile(event.content);\n if (presented) setPresentedFile(presented);\n }\n patchAssistant({});\n }\n } else if (event.type === 'STATE_SNAPSHOT') {\n setFiles(normalizeWorkspaceFiles(event.snapshot.files));\n setTodos(event.snapshot.todos);\n } else if (event.type === 'REASONING_MESSAGE_START' && event.messageId) {\n // A fresh reasoning phase — its own message, regardless of how\n // many phases this run produces.\n activeReasoningId = event.messageId;\n reasoningById.set(event.messageId, { content: '' });\n insertReasoningMessage(event.messageId);\n } else if (event.type === 'REASONING_MESSAGE_CONTENT') {\n // Defensive: if the backend ever skips REASONING_MESSAGE_START,\n // lazily open the message on the first content chunk.\n let rid: string = event.messageId || activeReasoningId || '';\n if (!rid || !reasoningById.has(rid)) {\n rid =\n rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n activeReasoningId = rid;\n reasoningById.set(rid, { content: '' });\n insertReasoningMessage(rid);\n }\n const entry = reasoningById.get(rid)!;\n entry.content += event.delta;\n setMessages((prev) =>\n prev.map((m) =>\n m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m\n )\n );\n } else if (event.type === 'REASONING_END') {\n const rid = activeReasoningId;\n activeReasoningId = null;\n if (rid) {\n setMessages((prev) =>\n prev.map((m) => (m.id === rid ? { ...m, isStreaming: false } : m))\n );\n }\n } else if (event.type === 'CUSTOM') {\n if (event.name === 'hitl_request') {\n const value = event.value as Extract<PersonaInterrupt, { kind: 'hitl' }>;\n setInterrupt({\n kind: 'hitl',\n actionRequests: value.actionRequests,\n reviewConfigs: value.reviewConfigs,\n });\n } else if (event.name === 'clarification_request') {\n const value = event.value as Extract<PersonaInterrupt, { kind: 'clarification' }>;\n setInterrupt({ kind: 'clarification', questions: value.questions });\n } else if (event.name === 'subagent_activity') {\n const { toolCallId, ...entry } = event.value as { toolCallId: string } & PersonaSubagentActivityEntry;\n const existing = toolCallsMap.get(toolCallId);\n if (existing) {\n existing.subagentActivity = [...(existing.subagentActivity || []), entry];\n patchAssistant({});\n }\n }\n // 'mcp_app' custom events carry no chat-transcript UI here —\n // consumers that render MCP widgets read them via onEvent.\n } else if (event.type === 'RUN_ERROR') {\n throw new Error(event.message || 'Stream error from agent');\n }\n } catch (e) {\n if (e instanceof Error && e.message.startsWith('Stream error')) {\n throw e;\n }\n }\n }\n }\n\n const finalMessage: PersonaMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: accumulatedText,\n createdAt: new Date(),\n isStreaming: false,\n toolCalls: Array.from(toolCallsMap.values()),\n };\n\n setMessages((prev) =>\n prev.map((msg) => (msg.id === assistantMessageId ? finalMessage : msg))\n );\n\n options.onFinish?.(finalMessage);\n } catch (err) {\n if (controller.signal.aborted) {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg\n )\n );\n return;\n }\n\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n options.onError?.(errorObj);\n\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === assistantMessageId\n ? {\n ...msg,\n content:\n msg.content || `⚠️ Error: ${errorObj.message || 'Failed to get response.'}`,\n isStreaming: false,\n }\n : msg\n )\n );\n } finally {\n setIsStreaming(false);\n abortControllerRef.current = null;\n // A run that ends without a final REASONING_END (abort, error) must\n // still flip its in-flight reasoning messages to done.\n finalizeReasoning();\n }\n },\n [agentId, baseUrl, getAuthToken, input, isStreaming, messages, options]\n );\n\n const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setInput(e.target.value);\n }, []);\n\n const handleSubmit = useCallback(\n (e?: React.FormEvent) => {\n if (e) e.preventDefault();\n void sendMessage();\n },\n [sendMessage]\n );\n\n const reload = useCallback(() => {\n if (messages.length === 0 || isStreaming) return;\n let lastUserIndex = -1;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === 'user') {\n lastUserIndex = i;\n break;\n }\n }\n if (lastUserIndex === -1) return;\n\n const lastUserMessage = messages[lastUserIndex];\n setMessages(messages.slice(0, lastUserIndex));\n void sendMessage(lastUserMessage.content);\n }, [isStreaming, messages, sendMessage]);\n\n // Unpauses a paused HITL/clarification run. `displayContent` becomes the\n // visible user-turn bubble (e.g. \"Approved\", or the typed clarification\n // answer) — the server resolves the actual resume value from `resume`\n // itself, `displayContent` is only ever used for its own transcript text.\n const resumeInterrupt = useCallback(\n (resume: PersonaResumeValue, displayContent: string) => sendMessage(displayContent, { resume }),\n [sendMessage]\n );\n\n const dismissPresentedFile = useCallback(() => setPresentedFile(null), []);\n\n // Manually re-open a workspace file — e.g. a present_file tool card's\n // \"Open\" button, after the auto-opened drawer was closed or a different\n // file was selected since.\n const openWorkspaceFile = useCallback(\n (path: string) => setPresentedFile({ path, title: path.split('/').pop() || path, description: '' }),\n []\n );\n\n return {\n messages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n sendMessage,\n isStreaming,\n isLoading: isStreaming,\n isLoadingHistory,\n error,\n interrupt,\n resumeInterrupt,\n files,\n todos,\n presentedFile,\n dismissPresentedFile,\n openWorkspaceFile,\n stop,\n reload,\n clear,\n setMessages,\n loadThreadMessages,\n };\n}\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","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"],"mappings":"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","names":["value","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../src/context/PersonaContext.tsx","../src/hooks/useChat.ts","../src/streaming.ts","../src/hooks/useMemory.ts","../src/hooks/useThreads.ts","../src/hooks/useFiles.ts","../src/hooks/useAgents.ts","../src/hooks/useConnection.ts","../src/hooks/useMcpConnections.ts","../src/index.ts"],"sourcesContent":["'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","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"],"mappings":"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","names":["value","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect","useCallback","useEffect","useState","useState","useCallback","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@personaai/react",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "React hooks and state management library for the Persona AI agent runtime. Client-side only.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",