@agents24/chat-react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/dist/index.cjs +1306 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +351 -0
- package/dist/index.d.ts +351 -0
- package/dist/index.js +1260 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/controller.ts","../src/model.ts","../src/sse.ts","../src/transport.ts","../src/viewport.tsx"],"sourcesContent":["export * from \"./controller\";\nexport * from \"./model\";\nexport * from \"./sse\";\nexport * from \"./transport\";\nexport * from \"./types\";\nexport * from \"./viewport\";\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n activeRunIdFromThread,\n activeRunIdFromThreadDetail,\n assistantTextFromBlocks,\n createChatId,\n DEFAULT_THREAD_PAGE_SIZE,\n hasStaleUnfinishedAssistantCache,\n latestContextWindowFromThread,\n mergeReasoningSteps,\n reasoningStepsFromBlocks,\n renderBlocksFromResponseBlocks,\n textFromFinalOutput,\n threadActivityDate,\n threadDetailToMessages,\n threadPaging,\n titleFromMessage,\n} from \"./model\";\nimport type {\n ChatAttachment,\n ChatContextWindow,\n ChatController,\n ChatMessage,\n ChatMessageBlock,\n ChatReasoningStep,\n ChatRuntimeEvent,\n ChatStorageAdapter,\n ChatTransport,\n StoredChatThread,\n} from \"./types\";\n\nexport type UseAgents24ChatControllerOptions = {\n transport: ChatTransport;\n storage: ChatStorageAdapter;\n activeThreadId?: string | null;\n pageSize?: number;\n storageKey?: unknown;\n createId?: () => string;\n onActiveThreadIdChange?: (threadId: string | null) => void;\n onSourceClick?: (citations: ChatMessage[\"citations\"]) => void;\n onStreamErrorMessage?: (error: unknown) => string;\n};\n\ntype FinalizeInput = {\n threadId: string | null;\n baseMessages: ChatMessage[];\n assistantText: string;\n reasoning: ChatReasoningStep[];\n thinkingDurationMs: number;\n messageId?: string | null;\n runId?: string | null;\n blocks?: ChatMessageBlock[];\n error?: string;\n};\n\nconst mergeContextWindow = (\n current: ChatContextWindow | null,\n incoming: unknown\n): ChatContextWindow | null => {\n if (!incoming || typeof incoming !== \"object\") return current;\n return { ...(current || {}), ...(incoming as ChatContextWindow) };\n};\n\nconst threadSummaryToStored = (thread: Record<string, unknown>): StoredChatThread => ({\n ...(thread as StoredChatThread),\n id: String(thread.id),\n title: String(thread.title || \"New chat\"),\n updated_at: String(thread.updated_at || thread.last_activity_at || thread.created_at || new Date().toISOString()),\n messages: [],\n isHydrated: false,\n});\n\nexport function useAgents24ChatController({\n transport,\n storage,\n activeThreadId: controlledActiveThreadId,\n pageSize = DEFAULT_THREAD_PAGE_SIZE,\n storageKey,\n createId = createChatId,\n onActiveThreadIdChange,\n onSourceClick,\n onStreamErrorMessage,\n}: UseAgents24ChatControllerOptions): ChatController {\n const activeThreadId = controlledActiveThreadId ?? storage.getActiveThreadId?.() ?? null;\n const initialCached = activeThreadId ? storage.getThread(activeThreadId) : undefined;\n const [messages, setMessages] = useState<ChatMessage[]>(() => initialCached?.messages || []);\n const [isLoading, setIsLoading] = useState(false);\n const [isLoadingHistory, setIsLoadingHistory] = useState(() => Boolean(activeThreadId) && !initialCached?.messages?.length);\n const [isLoadingOlder, setIsLoadingOlder] = useState(false);\n const [hasOlderTurns, setHasOlderTurns] = useState(Boolean(initialCached?.hasOlderTurns));\n const [streamingContent, setStreamingContent] = useState(\"\");\n const [streamingMessageId, setStreamingMessageId] = useState<string | null>(null);\n const [contextStatus, setContextStatus] = useState<ChatContextWindow | null>(null);\n const [currentReasoning, setCurrentReasoning] = useState<ChatReasoningStep[]>([]);\n const [liked, setLiked] = useState<Record<string, boolean>>({});\n const [disliked, setDisliked] = useState<Record<string, boolean>>({});\n const [copiedMessageId, setCopiedMessageId] = useState<string | null>(null);\n const [lastThinkingDurationMs, setLastThinkingDurationMs] = useState<number | null>(null);\n\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const activeThreadIdRef = useRef<string | null>(activeThreadId);\n const messagesRef = useRef<ChatMessage[]>(messages);\n const nextBeforeTurnIndexRef = useRef<number | null>(initialCached?.nextBeforeTurnIndex ?? null);\n const hasOlderTurnsRef = useRef(Boolean(initialCached?.hasOlderTurns));\n const isLoadingOlderRef = useRef(false);\n const loadedThreadIdRef = useRef<string | null>(initialCached?.messages?.length ? activeThreadId : null);\n const requestSeqRef = useRef(0);\n const isLoadingHistoryRef = useRef(isLoadingHistory);\n const activeRunIdRef = useRef<string | null>(null);\n const reattachedRunIdRef = useRef<string | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\n const streamingContentRef = useRef(\"\");\n const streamingMessageIdRef = useRef<string | null>(null);\n const reasoningRef = useRef<ChatReasoningStep[]>([]);\n const liveVoiceIdsRef = useRef<{ user?: string; assistant?: string }>({});\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n const persistThread = useCallback(\n (\n threadId: string,\n nextMessages: ChatMessage[],\n paging?: { hasOlderTurns?: boolean; nextBeforeTurnIndex?: number | null },\n options?: { updatedAt?: string; touch?: boolean }\n ) => {\n const existing = storage.getThread(threadId);\n const firstUser = nextMessages.find((message) => message.role === \"user\");\n storage.upsertThread({\n ...(existing || {}),\n id: threadId,\n title: existing?.title || (firstUser ? titleFromMessage(firstUser.content, firstUser.attachments || []) : \"New chat\"),\n updated_at: options?.updatedAt || (options?.touch ? new Date().toISOString() : existing?.updated_at) || new Date().toISOString(),\n messages: nextMessages,\n isHydrated: true,\n hasOlderTurns: paging?.hasOlderTurns ?? hasOlderTurnsRef.current,\n nextBeforeTurnIndex: paging?.nextBeforeTurnIndex ?? nextBeforeTurnIndexRef.current,\n });\n },\n [storage]\n );\n\n const markThreadRunStatus = useCallback(\n (threadId: string, runId: string, status: string, lastEventSeq?: number | null) => {\n const existing = storage.getThread(threadId);\n if (!existing || !runId) return;\n storage.upsertThread({\n ...existing,\n last_run_id: runId,\n last_run_status: status,\n active_run: {\n run_id: runId,\n status,\n created_at: existing.activeRun?.created_at ?? existing.active_run?.created_at ?? new Date().toISOString(),\n },\n lastRunId: runId,\n lastRunStatus: status,\n activeRun: {\n run_id: runId,\n status,\n created_at: existing.activeRun?.created_at ?? existing.active_run?.created_at ?? new Date().toISOString(),\n },\n lastEventSeq: typeof lastEventSeq === \"number\" ? lastEventSeq : existing.lastEventSeq ?? null,\n isRunning: status === \"queued\" || status === \"running\",\n });\n },\n [storage]\n );\n\n const refresh = useCallback(async () => {\n const data = await transport.listThreads();\n storage.setThreads((data.items || []).map((item) => threadSummaryToStored(item)));\n }, [storage, transport]);\n\n const applyThreadId = useCallback(\n (threadId: string, baseMessages: ChatMessage[]) => {\n if (!threadId || activeThreadIdRef.current === threadId) return;\n activeThreadIdRef.current = threadId;\n persistThread(threadId, messagesRef.current.length > 0 ? messagesRef.current : baseMessages, undefined, { touch: true });\n storage.setActiveThreadId?.(threadId);\n onActiveThreadIdChange?.(threadId);\n },\n [onActiveThreadIdChange, persistThread, storage]\n );\n\n const setStreamingText = (value: string) => {\n streamingContentRef.current = value;\n setStreamingContent(value);\n };\n\n const setLoadingHistory = useCallback((value: boolean) => {\n isLoadingHistoryRef.current = value;\n setIsLoadingHistory(value);\n }, []);\n\n const setReasoningSteps = useCallback((value: ChatReasoningStep[]) => {\n reasoningRef.current = value || [];\n setCurrentReasoning(value || []);\n }, []);\n\n const detachActiveStream = useCallback(() => {\n const controller = abortControllerRef.current;\n abortControllerRef.current = null;\n controller?.abort();\n activeRunIdRef.current = null;\n reattachedRunIdRef.current = null;\n streamingMessageIdRef.current = null;\n streamingContentRef.current = \"\";\n reasoningRef.current = [];\n setStreamingMessageId(null);\n setIsLoading(false);\n setStreamingContent(\"\");\n setCurrentReasoning([]);\n }, []);\n\n const setLiveAssistantMessage = useCallback(\n (input: {\n messageId: string;\n runId?: string | null;\n content: string;\n reasoning: ChatReasoningStep[];\n blocks?: ChatMessageBlock[];\n baseMessages?: ChatMessage[];\n }) => {\n setMessages((prev) => {\n const index = prev.findIndex(\n (message) => message.id === input.messageId || (input.runId && message.role === \"assistant\" && message.runId === input.runId)\n );\n if (index === -1) {\n const next = [...prev];\n (input.baseMessages || []).forEach((message) => {\n const isSameAssistant =\n message.id === input.messageId ||\n Boolean(input.runId && message.role === \"assistant\" && message.runId === input.runId);\n if (!isSameAssistant && !next.some((item) => item.id === message.id)) {\n next.push(message);\n }\n });\n next.push({\n id: input.messageId,\n role: \"assistant\",\n runId: input.runId ?? null,\n content: input.content,\n createdAt: new Date(),\n reasoningSteps: input.reasoning,\n isFinal: false,\n blocks: input.blocks,\n });\n messagesRef.current = next;\n return next;\n }\n const next = [...prev];\n next[index] = {\n ...next[index],\n runId: input.runId ?? next[index].runId ?? null,\n content: input.content,\n reasoningSteps: input.reasoning,\n isFinal: false,\n blocks: input.blocks ?? next[index].blocks,\n };\n messagesRef.current = next;\n return next;\n });\n },\n []\n );\n\n const finalizeAssistantMessage = useCallback(\n (input: FinalizeInput) => {\n const content = input.error || input.assistantText.trim();\n if (!content) return input.baseMessages;\n const existingIndex = input.baseMessages.findIndex(\n (message) => (input.messageId && message.id === input.messageId) || (input.runId && message.role === \"assistant\" && message.runId === input.runId)\n );\n const existing = existingIndex >= 0 ? input.baseMessages[existingIndex] : undefined;\n const blocks =\n input.blocks ||\n existing?.blocks ||\n renderBlocksFromResponseBlocks(undefined, content);\n const assistant: ChatMessage = {\n id: existing?.id || input.messageId || createId(),\n role: \"assistant\",\n runId: input.runId ?? existing?.runId ?? null,\n content,\n createdAt: new Date(),\n isFinal: true,\n blocks: blocks.map((block) => {\n if (block.kind === \"tool\") return { ...block, status: input.error ? \"error\" : \"done\" };\n if (block.kind === \"tool_group\") {\n return { ...block, status: input.error ? \"error\" : \"done\", tools: block.tools.map((tool) => ({ ...tool, status: input.error ? \"error\" : \"done\" })) };\n }\n return block;\n }),\n reasoningSteps: mergeReasoningSteps(input.reasoning, { finalize: true }),\n thinkingDurationMs: input.thinkingDurationMs,\n };\n const completed = existingIndex >= 0\n ? input.baseMessages.map((message, index) => (index === existingIndex ? assistant : message))\n : [...input.baseMessages, assistant];\n setMessages(completed);\n messagesRef.current = completed;\n if (input.threadId) {\n persistThread(input.threadId, completed);\n const existingThread = storage.getThread(input.threadId);\n if (existingThread && input.runId) {\n storage.upsertThread({\n ...existingThread,\n messages: completed,\n last_run_id: input.runId,\n last_run_status: input.error ? \"failed\" : \"completed\",\n active_run: null,\n lastRunId: input.runId,\n lastRunStatus: input.error ? \"failed\" : \"completed\",\n activeRun: null,\n isRunning: false,\n });\n }\n }\n return completed;\n },\n [createId, persistThread, storage]\n );\n\n const loadThread = useCallback(\n async (threadId: string) => {\n const seq = ++requestSeqRef.current;\n setLoadingHistory(true);\n setIsLoadingOlder(false);\n isLoadingOlderRef.current = false;\n try {\n const detail = await transport.getThread({ threadId, limit: pageSize });\n if (activeThreadIdRef.current !== threadId || seq !== requestSeqRef.current) return;\n const nextMessages = threadDetailToMessages(detail);\n const paging = threadPaging(detail);\n setContextStatus(latestContextWindowFromThread(detail));\n setMessages(nextMessages);\n messagesRef.current = nextMessages;\n setHasOlderTurns(paging.hasOlderTurns);\n hasOlderTurnsRef.current = paging.hasOlderTurns;\n nextBeforeTurnIndexRef.current = paging.nextBeforeTurnIndex;\n loadedThreadIdRef.current = threadId;\n storage.upsertThread({\n ...threadSummaryToStored(detail),\n messages: nextMessages,\n isHydrated: true,\n hasOlderTurns: paging.hasOlderTurns,\n nextBeforeTurnIndex: paging.nextBeforeTurnIndex,\n updated_at: threadActivityDate(detail),\n });\n } finally {\n if (activeThreadIdRef.current === threadId) setLoadingHistory(false);\n }\n },\n [pageSize, setLoadingHistory, storage, transport]\n );\n\n const loadOlderTurns = useCallback(async () => {\n const threadId = activeThreadIdRef.current;\n const beforeTurnIndex = nextBeforeTurnIndexRef.current;\n if (!threadId || beforeTurnIndex === null || isLoadingOlderRef.current) return;\n isLoadingOlderRef.current = true;\n setIsLoadingOlder(true);\n try {\n const detail = await transport.getThread({ threadId, limit: pageSize, beforeTurnIndex });\n if (activeThreadIdRef.current !== threadId) return;\n const older = threadDetailToMessages(detail);\n const paging = threadPaging(detail);\n const next = [...older, ...messagesRef.current];\n setMessages(next);\n messagesRef.current = next;\n setHasOlderTurns(paging.hasOlderTurns);\n hasOlderTurnsRef.current = paging.hasOlderTurns;\n nextBeforeTurnIndexRef.current = paging.nextBeforeTurnIndex;\n persistThread(threadId, next, paging);\n } finally {\n if (activeThreadIdRef.current === threadId) setIsLoadingOlder(false);\n isLoadingOlderRef.current = false;\n }\n }, [pageSize, persistThread, transport]);\n\n const handleStreamEvent = useCallback(\n (input: { event: ChatRuntimeEvent; assistantMessageId: string; startedAt: number; streamThreadIdRef: { current: string | null }; baseMessages: ChatMessage[] }) => {\n const { event, assistantMessageId, startedAt, streamThreadIdRef, baseMessages } = input;\n const payload = event.payload || {};\n const responseBlocks = Array.isArray(payload.response_blocks) ? (payload.response_blocks as Array<Record<string, unknown>>) : null;\n if (event.run_id) activeRunIdRef.current = event.run_id;\n setContextStatus((current) => mergeContextWindow(current, payload.context_window));\n if (responseBlocks) {\n const blockText = String(payload.assistant_output_text || \"\") || assistantTextFromBlocks(responseBlocks) || streamingContentRef.current;\n if (blockText) setStreamingText(blockText);\n const reasoning = mergeReasoningSteps([...reasoningRef.current, ...reasoningStepsFromBlocks(responseBlocks)]);\n setReasoningSteps(reasoning);\n setLiveAssistantMessage({\n messageId: assistantMessageId,\n runId: event.run_id || activeRunIdRef.current,\n content: blockText,\n reasoning,\n blocks: renderBlocksFromResponseBlocks(responseBlocks, blockText),\n baseMessages,\n });\n }\n if (event.event === \"run.accepted\" || event.event === \"run.snapshot\") {\n const nextThreadId = String(payload.thread_id || streamThreadIdRef.current || \"\");\n if (nextThreadId) {\n streamThreadIdRef.current = nextThreadId;\n applyThreadId(nextThreadId, baseMessages);\n markThreadRunStatus(nextThreadId, event.run_id || activeRunIdRef.current || \"\", String(payload.status || \"running\"), typeof payload.last_event_seq === \"number\" ? payload.last_event_seq : null);\n }\n return;\n }\n const isTerminal = event.event === \"run.completed\" || event.event === \"run.cancelled\" || event.event === \"reshet.stream.result\";\n const isFailed = event.event === \"run.failed\" || event.event.endsWith(\".stream.error\");\n if (!isTerminal && !isFailed) return;\n const terminalThreadId = String(payload.thread_id || \"\");\n if (terminalThreadId && !streamThreadIdRef.current) {\n streamThreadIdRef.current = terminalThreadId;\n applyThreadId(terminalThreadId, baseMessages);\n }\n const finalText = String(payload.assistant_output_text || textFromFinalOutput(payload.final_output) || streamingContentRef.current || \"\");\n finalizeAssistantMessage({\n threadId: streamThreadIdRef.current || activeThreadIdRef.current,\n baseMessages: messagesRef.current,\n assistantText: finalText,\n reasoning: reasoningRef.current,\n thinkingDurationMs: Date.now() - startedAt,\n messageId: assistantMessageId,\n runId: event.run_id || activeRunIdRef.current,\n blocks: responseBlocks ? renderBlocksFromResponseBlocks(responseBlocks, finalText) : undefined,\n error: isFailed\n ? String(payload.message || payload.error || event.diagnostics?.[0]?.message || onStreamErrorMessage?.(event) || \"The chat run failed.\")\n : undefined,\n });\n },\n [applyThreadId, finalizeAssistantMessage, markThreadRunStatus, onStreamErrorMessage, setLiveAssistantMessage, setReasoningSteps]\n );\n\n const runStream = useCallback(\n async (input: { mode: \"submit\"; message: { text: string; files?: ChatAttachment[] } } | { mode: \"attach\"; threadId: string; runId: string }) => {\n const startedAt = Date.now();\n const controller = new AbortController();\n requestSeqRef.current += 1;\n abortControllerRef.current = controller;\n setIsLoading(true);\n setStreamingText(\"\");\n setReasoningSteps([{ label: input.mode === \"attach\" ? \"Reconnecting\" : \"Connecting\", status: \"active\" }]);\n const streamThreadIdRef = { current: input.mode === \"attach\" ? input.threadId : activeThreadIdRef.current };\n const attachAssistantMessage = input.mode === \"attach\"\n ? [...messagesRef.current]\n .reverse()\n .find(\n (message) =>\n message.role === \"assistant\" &&\n (message.runId === input.runId || message.isFinal === false)\n )\n : undefined;\n let assistantMessageId = input.mode === \"attach\"\n ? attachAssistantMessage?.id || `${input.runId}-assistant`\n : createId();\n let baseMessages = messagesRef.current;\n if (input.mode === \"submit\") {\n const userMessage: ChatMessage = {\n id: createId(),\n role: \"user\",\n content: input.message.text,\n createdAt: new Date(),\n attachments: input.message.files,\n };\n baseMessages = [...messagesRef.current, userMessage];\n }\n if (!messagesRef.current.some((message) => message.id === assistantMessageId)) {\n const assistantMessage: ChatMessage = {\n id: assistantMessageId,\n role: \"assistant\",\n content: \"\",\n createdAt: new Date(),\n isFinal: false,\n reasoningSteps: [],\n };\n const liveMessages: ChatMessage[] = [...baseMessages, assistantMessage];\n setMessages(liveMessages);\n messagesRef.current = liveMessages;\n } else if (input.mode === \"attach\" && attachAssistantMessage) {\n const nextMessages = messagesRef.current.map((message) =>\n message.id === attachAssistantMessage.id\n ? { ...message, runId: message.runId || input.runId, isFinal: false }\n : message\n );\n setMessages(nextMessages);\n messagesRef.current = nextMessages;\n baseMessages = nextMessages;\n if (streamThreadIdRef.current) persistThread(streamThreadIdRef.current, nextMessages);\n }\n streamingMessageIdRef.current = assistantMessageId;\n setStreamingMessageId(assistantMessageId);\n if (streamThreadIdRef.current) {\n persistThread(\n streamThreadIdRef.current,\n messagesRef.current.length > 0 ? messagesRef.current : baseMessages,\n undefined,\n { touch: input.mode === \"submit\" }\n );\n }\n try {\n if (input.mode === \"attach\") {\n activeRunIdRef.current = input.runId;\n reattachedRunIdRef.current = input.runId;\n await transport.attachRun({ runId: input.runId, signal: controller.signal }, (event) =>\n handleStreamEvent({ event, assistantMessageId, startedAt, streamThreadIdRef, baseMessages })\n );\n } else {\n await transport.streamMessage(\n { text: input.message.text, files: input.message.files || [], threadId: activeThreadIdRef.current, signal: controller.signal },\n (event) => handleStreamEvent({ event, assistantMessageId, startedAt, streamThreadIdRef, baseMessages })\n );\n }\n if (streamingContentRef.current.trim() && streamingMessageIdRef.current) {\n finalizeAssistantMessage({\n threadId: streamThreadIdRef.current,\n baseMessages: messagesRef.current,\n assistantText: streamingContentRef.current,\n reasoning: reasoningRef.current,\n thinkingDurationMs: Date.now() - startedAt,\n messageId: assistantMessageId,\n runId: activeRunIdRef.current,\n });\n }\n await refresh().catch(() => undefined);\n } catch (error) {\n if ((error as Error).name !== \"AbortError\") {\n finalizeAssistantMessage({\n threadId: streamThreadIdRef.current,\n baseMessages: messagesRef.current,\n assistantText: streamingContentRef.current,\n reasoning: reasoningRef.current,\n thinkingDurationMs: Date.now() - startedAt,\n messageId: assistantMessageId,\n runId: activeRunIdRef.current,\n error: onStreamErrorMessage?.(error) || (error as Error).message || \"Failed to reach the chat agent.\",\n });\n }\n } finally {\n const isCurrentStream =\n abortControllerRef.current === controller ||\n streamingMessageIdRef.current === assistantMessageId;\n if (abortControllerRef.current === controller) abortControllerRef.current = null;\n if (isCurrentStream) {\n activeRunIdRef.current = null;\n streamingMessageIdRef.current = null;\n reattachedRunIdRef.current = null;\n setStreamingMessageId(null);\n setIsLoading(false);\n setStreamingText(\"\");\n setReasoningSteps([]);\n setLastThinkingDurationMs(Date.now() - startedAt);\n }\n }\n },\n [createId, finalizeAssistantMessage, handleStreamEvent, onStreamErrorMessage, persistThread, refresh, setReasoningSteps, transport]\n );\n\n const handleSubmit = useCallback(\n async (message: { text: string; files?: ChatAttachment[] }) => {\n if (!message.text.trim() && !(message.files || []).length) return;\n await runStream({ mode: \"submit\", message });\n },\n [runStream]\n );\n\n const handleStop = useCallback(() => {\n const runId = activeRunIdRef.current;\n const partial = streamingContentRef.current;\n const liveMessageId = streamingMessageIdRef.current;\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n activeRunIdRef.current = null;\n streamingMessageIdRef.current = null;\n setStreamingMessageId(null);\n setIsLoading(false);\n setStreamingText(\"\");\n setReasoningSteps([]);\n if (runId) transport.cancelRun({ runId, assistantOutputText: partial }).catch(() => undefined);\n if (partial.trim()) {\n finalizeAssistantMessage({\n threadId: activeThreadIdRef.current,\n baseMessages: messagesRef.current,\n assistantText: partial,\n reasoning: reasoningRef.current,\n thinkingDurationMs: lastThinkingDurationMs || 0,\n messageId: liveMessageId,\n });\n }\n }, [finalizeAssistantMessage, lastThinkingDurationMs, setReasoningSteps, transport]);\n\n useEffect(() => {\n refresh().catch(() => storage.setThreads([]));\n }, [refresh, storage]);\n\n useEffect(() => {\n const previous = activeThreadIdRef.current;\n activeThreadIdRef.current = activeThreadId;\n if (\n activeThreadId &&\n previous === activeThreadId &&\n (activeRunIdRef.current || streamingMessageIdRef.current)\n ) {\n return;\n }\n if (previous && previous !== activeThreadId && abortControllerRef.current) {\n detachActiveStream();\n }\n if (!activeThreadId) {\n requestSeqRef.current += 1;\n loadedThreadIdRef.current = null;\n setMessages([]);\n messagesRef.current = [];\n setHasOlderTurns(false);\n setIsLoadingOlder(false);\n setContextStatus(null);\n nextBeforeTurnIndexRef.current = null;\n setLoadingHistory(false);\n return;\n }\n const cached = storage.getThread(activeThreadId);\n const cachedMessages = cached?.isHydrated && cached.messages?.length ? cached.messages : null;\n const hasCachedMessages = Boolean(cachedMessages);\n const shouldRefreshStaleCache = hasCachedMessages && hasStaleUnfinishedAssistantCache(cached);\n if (cached && cachedMessages) {\n setMessages(cachedMessages);\n messagesRef.current = cachedMessages;\n setHasOlderTurns(Boolean(cached.hasOlderTurns));\n hasOlderTurnsRef.current = Boolean(cached.hasOlderTurns);\n nextBeforeTurnIndexRef.current = cached.nextBeforeTurnIndex ?? null;\n loadedThreadIdRef.current = activeThreadId;\n setLoadingHistory(false);\n if (!shouldRefreshStaleCache) return;\n }\n if (!hasCachedMessages) {\n setMessages([]);\n messagesRef.current = [];\n }\n void loadThread(activeThreadId).catch(() => setLoadingHistory(false));\n }, [activeThreadId, detachActiveStream, loadThread, setLoadingHistory, storage]);\n\n useEffect(() => {\n const threadId = activeThreadId;\n if (!threadId || isLoadingHistory || loadedThreadIdRef.current !== threadId || activeRunIdRef.current) return;\n const runId = activeRunIdFromThread(storage.getThread(threadId));\n if (!runId || reattachedRunIdRef.current === runId) return;\n void runStream({ mode: \"attach\", threadId, runId });\n }, [activeThreadId, isLoadingHistory, runStream, storage, storageKey]);\n\n useEffect(() => {\n const threadId = activeThreadId;\n if (\n !threadId ||\n isLoadingHistoryRef.current ||\n activeRunIdRef.current ||\n streamingMessageIdRef.current\n ) {\n return;\n }\n const cached = storage.getThread(threadId);\n if (!hasStaleUnfinishedAssistantCache(cached)) return;\n void loadThread(threadId).catch(() => setLoadingHistory(false));\n }, [activeThreadId, loadThread, setLoadingHistory, storage, storageKey]);\n\n const handleCopy = useCallback((content: string, messageId: string) => {\n navigator.clipboard?.writeText(content);\n setCopiedMessageId(messageId);\n setTimeout(() => setCopiedMessageId(null), 200);\n }, []);\n\n const handleLike = useCallback(async (msg: ChatMessage) => {\n const nextLiked = !liked[msg.id];\n setLiked((prev) => ({ ...prev, [msg.id]: nextLiked }));\n if (nextLiked) setDisliked((prev) => ({ ...prev, [msg.id]: false }));\n }, [liked]);\n\n const handleDislike = useCallback(async (msg: ChatMessage) => {\n const nextDisliked = !disliked[msg.id];\n setDisliked((prev) => ({ ...prev, [msg.id]: nextDisliked }));\n if (nextDisliked) setLiked((prev) => ({ ...prev, [msg.id]: false }));\n }, [disliked]);\n\n const handleRetry = useCallback(async (msg: ChatMessage) => {\n const index = messagesRef.current.findIndex((message) => message.id === msg.id);\n if (index <= 0) return;\n const userMessage = messagesRef.current[index - 1];\n if (userMessage.role !== \"user\") return;\n const trimmed = messagesRef.current.slice(0, index);\n setMessages(trimmed);\n messagesRef.current = trimmed;\n if (activeThreadIdRef.current) persistThread(activeThreadIdRef.current, trimmed);\n await handleSubmit({ text: userMessage.content, files: userMessage.attachments || [] });\n }, [handleSubmit, persistThread]);\n\n const upsertLiveVoiceMessage = useCallback((input: {\n role: \"user\" | \"assistant\";\n content: string;\n isFinal?: boolean;\n citations?: ChatMessage[\"citations\"];\n reasoningSteps?: ChatReasoningStep[];\n }) => {\n const content = input.content?.trim() ?? \"\";\n if (!content && !input.citations?.length && !input.reasoningSteps?.length) return;\n setMessages((prev) => {\n const currentId = liveVoiceIdsRef.current[input.role];\n const index = currentId ? prev.findIndex((message) => message.id === currentId) : -1;\n const nextMessage: ChatMessage = {\n id: currentId || createId(),\n role: input.role,\n content,\n createdAt: new Date(),\n isFinal: Boolean(input.isFinal),\n isVoice: input.role === \"user\",\n citations: input.citations,\n reasoningSteps: input.reasoningSteps,\n };\n const next = index === -1 ? [...prev, nextMessage] : prev.map((message, itemIndex) => itemIndex === index ? { ...message, ...nextMessage } : message);\n liveVoiceIdsRef.current[input.role] = input.isFinal ? undefined : nextMessage.id;\n messagesRef.current = next;\n if (activeThreadIdRef.current) persistThread(activeThreadIdRef.current, next);\n return next;\n });\n }, [createId, persistThread]);\n\n return useMemo(() => ({\n messages,\n streamingContent,\n streamingMessageId,\n contextStatus,\n currentReasoning,\n isLoading,\n isLoadingHistory,\n isLoadingOlder,\n hasOlderTurns,\n liked,\n disliked,\n copiedMessageId,\n lastThinkingDurationMs,\n activeRunId: activeRunIdRef.current,\n handleSubmit,\n handleStop,\n handleCopy,\n handleLike,\n handleDislike,\n handleRetry,\n handleSourceClick: (citations: ChatMessage[\"citations\"]) => onSourceClick?.(citations),\n upsertLiveVoiceMessage,\n loadOlderTurns,\n refresh,\n textareaRef,\n }), [\n copiedMessageId,\n contextStatus,\n currentReasoning,\n disliked,\n handleCopy,\n handleDislike,\n handleLike,\n handleRetry,\n handleStop,\n handleSubmit,\n hasOlderTurns,\n isLoading,\n isLoadingHistory,\n isLoadingOlder,\n lastThinkingDurationMs,\n liked,\n loadOlderTurns,\n messages,\n onSourceClick,\n refresh,\n streamingContent,\n streamingMessageId,\n upsertLiveVoiceMessage,\n ]);\n}\n","import type {\n ChatContextWindow,\n ChatMessage,\n ChatMessageBlock,\n ChatReasoningStep,\n ChatRuntimeEvent,\n ChatThreadDetail,\n ChatThreadSummary,\n ChatThreadTurn,\n ChatToolActionKey,\n ChatToolBlock,\n ChatToolStatus,\n} from \"./types\";\n\nexport const DEFAULT_THREAD_PAGE_SIZE = 5;\n\nexport const isRunningThreadStatus = (status?: string | null) =>\n new Set([\"queued\", \"running\"]).has(String(status || \"\").toLowerCase());\n\nexport const createChatId = () => {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) return crypto.randomUUID();\n return `chat-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n};\n\nexport const titleFromMessage = (text: string, files: Array<{ filename?: string }> = []) => {\n const base = text.trim() || files[0]?.filename || \"New chat\";\n return base.replace(/\\s+/g, \" \").slice(0, 48);\n};\n\nexport const threadActivityDate = (thread: ChatThreadSummary) =>\n String(thread.updated_at || thread.last_activity_at || thread.created_at || new Date().toISOString());\n\nexport const assistantTextFromBlocks = (blocks?: Array<Record<string, unknown>>) =>\n (blocks || [])\n .filter((block) => block.kind === \"assistant_text\" && typeof block.text === \"string\")\n .map((block) => String(block.text))\n .join(\"\\n\\n\")\n .trim();\n\nexport const textFromFinalOutput = (value: unknown) => {\n if (typeof value === \"string\") return value;\n if (!value || typeof value !== \"object\") return \"\";\n const record = value as Record<string, unknown>;\n return String(record.message || record.text || record.answer || \"\");\n};\n\nconst displayTextWithoutInlineAttachments = (text: string, hasAttachments: boolean) => {\n if (!hasAttachments) return text;\n const marker = \"Attached text file (\";\n const trimmed = text.trim();\n if (trimmed.startsWith(marker)) return \"\";\n const markerIndex = text.indexOf(`\\n\\n${marker}`);\n if (markerIndex === -1) return text;\n return text.slice(0, markerIndex).trim();\n};\n\nconst attachmentsFromTurn = (turn: ChatThreadTurn) =>\n (turn.attachments || []).map((attachment, index) => {\n const record = attachment || {};\n return {\n ...record,\n type: \"file\",\n url: String(record.url || \"\"),\n filename: String(record.filename || record.name || `attachment-${index + 1}`),\n mediaType: String(record.mime_type || record.mediaType || record.type || \"application/octet-stream\"),\n };\n });\n\nconst latestEventPayloadValue = (events: ChatRuntimeEvent[] | undefined, key: string) => {\n for (let index = (events || []).length - 1; index >= 0; index -= 1) {\n const payload = events?.[index]?.payload;\n if (payload && payload[key] !== undefined && payload[key] !== null) return payload[key];\n }\n return undefined;\n};\n\nconst responseBlocksFromTurn = (turn: ChatThreadTurn) => {\n if (Array.isArray(turn.response_blocks) && turn.response_blocks.length > 0) return turn.response_blocks;\n const fromEvents = latestEventPayloadValue(turn.run_events, \"response_blocks\");\n return Array.isArray(fromEvents) ? (fromEvents as Array<Record<string, unknown>>) : [];\n};\n\nconst assistantTextFromEvents = (events?: ChatRuntimeEvent[]) => {\n const assistantText = latestEventPayloadValue(events, \"assistant_output_text\");\n if (typeof assistantText === \"string\" && assistantText.trim()) return assistantText;\n return textFromFinalOutput(latestEventPayloadValue(events, \"final_output\"));\n};\n\nconst normalizeToolStatus = (status?: unknown): ChatToolStatus => {\n if (status === \"running\" || status === \"active\" || status === \"pending\") return \"running\";\n if (status === \"failed\" || status === \"error\") return \"error\";\n return \"done\";\n};\n\nconst toolName = (tool: Record<string, unknown>) =>\n String(tool.toolName || tool.tool_name || tool.name || tool.slug || tool.action || tool.title || \"\")\n .trim()\n .toLowerCase();\n\nconst humanize = (value: string) =>\n value\n .replace(/[_-]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n\nconst toolActionKey = (tool: Record<string, unknown>): ChatToolActionKey => {\n const name = toolName(tool);\n if (name.includes(\"search\")) return \"search\";\n if (name.includes(\"browse\") || name.includes(\"navigate\")) return \"navigate\";\n if (name.includes(\"resolve\")) return \"resolve\";\n if (name.includes(\"open\") || name.includes(\"read\")) return \"read\";\n if (name.includes(\"context\")) return \"context\";\n if (name.includes(\"link\")) return \"links\";\n return \"work\";\n};\n\nconst actionLabels: Record<ChatToolActionKey, string> = {\n search: \"Searching\",\n navigate: \"Navigating\",\n resolve: \"Resolving\",\n read: \"Reading\",\n context: \"Checking context\",\n links: \"Finding links\",\n work: \"Working\",\n};\n\nconst toolTitle = (tool: Record<string, unknown>) => {\n const explicit = tool.title || tool.label || tool.summary;\n if (explicit) return String(explicit);\n const name = toolName(tool);\n return name ? humanize(name) : actionLabels[toolActionKey(tool)];\n};\n\nconst toolDetail = (tool: Record<string, unknown>) => {\n const summary = String(tool.summary || \"\").trim();\n const detail = String(tool.detail || \"\").trim();\n return summary || detail || undefined;\n};\n\nconst summarizeToolGroup = (tools: ChatToolBlock[]) => {\n if (tools.length === 1) return tools[0].title;\n const counts = new Map<ChatToolActionKey, number>();\n tools.forEach((tool) => counts.set(tool.actionKey, (counts.get(tool.actionKey) || 0) + 1));\n return Array.from(counts.entries())\n .map(([key, count]) => `${actionLabels[key]} ${count}`)\n .join(\", \");\n};\n\nconst toolGroupStatus = (tools: ChatToolBlock[]): ChatToolStatus => {\n if (tools.some((tool) => tool.status === \"error\")) return \"error\";\n if (tools.some((tool) => tool.status === \"running\")) return \"running\";\n return \"done\";\n};\n\nconst createToolBlock = (block: Record<string, unknown>, index: number): ChatToolBlock => {\n const tool = (block.tool || {}) as Record<string, unknown>;\n const actionKey = toolActionKey(tool);\n return {\n id: String(block.id || `${block.kind || \"tool\"}-${index}`),\n kind: \"tool\",\n title: toolTitle(tool),\n actionLabel: actionLabels[actionKey],\n actionKey,\n status: normalizeToolStatus(block.status),\n detail: toolDetail(tool),\n };\n};\n\nexport const renderBlocksFromResponseBlocks = (\n blocks?: Array<Record<string, unknown>>,\n fallbackText?: string\n): ChatMessageBlock[] => {\n const mapped: ChatMessageBlock[] = [];\n let pendingTools: ChatToolBlock[] = [];\n const flushTools = () => {\n if (pendingTools.length === 0) return;\n mapped.push({\n id: `tool-group-${pendingTools[0].id}`,\n kind: \"tool_group\",\n title: summarizeToolGroup(pendingTools),\n status: toolGroupStatus(pendingTools),\n tools: pendingTools,\n });\n pendingTools = [];\n };\n (blocks || []).forEach((block, index) => {\n const id = String(block.id || `${block.kind || \"block\"}-${index}`);\n if (block.kind === \"assistant_text\" && typeof block.text === \"string\") {\n flushTools();\n mapped.push({ id, kind: \"text\", content: String(block.text) });\n return;\n }\n if (block.kind === \"tool_call\") pendingTools.push(createToolBlock(block, index));\n });\n flushTools();\n if (!mapped.some((block) => block.kind === \"text\") && fallbackText?.trim()) {\n mapped.push({ id: \"assistant-fallback-text\", kind: \"text\", content: fallbackText });\n }\n return mapped;\n};\n\nexport const mergeReasoningSteps = (\n steps?: ChatReasoningStep[],\n options?: { finalize?: boolean }\n) => {\n if (!steps?.length) return [];\n const merged: ChatReasoningStep[] = [];\n const indexMap = new Map<string, number>();\n steps.forEach((step) => {\n const key = String(step.label);\n const status = options?.finalize ? \"complete\" : step.status || \"complete\";\n if (indexMap.has(key)) {\n const index = indexMap.get(key)!;\n merged[index] = { ...merged[index], ...step, status };\n } else {\n indexMap.set(key, merged.push({ ...step, status }) - 1);\n }\n });\n return merged;\n};\n\nexport const reasoningStepsFromBlocks = (blocks?: Array<Record<string, unknown>>): ChatReasoningStep[] =>\n (blocks || [])\n .map((block) => {\n const kind = String(block.kind || \"\");\n if (kind === \"tool_call\") {\n const tool = (block.tool || {}) as Record<string, unknown>;\n return {\n label: toolTitle(tool),\n status: block.status === \"running\" ? \"active\" : \"complete\",\n description: String(tool.summary || tool.detail || tool.action || \"\"),\n } satisfies ChatReasoningStep;\n }\n if (kind === \"reasoning_note\") {\n return {\n label: String(block.label || \"Reasoning\"),\n status: block.status === \"running\" ? \"active\" : \"complete\",\n description: String(block.text || block.summary || \"\"),\n } satisfies ChatReasoningStep;\n }\n return null;\n })\n .filter(Boolean) as ChatReasoningStep[];\n\nconst turnToMessages = (turn: ChatThreadTurn, activeRunId?: string | null): ChatMessage[] => {\n const messages: ChatMessage[] = [];\n const createdAt = turn.created_at ? new Date(turn.created_at) : new Date();\n const baseId = turn.id || turn.run_id || createChatId();\n const responseBlocks = responseBlocksFromTurn(turn);\n const isRunning = isRunningThreadStatus(turn.status) || Boolean(turn.run_id && activeRunId === turn.run_id);\n const attachments = attachmentsFromTurn(turn);\n const userContent = displayTextWithoutInlineAttachments(turn.user_input_text || \"\", attachments.length > 0);\n if (userContent || attachments.length > 0) {\n messages.push({\n id: `${baseId}-user`,\n role: \"user\",\n content: userContent,\n createdAt,\n attachments,\n });\n }\n const assistantText =\n turn.assistant_output_text ||\n assistantTextFromBlocks(responseBlocks) ||\n assistantTextFromEvents(turn.run_events) ||\n textFromFinalOutput(turn.final_output);\n if (assistantText || responseBlocks.length > 0 || isRunning) {\n messages.push({\n id: `${baseId}-assistant`,\n role: \"assistant\",\n runId: turn.run_id || null,\n content: assistantText,\n createdAt: turn.completed_at ? new Date(turn.completed_at) : createdAt,\n blocks: renderBlocksFromResponseBlocks(responseBlocks, assistantText),\n reasoningSteps: mergeReasoningSteps(reasoningStepsFromBlocks(responseBlocks), { finalize: !isRunning }),\n isFinal: !isRunning,\n });\n }\n return messages;\n};\n\nexport const threadDetailToMessages = (thread: ChatThreadDetail) => {\n const activeRun = activeRunIdFromThreadDetail(thread);\n return (thread.turns || []).flatMap((turn) => turnToMessages(turn, activeRun));\n};\n\nexport const threadPaging = (thread: ChatThreadDetail) => {\n const nextBeforeTurnIndex = thread.paging?.next_before_turn_index ?? null;\n return {\n hasOlderTurns: Boolean(thread.paging?.has_more || nextBeforeTurnIndex !== null),\n nextBeforeTurnIndex,\n };\n};\n\nexport const latestContextWindowFromThread = (thread: ChatThreadDetail): ChatContextWindow | null => {\n if (thread.context_window && typeof thread.context_window === \"object\") return thread.context_window as ChatContextWindow;\n for (let index = (thread.turns || []).length - 1; index >= 0; index -= 1) {\n const value = thread.turns?.[index]?.context_window;\n if (value && typeof value === \"object\") return value as ChatContextWindow;\n }\n return null;\n};\n\nexport const activeRunIdFromThread = (thread?: Partial<ChatThreadSummary> | null) => {\n const hasCamelActiveRun = Boolean(\n thread && Object.prototype.hasOwnProperty.call(thread, \"activeRun\")\n );\n const hasCamelLastRunStatus = Boolean(\n thread && Object.prototype.hasOwnProperty.call(thread, \"lastRunStatus\")\n );\n const hasCamelLastRunId = Boolean(\n thread && Object.prototype.hasOwnProperty.call(thread, \"lastRunId\")\n );\n const activeRun = hasCamelActiveRun ? thread?.activeRun || null : thread?.active_run || null;\n const lastRunStatus = hasCamelLastRunStatus\n ? thread?.lastRunStatus || null\n : thread?.last_run_status || thread?.lastRunStatus || null;\n const activeRunId = activeRun?.run_id ? String(activeRun.run_id) : \"\";\n if (activeRunId && isRunningThreadStatus(activeRun?.status || lastRunStatus)) return activeRunId;\n const lastRunId = hasCamelLastRunId\n ? thread?.lastRunId\n : thread?.last_run_id || thread?.lastRunId;\n return lastRunId && isRunningThreadStatus(lastRunStatus) ? String(lastRunId) : null;\n};\n\nexport const hasUnfinishedAssistantMessage = (messages?: ChatMessage[]) =>\n Boolean(messages?.some((message) => message.role === \"assistant\" && message.isFinal === false));\n\nexport const hasStaleUnfinishedAssistantCache = (\n thread?: (Partial<ChatThreadSummary> & { messages?: ChatMessage[] }) | null\n) => hasUnfinishedAssistantMessage(thread?.messages) && !activeRunIdFromThread(thread);\n\nexport const activeRunIdFromThreadDetail = (thread?: ChatThreadDetail | null) => {\n const summaryRunId = activeRunIdFromThread(thread);\n if (summaryRunId) return summaryRunId;\n const runningTurn = [...(thread?.turns || [])].reverse().find((turn) => turn.run_id && isRunningThreadStatus(turn.status));\n return runningTurn?.run_id ? String(runningTurn.run_id) : null;\n};\n","import type { ChatRuntimeEvent, ChatStreamResult } from \"./types\";\n\nexport const parseSseBlock = (block: string): ChatRuntimeEvent | null => {\n const data = block\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.replace(/^data:\\s?/, \"\"))\n .join(\"\\n\")\n .trim();\n if (!data) return null;\n return JSON.parse(data) as ChatRuntimeEvent;\n};\n\nexport const consumeSseResponse = async (\n response: Response,\n onEvent: (event: ChatRuntimeEvent) => void | Promise<void>\n): Promise<ChatStreamResult> => {\n if (!response.ok) {\n let message = response.statusText || \"Failed to open chat stream.\";\n try {\n const errorData = await response.json();\n message = String(errorData.detail || errorData.message || message);\n } catch {\n // Keep the status text.\n }\n throw new Error(message);\n }\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"The chat stream did not return a readable body.\");\n const decoder = new TextDecoder();\n let buffer = \"\";\n let threadId: string | null = null;\n let runId: string | null = null;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary !== -1) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n boundary = buffer.indexOf(\"\\n\\n\");\n const event = parseSseBlock(block);\n if (!event) continue;\n if (event.run_id) runId = event.run_id;\n const payloadThreadId = event.payload?.thread_id;\n if (payloadThreadId) threadId = String(payloadThreadId);\n await onEvent(event);\n }\n }\n return { threadId, runId };\n};\n","import { consumeSseResponse } from \"./sse\";\nimport type { ChatAttachment, ChatTransport } from \"./types\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport type FetchChatTransportRoutes = {\n listThreads: () => string;\n getThread: (input: { threadId: string; limit?: number; beforeTurnIndex?: number | null }) => string;\n streamMessage: () => string;\n attachRun: (input: { runId: string }) => string;\n cancelRun: (input: { runId: string }) => string;\n deleteThread?: (input: { threadId: string }) => string;\n};\n\nexport type FetchChatTransportOptions = {\n routes: FetchChatTransportRoutes;\n fetchImpl?: typeof fetch;\n headers?: () => MaybePromise<HeadersInit>;\n streamBody?: (input: {\n text: string;\n threadId?: string | null;\n files?: ChatAttachment[];\n }) => unknown;\n};\n\nconst jsonHeaders = (headers?: HeadersInit) => ({\n ...(headers || {}),\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n});\n\nconst streamHeaders = (headers?: HeadersInit) => ({\n ...(headers || {}),\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n});\n\nexport const createFetchChatTransport = ({\n routes,\n fetchImpl = fetch,\n headers,\n streamBody,\n}: FetchChatTransportOptions): ChatTransport => {\n const loadHeaders = async () => headers?.() ?? {};\n return {\n async listThreads(input) {\n const response = await fetchImpl(routes.listThreads(), {\n signal: input?.signal,\n headers: jsonHeaders(await loadHeaders()),\n });\n if (!response.ok) throw new Error(response.statusText || \"Failed to list chat threads.\");\n return response.json();\n },\n async getThread(input) {\n const response = await fetchImpl(routes.getThread(input), {\n signal: input.signal,\n headers: jsonHeaders(await loadHeaders()),\n });\n if (!response.ok) throw new Error(response.statusText || \"Failed to load chat thread.\");\n return response.json();\n },\n async streamMessage(input, onEvent) {\n const response = await fetchImpl(routes.streamMessage(), {\n method: \"POST\",\n signal: input.signal,\n headers: streamHeaders(await loadHeaders()),\n body: JSON.stringify(\n streamBody?.(input) ?? {\n input: input.text,\n thread_id: input.threadId || undefined,\n files: input.files || [],\n }\n ),\n });\n return consumeSseResponse(response, onEvent);\n },\n async attachRun(input, onEvent) {\n const response = await fetchImpl(routes.attachRun(input), {\n method: \"POST\",\n signal: input.signal,\n headers: streamHeaders(await loadHeaders()),\n body: JSON.stringify({}),\n });\n return consumeSseResponse(response, onEvent);\n },\n async cancelRun(input) {\n const response = await fetchImpl(routes.cancelRun(input), {\n method: \"POST\",\n headers: jsonHeaders(await loadHeaders()),\n body: JSON.stringify({ assistant_output_text: input.assistantOutputText || undefined }),\n });\n if (!response.ok) throw new Error(response.statusText || \"Failed to cancel chat run.\");\n return response.json();\n },\n async deleteThread(input) {\n if (!routes.deleteThread) return { deleted: false };\n const response = await fetchImpl(routes.deleteThread(input), {\n method: \"DELETE\",\n headers: jsonHeaders(await loadHeaders()),\n });\n if (!response.ok) throw new Error(response.statusText || \"Failed to delete chat thread.\");\n return response.json();\n },\n };\n};\n","import {\n type ReactNode,\n type RefObject,\n type UIEvent,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nconst LATEST_EDGE_THRESHOLD_PX = 2;\nconst MIN_OLDER_PREFETCH_PX = 320;\nconst MAX_OLDER_PREFETCH_PX = 900;\n\nexport const isScrollable = (element: Pick<HTMLDivElement, \"scrollHeight\" | \"clientHeight\">) =>\n element.scrollHeight - element.clientHeight > LATEST_EDGE_THRESHOLD_PX;\n\nexport const isAtTimelineLatestEdge = (\n element: Pick<HTMLDivElement, \"scrollHeight\" | \"clientHeight\" | \"scrollTop\">,\n isTopOrigin: boolean\n) => {\n if (!isScrollable(element)) return true;\n return isTopOrigin\n ? element.scrollHeight - element.clientHeight - element.scrollTop <= LATEST_EDGE_THRESHOLD_PX\n : Math.abs(element.scrollTop) <= LATEST_EDGE_THRESHOLD_PX;\n};\n\nexport const shouldPrefetchOlder = (\n element: Pick<HTMLDivElement, \"scrollHeight\" | \"clientHeight\" | \"scrollTop\">\n) =>\n Math.abs(element.scrollTop) + element.clientHeight >=\n element.scrollHeight - Math.min(MAX_OLDER_PREFETCH_PX, Math.max(MIN_OLDER_PREFETCH_PX, element.clientHeight * 0.75));\n\nexport const getLatestScrollTop = (\n element: Pick<HTMLDivElement, \"scrollHeight\" | \"clientHeight\">,\n isTopOrigin: boolean\n) => isTopOrigin ? Math.max(0, element.scrollHeight - element.clientHeight) : 0;\n\nexport type UseLatestThreadViewportOptions = {\n itemCount: number;\n hasOlder: boolean;\n isLoadingOlder: boolean;\n onLoadOlder: () => Promise<void> | void;\n activeStreamKey?: string | null;\n shouldAutoFollow?: boolean;\n topOriginMaxItems?: number;\n};\n\nexport type LatestThreadViewportState = {\n scrollContainerRef: RefObject<HTMLDivElement | null>;\n isAtLatest: boolean;\n isTopOrigin: boolean;\n shouldShowLatestButton: boolean;\n handleScroll: (event: UIEvent<HTMLDivElement>) => void;\n scrollToLatest: () => void;\n preserveIntrinsicResize: () => void;\n};\n\nexport function useLatestThreadViewport({\n itemCount,\n hasOlder,\n isLoadingOlder,\n onLoadOlder,\n activeStreamKey,\n shouldAutoFollow = true,\n topOriginMaxItems = 4,\n}: UseLatestThreadViewportOptions): LatestThreadViewportState {\n const scrollContainerRef = useRef<HTMLDivElement | null>(null);\n const olderPagePreserveRef = useRef<{ previousHeight: number; previousTop: number } | null>(null);\n const olderPageRequestInFlightRef = useRef(false);\n const intrinsicResizePreserveRef = useRef<{ lastHeight: number; endAt: number; frame: number | null } | null>(null);\n const autoFollowLatestRef = useRef(true);\n const programmaticScrollRef = useRef(false);\n const programmaticScrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const activeStreamKeyRef = useRef<string | null>(null);\n const [isAtLatest, setIsAtLatest] = useState(true);\n const [topOriginCandidateOverflows, setTopOriginCandidateOverflows] = useState(false);\n\n const topOriginCandidate = !hasOlder && itemCount > 0 && itemCount <= topOriginMaxItems;\n const isTopOrigin = topOriginCandidate && !topOriginCandidateOverflows;\n\n const markProgrammaticScroll = useCallback(() => {\n programmaticScrollRef.current = true;\n if (programmaticScrollTimeoutRef.current) clearTimeout(programmaticScrollTimeoutRef.current);\n programmaticScrollTimeoutRef.current = setTimeout(() => {\n programmaticScrollRef.current = false;\n programmaticScrollTimeoutRef.current = null;\n }, 80);\n }, []);\n\n const scrollToLatest = useCallback(() => {\n const element = scrollContainerRef.current;\n if (!element) return;\n markProgrammaticScroll();\n element.scrollTop = getLatestScrollTop(element, isTopOrigin);\n setIsAtLatest(true);\n }, [isTopOrigin, markProgrammaticScroll]);\n\n useEffect(() => {\n return () => {\n if (programmaticScrollTimeoutRef.current) clearTimeout(programmaticScrollTimeoutRef.current);\n const preserve = intrinsicResizePreserveRef.current;\n if (preserve?.frame !== null && preserve?.frame !== undefined) cancelAnimationFrame(preserve.frame);\n };\n }, []);\n\n useLayoutEffect(() => {\n const element = scrollContainerRef.current;\n const preserve = olderPagePreserveRef.current;\n if (!element) return;\n if (topOriginCandidate) {\n setTopOriginCandidateOverflows(isScrollable(element));\n } else if (topOriginCandidateOverflows) {\n setTopOriginCandidateOverflows(false);\n }\n if (!preserve) {\n setIsAtLatest(isAtTimelineLatestEdge(element, isTopOrigin));\n return;\n }\n const addedHeight = element.scrollHeight - preserve.previousHeight;\n markProgrammaticScroll();\n element.scrollTop = preserve.previousTop - addedHeight;\n olderPagePreserveRef.current = null;\n olderPageRequestInFlightRef.current = false;\n setIsAtLatest(isAtTimelineLatestEdge(element, isTopOrigin));\n }, [isTopOrigin, itemCount, markProgrammaticScroll, topOriginCandidate, topOriginCandidateOverflows]);\n\n const handleScroll = useCallback(\n (event: UIEvent<HTMLDivElement>) => {\n const element = event.currentTarget;\n const atLatest = isAtTimelineLatestEdge(element, isTopOrigin);\n setIsAtLatest(atLatest);\n if (!programmaticScrollRef.current) autoFollowLatestRef.current = atLatest;\n if (\n isTopOrigin ||\n !hasOlder ||\n isLoadingOlder ||\n olderPageRequestInFlightRef.current ||\n !shouldPrefetchOlder(element)\n ) {\n return;\n }\n olderPageRequestInFlightRef.current = true;\n olderPagePreserveRef.current = {\n previousHeight: element.scrollHeight,\n previousTop: element.scrollTop,\n };\n void Promise.resolve(onLoadOlder()).finally(() => {\n requestAnimationFrame(() => {\n if (!olderPagePreserveRef.current) return;\n olderPagePreserveRef.current = null;\n olderPageRequestInFlightRef.current = false;\n });\n });\n },\n [hasOlder, isLoadingOlder, isTopOrigin, onLoadOlder]\n );\n\n const preserveIntrinsicResize = useCallback(() => {\n const element = scrollContainerRef.current;\n if (!element || isTopOrigin) return;\n const active = intrinsicResizePreserveRef.current;\n if (active?.frame !== null && active?.frame !== undefined) cancelAnimationFrame(active.frame);\n intrinsicResizePreserveRef.current = {\n lastHeight: element.scrollHeight,\n endAt: Date.now() + 260,\n frame: null,\n };\n const preserveFrame = () => {\n const nextElement = scrollContainerRef.current;\n const preserve = intrinsicResizePreserveRef.current;\n if (!nextElement || !preserve) return;\n const heightDelta = nextElement.scrollHeight - preserve.lastHeight;\n if (Math.abs(heightDelta) >= 1) {\n markProgrammaticScroll();\n nextElement.scrollTop -= heightDelta;\n preserve.lastHeight = nextElement.scrollHeight;\n setIsAtLatest(isAtTimelineLatestEdge(nextElement, isTopOrigin));\n }\n if (Date.now() < preserve.endAt) {\n preserve.frame = requestAnimationFrame(preserveFrame);\n } else {\n intrinsicResizePreserveRef.current = null;\n }\n };\n intrinsicResizePreserveRef.current.frame = requestAnimationFrame(preserveFrame);\n }, [isTopOrigin, markProgrammaticScroll]);\n\n useEffect(() => {\n const key = activeStreamKey || null;\n if (!key || activeStreamKeyRef.current === key) {\n activeStreamKeyRef.current = key;\n return;\n }\n autoFollowLatestRef.current = true;\n const frame = requestAnimationFrame(scrollToLatest);\n activeStreamKeyRef.current = key;\n return () => cancelAnimationFrame(frame);\n }, [activeStreamKey, scrollToLatest]);\n\n useLayoutEffect(() => {\n if (!activeStreamKey || !shouldAutoFollow || !autoFollowLatestRef.current) return;\n if (isLoadingOlder || olderPageRequestInFlightRef.current) return;\n const frame = requestAnimationFrame(() => {\n if (autoFollowLatestRef.current && !isLoadingOlder && !olderPageRequestInFlightRef.current) scrollToLatest();\n });\n return () => cancelAnimationFrame(frame);\n }, [activeStreamKey, isLoadingOlder, itemCount, scrollToLatest, shouldAutoFollow]);\n\n return {\n scrollContainerRef,\n isAtLatest,\n isTopOrigin,\n shouldShowLatestButton: !isAtLatest,\n handleScroll,\n scrollToLatest,\n preserveIntrinsicResize,\n };\n}\n\nexport type LatestThreadViewportRenderContext = {\n preserveIntrinsicResize: () => void;\n isTopOrigin: boolean;\n};\n\nexport type LatestThreadViewportProps<T> = {\n items: T[];\n hasOlder: boolean;\n isLoadingOlder: boolean;\n onLoadOlder: () => Promise<void> | void;\n activeStreamKey?: string | null;\n className?: string;\n latestSpacer?: ReactNode;\n trailingSpacer?: ReactNode;\n renderItem: (item: T, context: LatestThreadViewportRenderContext) => ReactNode;\n};\n\nexport function LatestThreadViewport<T>({\n items,\n hasOlder,\n isLoadingOlder,\n onLoadOlder,\n activeStreamKey,\n className,\n latestSpacer,\n trailingSpacer,\n renderItem,\n}: LatestThreadViewportProps<T>) {\n const viewport = useLatestThreadViewport({\n itemCount: items.length,\n hasOlder,\n isLoadingOlder,\n onLoadOlder,\n activeStreamKey,\n });\n const timelineItems = useMemo(() => viewport.isTopOrigin ? items : [...items].reverse(), [items, viewport.isTopOrigin]);\n return (\n <div\n ref={viewport.scrollContainerRef}\n className={className}\n onScroll={viewport.handleScroll}\n role=\"log\"\n style={{ overflowAnchor: \"none\" }}\n >\n {!viewport.isTopOrigin && (latestSpacer ?? null)}\n {timelineItems.map((item) => renderItem(item, viewport))}\n {viewport.isTopOrigin && (trailingSpacer ?? latestSpacer ?? null)}\n </div>\n );\n}\n"],"mappings":"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","names":["next","import_react"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { RefObject, ReactNode, UIEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
type ChatRunStatus = "queued" | "running" | "completed" | "cancelled" | "failed" | string;
|
|
5
|
+
type ChatContextWindow = {
|
|
6
|
+
stage?: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
usedTokens?: number;
|
|
9
|
+
maxTokens?: number;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
type ChatCitation = {
|
|
13
|
+
title: string;
|
|
14
|
+
url: string;
|
|
15
|
+
description: string;
|
|
16
|
+
sourceRef?: string;
|
|
17
|
+
ref?: string;
|
|
18
|
+
firstRef?: string;
|
|
19
|
+
totalSegments?: number;
|
|
20
|
+
rangeRef?: string;
|
|
21
|
+
};
|
|
22
|
+
type ChatAttachment = {
|
|
23
|
+
url?: string;
|
|
24
|
+
filename?: string;
|
|
25
|
+
mediaType?: string;
|
|
26
|
+
contentType?: string;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
type ChatReasoningStep = {
|
|
30
|
+
label: string;
|
|
31
|
+
status: "active" | "complete" | "pending";
|
|
32
|
+
icon?: unknown;
|
|
33
|
+
description?: string;
|
|
34
|
+
citations?: ChatCitation[];
|
|
35
|
+
query?: string;
|
|
36
|
+
sources?: Array<Record<string, unknown>>;
|
|
37
|
+
};
|
|
38
|
+
type ChatToolStatus = "running" | "done" | "error";
|
|
39
|
+
type ChatToolActionKey = "search" | "navigate" | "resolve" | "read" | "context" | "links" | "work";
|
|
40
|
+
type ChatTextBlock = {
|
|
41
|
+
id: string;
|
|
42
|
+
kind: "text";
|
|
43
|
+
content: string;
|
|
44
|
+
};
|
|
45
|
+
type ChatToolBlock = {
|
|
46
|
+
id: string;
|
|
47
|
+
kind: "tool";
|
|
48
|
+
title: string;
|
|
49
|
+
actionLabel: string;
|
|
50
|
+
actionKey: ChatToolActionKey;
|
|
51
|
+
status: ChatToolStatus;
|
|
52
|
+
detail?: string;
|
|
53
|
+
};
|
|
54
|
+
type ChatToolGroupBlock = {
|
|
55
|
+
id: string;
|
|
56
|
+
kind: "tool_group";
|
|
57
|
+
title: string;
|
|
58
|
+
status: ChatToolStatus;
|
|
59
|
+
tools: ChatToolBlock[];
|
|
60
|
+
};
|
|
61
|
+
type ChatMessageBlock = ChatTextBlock | ChatToolBlock | ChatToolGroupBlock;
|
|
62
|
+
type ChatMessage = {
|
|
63
|
+
id: string;
|
|
64
|
+
role: "user" | "assistant";
|
|
65
|
+
runId?: string | null;
|
|
66
|
+
content: string;
|
|
67
|
+
createdAt: Date;
|
|
68
|
+
isFinal?: boolean;
|
|
69
|
+
blocks?: ChatMessageBlock[];
|
|
70
|
+
attachments?: ChatAttachment[];
|
|
71
|
+
citations?: ChatCitation[];
|
|
72
|
+
reasoningSteps?: ChatReasoningStep[];
|
|
73
|
+
thinkingDurationMs?: number;
|
|
74
|
+
liked?: boolean;
|
|
75
|
+
disliked?: boolean;
|
|
76
|
+
messageIndex?: number;
|
|
77
|
+
isVoice?: boolean;
|
|
78
|
+
};
|
|
79
|
+
type ChatRuntimeEvent = {
|
|
80
|
+
version?: string;
|
|
81
|
+
seq?: number;
|
|
82
|
+
ts?: string;
|
|
83
|
+
event: string;
|
|
84
|
+
run_id?: string;
|
|
85
|
+
stage?: string;
|
|
86
|
+
payload?: Record<string, unknown>;
|
|
87
|
+
diagnostics?: Array<Record<string, unknown>>;
|
|
88
|
+
};
|
|
89
|
+
type ChatActiveRun = {
|
|
90
|
+
run_id?: string | null;
|
|
91
|
+
status?: string | null;
|
|
92
|
+
started_at?: string | null;
|
|
93
|
+
created_at?: string | null;
|
|
94
|
+
};
|
|
95
|
+
type ChatThreadSummary = {
|
|
96
|
+
id: string;
|
|
97
|
+
title?: string | null;
|
|
98
|
+
status?: string | null;
|
|
99
|
+
surface?: string | null;
|
|
100
|
+
agent_id?: string | null;
|
|
101
|
+
last_run_id?: string | null;
|
|
102
|
+
last_run_status?: string | null;
|
|
103
|
+
active_run?: ChatActiveRun | null;
|
|
104
|
+
activeRun?: ChatActiveRun | null;
|
|
105
|
+
updated_at?: string | null;
|
|
106
|
+
last_activity_at?: string | null;
|
|
107
|
+
created_at?: string | null;
|
|
108
|
+
messages?: ChatMessage[];
|
|
109
|
+
isHydrated?: boolean;
|
|
110
|
+
hasOlderTurns?: boolean;
|
|
111
|
+
nextBeforeTurnIndex?: number | null;
|
|
112
|
+
lastRunId?: string | null;
|
|
113
|
+
lastRunStatus?: string | null;
|
|
114
|
+
lastEventSeq?: number | null;
|
|
115
|
+
isRunning?: boolean;
|
|
116
|
+
[key: string]: unknown;
|
|
117
|
+
};
|
|
118
|
+
type ChatThreadTurn = {
|
|
119
|
+
id?: string;
|
|
120
|
+
run_id?: string;
|
|
121
|
+
turn_index?: number;
|
|
122
|
+
status?: string | null;
|
|
123
|
+
user_input_text?: string | null;
|
|
124
|
+
assistant_output_text?: string | null;
|
|
125
|
+
final_output?: unknown;
|
|
126
|
+
response_blocks?: Array<Record<string, unknown>>;
|
|
127
|
+
run_events?: ChatRuntimeEvent[];
|
|
128
|
+
context_window?: unknown;
|
|
129
|
+
attachments?: Array<Record<string, unknown>>;
|
|
130
|
+
created_at?: string | null;
|
|
131
|
+
completed_at?: string | null;
|
|
132
|
+
};
|
|
133
|
+
type ChatThreadDetail = ChatThreadSummary & {
|
|
134
|
+
turns?: ChatThreadTurn[];
|
|
135
|
+
context_window?: unknown;
|
|
136
|
+
paging?: {
|
|
137
|
+
has_more?: boolean;
|
|
138
|
+
next_before_turn_index?: number | null;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
type ChatTransport = {
|
|
142
|
+
listThreads: (input?: {
|
|
143
|
+
signal?: AbortSignal;
|
|
144
|
+
}) => Promise<{
|
|
145
|
+
items: ChatThreadSummary[];
|
|
146
|
+
total?: number;
|
|
147
|
+
}>;
|
|
148
|
+
getThread: (input: {
|
|
149
|
+
threadId: string;
|
|
150
|
+
limit?: number;
|
|
151
|
+
beforeTurnIndex?: number | null;
|
|
152
|
+
signal?: AbortSignal;
|
|
153
|
+
}) => Promise<ChatThreadDetail>;
|
|
154
|
+
streamMessage: (input: {
|
|
155
|
+
text: string;
|
|
156
|
+
threadId?: string | null;
|
|
157
|
+
files?: ChatAttachment[];
|
|
158
|
+
signal?: AbortSignal;
|
|
159
|
+
}, onEvent: (event: ChatRuntimeEvent) => void | Promise<void>) => Promise<ChatStreamResult>;
|
|
160
|
+
attachRun: (input: {
|
|
161
|
+
runId: string;
|
|
162
|
+
signal?: AbortSignal;
|
|
163
|
+
}, onEvent: (event: ChatRuntimeEvent) => void | Promise<void>) => Promise<ChatStreamResult>;
|
|
164
|
+
cancelRun: (input: {
|
|
165
|
+
runId: string;
|
|
166
|
+
assistantOutputText?: string;
|
|
167
|
+
}) => Promise<{
|
|
168
|
+
run_id?: string;
|
|
169
|
+
status?: string;
|
|
170
|
+
}>;
|
|
171
|
+
deleteThread?: (input: {
|
|
172
|
+
threadId: string;
|
|
173
|
+
}) => Promise<{
|
|
174
|
+
deleted?: boolean;
|
|
175
|
+
}>;
|
|
176
|
+
uploadAttachment?: (input: {
|
|
177
|
+
file: File;
|
|
178
|
+
signal?: AbortSignal;
|
|
179
|
+
}) => Promise<ChatAttachment>;
|
|
180
|
+
};
|
|
181
|
+
type ChatStreamResult = {
|
|
182
|
+
threadId?: string | null;
|
|
183
|
+
runId?: string | null;
|
|
184
|
+
};
|
|
185
|
+
type StoredChatThread = ChatThreadSummary & {
|
|
186
|
+
messages: ChatMessage[];
|
|
187
|
+
isHydrated?: boolean;
|
|
188
|
+
hasOlderTurns?: boolean;
|
|
189
|
+
nextBeforeTurnIndex?: number | null;
|
|
190
|
+
};
|
|
191
|
+
type ChatStorageAdapter = {
|
|
192
|
+
listThreads: () => StoredChatThread[];
|
|
193
|
+
setThreads: (threads: StoredChatThread[]) => void;
|
|
194
|
+
getThread: (threadId: string) => StoredChatThread | undefined;
|
|
195
|
+
upsertThread: (thread: StoredChatThread) => void;
|
|
196
|
+
deleteThread?: (threadId: string) => void;
|
|
197
|
+
getActiveThreadId?: () => string | null;
|
|
198
|
+
setActiveThreadId?: (threadId: string | null) => void;
|
|
199
|
+
};
|
|
200
|
+
type ChatController = {
|
|
201
|
+
messages: ChatMessage[];
|
|
202
|
+
streamingContent: string;
|
|
203
|
+
streamingMessageId: string | null;
|
|
204
|
+
contextStatus: ChatContextWindow | null;
|
|
205
|
+
currentReasoning: ChatReasoningStep[];
|
|
206
|
+
isLoading: boolean;
|
|
207
|
+
isLoadingHistory: boolean;
|
|
208
|
+
isLoadingOlder: boolean;
|
|
209
|
+
hasOlderTurns: boolean;
|
|
210
|
+
liked: Record<string, boolean>;
|
|
211
|
+
disliked: Record<string, boolean>;
|
|
212
|
+
copiedMessageId: string | null;
|
|
213
|
+
lastThinkingDurationMs: number | null;
|
|
214
|
+
activeRunId: string | null;
|
|
215
|
+
handleSubmit: (message: {
|
|
216
|
+
text: string;
|
|
217
|
+
files?: ChatAttachment[];
|
|
218
|
+
}) => Promise<void>;
|
|
219
|
+
handleStop: () => void;
|
|
220
|
+
handleCopy: (content: string, messageId: string) => void;
|
|
221
|
+
handleLike: (msg: ChatMessage) => Promise<void>;
|
|
222
|
+
handleDislike: (msg: ChatMessage) => Promise<void>;
|
|
223
|
+
handleRetry: (msg: ChatMessage) => Promise<void>;
|
|
224
|
+
handleSourceClick: (citations: ChatMessage["citations"]) => void;
|
|
225
|
+
upsertLiveVoiceMessage: (input: {
|
|
226
|
+
role: "user" | "assistant";
|
|
227
|
+
content: string;
|
|
228
|
+
isFinal?: boolean;
|
|
229
|
+
citations?: ChatCitation[];
|
|
230
|
+
reasoningSteps?: ChatReasoningStep[];
|
|
231
|
+
}) => void;
|
|
232
|
+
loadOlderTurns: () => Promise<void>;
|
|
233
|
+
refresh: () => Promise<void>;
|
|
234
|
+
textareaRef: RefObject<HTMLTextAreaElement | null>;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
type UseAgents24ChatControllerOptions = {
|
|
238
|
+
transport: ChatTransport;
|
|
239
|
+
storage: ChatStorageAdapter;
|
|
240
|
+
activeThreadId?: string | null;
|
|
241
|
+
pageSize?: number;
|
|
242
|
+
storageKey?: unknown;
|
|
243
|
+
createId?: () => string;
|
|
244
|
+
onActiveThreadIdChange?: (threadId: string | null) => void;
|
|
245
|
+
onSourceClick?: (citations: ChatMessage["citations"]) => void;
|
|
246
|
+
onStreamErrorMessage?: (error: unknown) => string;
|
|
247
|
+
};
|
|
248
|
+
declare function useAgents24ChatController({ transport, storage, activeThreadId: controlledActiveThreadId, pageSize, storageKey, createId, onActiveThreadIdChange, onSourceClick, onStreamErrorMessage, }: UseAgents24ChatControllerOptions): ChatController;
|
|
249
|
+
|
|
250
|
+
declare const DEFAULT_THREAD_PAGE_SIZE = 5;
|
|
251
|
+
declare const isRunningThreadStatus: (status?: string | null) => boolean;
|
|
252
|
+
declare const createChatId: () => string;
|
|
253
|
+
declare const titleFromMessage: (text: string, files?: Array<{
|
|
254
|
+
filename?: string;
|
|
255
|
+
}>) => string;
|
|
256
|
+
declare const threadActivityDate: (thread: ChatThreadSummary) => string;
|
|
257
|
+
declare const assistantTextFromBlocks: (blocks?: Array<Record<string, unknown>>) => string;
|
|
258
|
+
declare const textFromFinalOutput: (value: unknown) => string;
|
|
259
|
+
declare const renderBlocksFromResponseBlocks: (blocks?: Array<Record<string, unknown>>, fallbackText?: string) => ChatMessageBlock[];
|
|
260
|
+
declare const mergeReasoningSteps: (steps?: ChatReasoningStep[], options?: {
|
|
261
|
+
finalize?: boolean;
|
|
262
|
+
}) => ChatReasoningStep[];
|
|
263
|
+
declare const reasoningStepsFromBlocks: (blocks?: Array<Record<string, unknown>>) => ChatReasoningStep[];
|
|
264
|
+
declare const threadDetailToMessages: (thread: ChatThreadDetail) => ChatMessage[];
|
|
265
|
+
declare const threadPaging: (thread: ChatThreadDetail) => {
|
|
266
|
+
hasOlderTurns: boolean;
|
|
267
|
+
nextBeforeTurnIndex: number | null;
|
|
268
|
+
};
|
|
269
|
+
declare const latestContextWindowFromThread: (thread: ChatThreadDetail) => ChatContextWindow | null;
|
|
270
|
+
declare const activeRunIdFromThread: (thread?: Partial<ChatThreadSummary> | null) => string | null;
|
|
271
|
+
declare const hasUnfinishedAssistantMessage: (messages?: ChatMessage[]) => boolean;
|
|
272
|
+
declare const hasStaleUnfinishedAssistantCache: (thread?: (Partial<ChatThreadSummary> & {
|
|
273
|
+
messages?: ChatMessage[];
|
|
274
|
+
}) | null) => boolean;
|
|
275
|
+
declare const activeRunIdFromThreadDetail: (thread?: ChatThreadDetail | null) => string | null;
|
|
276
|
+
|
|
277
|
+
declare const parseSseBlock: (block: string) => ChatRuntimeEvent | null;
|
|
278
|
+
declare const consumeSseResponse: (response: Response, onEvent: (event: ChatRuntimeEvent) => void | Promise<void>) => Promise<ChatStreamResult>;
|
|
279
|
+
|
|
280
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
281
|
+
type FetchChatTransportRoutes = {
|
|
282
|
+
listThreads: () => string;
|
|
283
|
+
getThread: (input: {
|
|
284
|
+
threadId: string;
|
|
285
|
+
limit?: number;
|
|
286
|
+
beforeTurnIndex?: number | null;
|
|
287
|
+
}) => string;
|
|
288
|
+
streamMessage: () => string;
|
|
289
|
+
attachRun: (input: {
|
|
290
|
+
runId: string;
|
|
291
|
+
}) => string;
|
|
292
|
+
cancelRun: (input: {
|
|
293
|
+
runId: string;
|
|
294
|
+
}) => string;
|
|
295
|
+
deleteThread?: (input: {
|
|
296
|
+
threadId: string;
|
|
297
|
+
}) => string;
|
|
298
|
+
};
|
|
299
|
+
type FetchChatTransportOptions = {
|
|
300
|
+
routes: FetchChatTransportRoutes;
|
|
301
|
+
fetchImpl?: typeof fetch;
|
|
302
|
+
headers?: () => MaybePromise<HeadersInit>;
|
|
303
|
+
streamBody?: (input: {
|
|
304
|
+
text: string;
|
|
305
|
+
threadId?: string | null;
|
|
306
|
+
files?: ChatAttachment[];
|
|
307
|
+
}) => unknown;
|
|
308
|
+
};
|
|
309
|
+
declare const createFetchChatTransport: ({ routes, fetchImpl, headers, streamBody, }: FetchChatTransportOptions) => ChatTransport;
|
|
310
|
+
|
|
311
|
+
declare const isScrollable: (element: Pick<HTMLDivElement, "scrollHeight" | "clientHeight">) => boolean;
|
|
312
|
+
declare const isAtTimelineLatestEdge: (element: Pick<HTMLDivElement, "scrollHeight" | "clientHeight" | "scrollTop">, isTopOrigin: boolean) => boolean;
|
|
313
|
+
declare const shouldPrefetchOlder: (element: Pick<HTMLDivElement, "scrollHeight" | "clientHeight" | "scrollTop">) => boolean;
|
|
314
|
+
declare const getLatestScrollTop: (element: Pick<HTMLDivElement, "scrollHeight" | "clientHeight">, isTopOrigin: boolean) => number;
|
|
315
|
+
type UseLatestThreadViewportOptions = {
|
|
316
|
+
itemCount: number;
|
|
317
|
+
hasOlder: boolean;
|
|
318
|
+
isLoadingOlder: boolean;
|
|
319
|
+
onLoadOlder: () => Promise<void> | void;
|
|
320
|
+
activeStreamKey?: string | null;
|
|
321
|
+
shouldAutoFollow?: boolean;
|
|
322
|
+
topOriginMaxItems?: number;
|
|
323
|
+
};
|
|
324
|
+
type LatestThreadViewportState = {
|
|
325
|
+
scrollContainerRef: RefObject<HTMLDivElement | null>;
|
|
326
|
+
isAtLatest: boolean;
|
|
327
|
+
isTopOrigin: boolean;
|
|
328
|
+
shouldShowLatestButton: boolean;
|
|
329
|
+
handleScroll: (event: UIEvent<HTMLDivElement>) => void;
|
|
330
|
+
scrollToLatest: () => void;
|
|
331
|
+
preserveIntrinsicResize: () => void;
|
|
332
|
+
};
|
|
333
|
+
declare function useLatestThreadViewport({ itemCount, hasOlder, isLoadingOlder, onLoadOlder, activeStreamKey, shouldAutoFollow, topOriginMaxItems, }: UseLatestThreadViewportOptions): LatestThreadViewportState;
|
|
334
|
+
type LatestThreadViewportRenderContext = {
|
|
335
|
+
preserveIntrinsicResize: () => void;
|
|
336
|
+
isTopOrigin: boolean;
|
|
337
|
+
};
|
|
338
|
+
type LatestThreadViewportProps<T> = {
|
|
339
|
+
items: T[];
|
|
340
|
+
hasOlder: boolean;
|
|
341
|
+
isLoadingOlder: boolean;
|
|
342
|
+
onLoadOlder: () => Promise<void> | void;
|
|
343
|
+
activeStreamKey?: string | null;
|
|
344
|
+
className?: string;
|
|
345
|
+
latestSpacer?: ReactNode;
|
|
346
|
+
trailingSpacer?: ReactNode;
|
|
347
|
+
renderItem: (item: T, context: LatestThreadViewportRenderContext) => ReactNode;
|
|
348
|
+
};
|
|
349
|
+
declare function LatestThreadViewport<T>({ items, hasOlder, isLoadingOlder, onLoadOlder, activeStreamKey, className, latestSpacer, trailingSpacer, renderItem, }: LatestThreadViewportProps<T>): react.JSX.Element;
|
|
350
|
+
|
|
351
|
+
export { type ChatActiveRun, type ChatAttachment, type ChatCitation, type ChatContextWindow, type ChatController, type ChatMessage, type ChatMessageBlock, type ChatReasoningStep, type ChatRunStatus, type ChatRuntimeEvent, type ChatStorageAdapter, type ChatStreamResult, type ChatTextBlock, type ChatThreadDetail, type ChatThreadSummary, type ChatThreadTurn, type ChatToolActionKey, type ChatToolBlock, type ChatToolGroupBlock, type ChatToolStatus, type ChatTransport, DEFAULT_THREAD_PAGE_SIZE, type FetchChatTransportOptions, type FetchChatTransportRoutes, LatestThreadViewport, type LatestThreadViewportProps, type LatestThreadViewportRenderContext, type LatestThreadViewportState, type StoredChatThread, type UseAgents24ChatControllerOptions, type UseLatestThreadViewportOptions, activeRunIdFromThread, activeRunIdFromThreadDetail, assistantTextFromBlocks, consumeSseResponse, createChatId, createFetchChatTransport, getLatestScrollTop, hasStaleUnfinishedAssistantCache, hasUnfinishedAssistantMessage, isAtTimelineLatestEdge, isRunningThreadStatus, isScrollable, latestContextWindowFromThread, mergeReasoningSteps, parseSseBlock, reasoningStepsFromBlocks, renderBlocksFromResponseBlocks, shouldPrefetchOlder, textFromFinalOutput, threadActivityDate, threadDetailToMessages, threadPaging, titleFromMessage, useAgents24ChatController, useLatestThreadViewport };
|