@adminide-stack/yantra-mobile 12.0.80-alpha.1 → 12.0.80-alpha.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.
@@ -1 +1 @@
1
- {"version":3,"file":"useChatStream.js","sources":["../../src/hooks/useChatStream.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n useCreateAccountChatFileDownloadLinksMutation,\n useCreateAccountChatFileUploadLinksMutation,\n} from 'common/graphql';\nimport {\n clearChannelHistoryRunning,\n markChannelHistoryRunning,\n patchChannelHistoryPreview,\n useChatMutations,\n useChatMessages,\n} from './useChatApi';\nimport { useCdecliChannel } from './useCdecliChannel';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\nimport { isAgentJwtRejected, shouldInlineGatewayMediaForHostedAgent } from './systemTokenJwt';\nimport { config } from '../config';\nimport {\n MAX_QUEUED_MESSAGES,\n clearQueuedGatewayMessages,\n dropQueuedGatewayMessage,\n queueGatewayMessage,\n queuedGatewayMessages,\n restoreQueuedGatewayMessages,\n subscribeQueuedGatewayMessages,\n} from '../services/queuedGatewayMessages';\nimport { isImageAttachment } from '../features/attachments/isImageAttachment';\nimport { buildGatewayMedia, buildGatewayMediaPreferUrls } from '../features/attachments/buildGatewayMedia';\nimport { preserveAttachmentPreviews } from '../features/attachments/preserveAttachmentPreviews';\nimport { releasePreviewBytes } from '../features/attachments/releasePreviewBytes';\nimport { resolveAssistantReply } from '../features/chat/emptyChatResponse';\nimport {\n appendFollowUpAssistant,\n appendOrReplaceAssistant,\n collapseConsecutiveAssistants,\n mergeOptimisticGatewayMessages,\n} from '../state/chatThreadMerge';\n\n/** Agent returned an error while the cdecli-serve channel stayed connected (e.g. bad LLM API key). */\nfunction isCdecliAgentFailureOutput(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n return (\n /⚠\\s*Error:/.test(t) ||\n /LLM stream error/i.test(t) ||\n /Incorrect API key/i.test(t) ||\n /invalid_api_key/i.test(t) ||\n /authentication_error/i.test(t) ||\n isAgentJwtRejected(t)\n );\n}\n\nexport interface MessageAttachment {\n id: string;\n name: string;\n type: 'file' | 'screenshot';\n dataUrl?: string;\n mimeType?: string;\n size?: number;\n url?: string;\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n attachments?: MessageAttachment[];\n metadata?: {\n tokenUsage?: { inputTokens: number; outputTokens: number; totalTokens: number };\n model?: string;\n };\n}\n\n/** The queued row renders this turn now, so the optimistic bubble must not stay behind it. */\nfunction withoutTrailingUserMessage(prev: ChatMessage[], text: string): ChatMessage[] {\n const last = prev[prev.length - 1];\n return last?.role === 'user' && last.content === text ? prev.slice(0, -1) : prev;\n}\n\n/** A message the gateway queued for the agent while a turn was running. */\nexport interface QueuedFollowUp {\n /** The gateway's id for it - what cancels it. */\n id: string;\n text: string;\n attachments?: MessageAttachment[];\n}\n\n/** What became of a send: delivered to the gateway, parked in the outbox, or refused outright. */\nexport type SendOutcome = 'sent' | 'queued' | 'failed';\n\nfunction formatBackendThread(\n backendMessages: Array<{\n role: string;\n content?: string;\n // The generated `ChatMessageUI` types `type` as a plain string; it is narrowed\n // to the UI union in the map below, so take it wide rather than cast at the call.\n attachments?: Array<{ id: string; name: string; type: string; mimeType?: string; size?: number; url?: string }>;\n tokenCount?: number;\n model?: string;\n }>,\n): ChatMessage[] {\n return collapseConsecutiveAssistants(\n backendMessages.map((msg) => ({\n role: msg.role as 'user' | 'assistant',\n content: msg.content ?? '',\n attachments: msg.attachments?.map((a) => ({\n id: a.id,\n name: a.name,\n type: a.type === 'screenshot' ? 'screenshot' : 'file',\n mimeType: a.mimeType,\n size: a.size,\n url: a.url,\n })),\n metadata: msg.tokenCount\n ? {\n tokenUsage: {\n inputTokens: 0,\n outputTokens: msg.tokenCount,\n totalTokens: msg.tokenCount,\n },\n model: msg.model,\n }\n : undefined,\n })),\n );\n}\n\n/** Mobile chat routes exclusively through CDeCLI (messenger-gateway). */\nexport interface UseChatStreamRouting {\n channelConnected: boolean;\n accountId: string;\n /** When `'backend'`, the gateway persists posts — skip client `saveMessages`. */\n persistenceMode?: 'backend' | 'frontend';\n /** Remint the system JWT and reconnect after cdecli-agent 401s the session. */\n recoverAgentAuth?: () => Promise<boolean>;\n}\n\nexport function useChatStream(\n sessionId: string | null,\n routing: UseChatStreamRouting = {\n channelConnected: false,\n accountId: 'default',\n persistenceMode: 'backend',\n },\n) {\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [response, setResponse] = useState('');\n /** Brain assist — never the published agent stream. Shown as a Quick answer strip. */\n const [quickReply, setQuickReply] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const isSendingRef = useRef(false);\n /**\n * Messages sent while a turn was running, which the gateway queued for the\n * agent. Shown above the composer until the agent starts on them (the way\n * Claude Code shows a message typed mid-turn), then moved into the thread.\n * Kept out of `messages` so a backend hydration cannot drop or double them.\n */\n const [queuedFollowUps, setQueuedFollowUps] = useState<QueuedFollowUp[]>([]);\n const queuedFollowUpsRef = useRef<QueuedFollowUp[]>([]);\n const sendMessageRef = useRef<\n (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible?: boolean,\n queuedId?: string,\n ) => Promise<SendOutcome>\n >(async () => 'failed');\n\n /** Ensures GraphQL stream subscriptions use the id from createChannel+send before the next parent render. */\n const [cdecliStreamOverrideId, setCdecliStreamOverrideId] = useState<string | undefined>(undefined);\n const userMsgForSaveRef = useRef<ChatMessage | null>(null);\n const saveSessionIdRef = useRef<string | null>(null);\n const sessionIdRef = useRef<string | null>(sessionId);\n sessionIdRef.current = sessionId || cdecliStreamOverrideId || null;\n /** Blocks duplicate cdecli `onComplete` from appending assistant twice / saving twice per send. */\n const cdecliRoundHandledRef = useRef(false);\n /**\n * The round in flight was opened by the agent, not by a send: a follow-up,\n * e.g. the answer to a request the gateway queued while the agent was busy.\n * It completes as a new bubble instead of replacing the reply before it.\n */\n const followUpRoundRef = useRef(false);\n /** One remint+resend per turn when cdecli-agent 401s the JWT. */\n const authRetryUsedRef = useRef(false);\n const recoveringAuthRef = useRef(false);\n const routingRef = useRef(routing);\n routingRef.current = routing;\n\n const tryRecoverAndResendRef = useRef<(reason: string) => Promise<boolean>>(async () => false);\n\n /** Coalesce token deltas so Fabric is not committing a native tree every chunk. */\n const pendingStreamRef = useRef('');\n const streamFlushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearPendingStream = useCallback(() => {\n if (streamFlushTimerRef.current != null) {\n clearTimeout(streamFlushTimerRef.current);\n streamFlushTimerRef.current = null;\n }\n pendingStreamRef.current = '';\n }, []);\n\n const flushPendingStream = useCallback(() => {\n streamFlushTimerRef.current = null;\n const pending = pendingStreamRef.current;\n if (!pending) return;\n pendingStreamRef.current = '';\n setResponse((r) => {\n const next = r + pending;\n const sid = sessionIdRef.current;\n if (sid) markChannelHistoryRunning(sid, next);\n return next;\n });\n }, []);\n\n useEffect(() => () => clearPendingStream(), [clearPendingStream]);\n\n const { saveMessages, patchChannelTitle } = useChatMutations();\n const titlePatchedChannelsRef = useRef(new Set<string>());\n const { accountUserId } = usePrerequisiteIds();\n const [createAccountChatFileUploadLinksMutation] = useCreateAccountChatFileUploadLinksMutation();\n const [createAccountChatFileDownloadLinksMutation] = useCreateAccountChatFileDownloadLinksMutation();\n const {\n messages: backendMessages,\n loading: backendMessagesLoading,\n messagesLoaded: backendMessagesLoaded,\n } = useChatMessages(sessionId);\n const lastHydratedSessionIdRef = useRef<string | null>(null);\n /** Trash-clear: do not re-hydrate gateway history until the next send. */\n const ignoreHydrationRef = useRef(false);\n\n const streamChannelId = sessionId || cdecliStreamOverrideId;\n\n const finalizeCdecliRound = useCallback(\n (assistantContent?: string) => {\n const previewSid = saveSessionIdRef.current || sessionIdRef.current;\n clearPendingStream();\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n followUpRoundRef.current = false;\n setResponse('');\n setQuickReply('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n if (previewSid) clearChannelHistoryRunning(previewSid);\n if (assistantContent !== undefined) {\n setMessages((prev) =>\n appendOrReplaceAssistant(prev, { role: 'assistant' as const, content: assistantContent }),\n );\n if (previewSid) patchChannelHistoryPreview(previewSid, assistantContent);\n }\n },\n [clearPendingStream],\n );\n\n const cdecliCallbacks = useMemo(\n () => ({\n onChunk: (text: string) => {\n if (!isSendingRef.current) {\n // No send opened this round: the agent is speaking on its own.\n isSendingRef.current = true;\n followUpRoundRef.current = true;\n cdecliRoundHandledRef.current = false;\n saveSessionIdRef.current = sessionIdRef.current;\n setIsLoading(true);\n setIsStreaming(true);\n setError(null);\n const sid = sessionIdRef.current;\n if (sid) markChannelHistoryRunning(sid, text);\n // The agent has started on what was queued: those messages\n // join the thread now, above the answer they are getting.\n const started = queuedFollowUpsRef.current;\n if (started.length > 0) {\n queuedFollowUpsRef.current = [];\n setQueuedFollowUps([]);\n setMessages((prev) => [\n ...prev,\n ...started.map((q) => ({\n role: 'user' as const,\n content: q.text,\n attachments: q.attachments,\n })),\n ]);\n }\n }\n pendingStreamRef.current += text;\n if (streamFlushTimerRef.current == null) {\n streamFlushTimerRef.current = setTimeout(flushPendingStream, 50);\n }\n },\n // The brain's provisional answer is the WHOLE reply-so-far, not a chunk:\n // it is set outright, and set to '' when the real stream supersedes it.\n onQuickReply: (text: string) => {\n setQuickReply(text);\n },\n // The gateway's own words on the running work (a status answer, a\n // long-wait report) arrive as thread posts through hydration; the\n // callback only keeps them from ending the reply in progress.\n onNotice: () => undefined,\n onStreamRestart: () => {\n clearPendingStream();\n pendingStreamRef.current = '';\n setResponse('');\n },\n onComplete: (text: string) => {\n clearPendingStream();\n if (cdecliRoundHandledRef.current) {\n return;\n }\n\n if (isCdecliAgentFailureOutput(text)) {\n void (async () => {\n if (await tryRecoverAndResendRef.current(text)) return;\n if (cdecliRoundHandledRef.current) return;\n cdecliRoundHandledRef.current = true;\n setError(\n isAgentJwtRejected(text)\n ? text\n : 'CDeCLI agent error. Check gateway status and server-side LLM configuration.',\n );\n finalizeCdecliRound(isAgentJwtRejected(text) ? undefined : text);\n })();\n return;\n }\n\n cdecliRoundHandledRef.current = true;\n authRetryUsedRef.current = false;\n\n const reply = resolveAssistantReply(text);\n const sid = saveSessionIdRef.current;\n const um = userMsgForSaveRef.current;\n const followUp = followUpRoundRef.current;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n followUpRoundRef.current = false;\n\n const assistant = { role: 'assistant' as const, content: reply };\n setMessages((prev) =>\n followUp ? appendFollowUpAssistant(prev, assistant) : appendOrReplaceAssistant(prev, assistant),\n );\n const previewSid = sid || sessionIdRef.current;\n if (previewSid) {\n clearChannelHistoryRunning(previewSid);\n patchChannelHistoryPreview(previewSid, reply);\n }\n setResponse('');\n setQuickReply('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n\n const rt = routingRef.current;\n const persistClientSide = rt.persistenceMode !== 'backend';\n\n if (sid && um && persistClientSide) {\n saveMessages({\n sessionId: sid,\n ...(accountUserId ? { createdBy: accountUserId } : {}),\n userMessage: {\n content: um.content,\n attachments: um.attachments?.map((a) => ({\n id: a.id,\n name: a.name,\n type: a.type,\n mimeType: a.mimeType,\n size: a.size,\n url: a.url,\n })),\n },\n assistantMessage: {\n content: reply,\n tokenCount: undefined,\n model: 'cdecli-serve',\n },\n }).catch((e) => {\n console.error('[useChatStream] saveMessages (cdecli):', e);\n });\n }\n },\n onError: (err: string) => {\n if (cdecliRoundHandledRef.current) return;\n void (async () => {\n if (await tryRecoverAndResendRef.current(err)) return;\n if (cdecliRoundHandledRef.current) return;\n cdecliRoundHandledRef.current = true;\n setError(err || 'CDeCLI stream error.');\n finalizeCdecliRound(resolveAssistantReply(''));\n })();\n },\n }),\n [saveMessages, accountUserId, finalizeCdecliRound, flushPendingStream, clearPendingStream],\n );\n\n const {\n sendMessage: sendCdecliMessage,\n sendQueued: sendQueuedCdecli,\n cancelQueued: cancelQueuedCdecli,\n cancel: cancelCdecliTurn,\n } = useCdecliChannel(routing.channelConnected, routing.accountId, streamChannelId, cdecliCallbacks);\n\n const setQueue = useCallback((next: QueuedFollowUp[]) => {\n queuedFollowUpsRef.current = next;\n setQueuedFollowUps(next);\n }, []);\n\n useEffect(() => {\n if (sessionId && cdecliStreamOverrideId && sessionId === cdecliStreamOverrideId) {\n setCdecliStreamOverrideId(undefined);\n }\n }, [sessionId, cdecliStreamOverrideId]);\n\n useEffect(() => {\n const prevSid = lastHydratedSessionIdRef.current;\n if (prevSid && sessionId && prevSid !== sessionId && isSendingRef.current) {\n // Switching threads: drop local send flags so this view can hydrate.\n // The previous channel's agent keeps running server-side; history still\n // shows it as running until that turn completes or we reopen it.\n clearPendingStream();\n setQueue([]);\n isSendingRef.current = false;\n followUpRoundRef.current = false;\n cdecliRoundHandledRef.current = false;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n setIsLoading(false);\n setIsStreaming(false);\n setResponse('');\n setQuickReply('');\n }\n\n if (!sessionId) {\n setMessages([]);\n setResponse('');\n setQuickReply('');\n lastHydratedSessionIdRef.current = null;\n return;\n }\n\n const stampHistoryPreview = (msgs: ChatMessage[]) => {\n const last = msgs[msgs.length - 1];\n const lastAssistant = [...msgs].reverse().find((msg) => msg.role === 'assistant' && msg.content.trim());\n if (lastAssistant && !isSendingRef.current) {\n patchChannelHistoryPreview(sessionId, lastAssistant.content);\n }\n // Finished thread (last post is assistant) — drop the history \"Running\" badge.\n // A live turn ends with a user post until the assistant lands.\n if (!isSendingRef.current && last?.role === 'assistant') {\n clearChannelHistoryRunning(sessionId);\n }\n };\n\n if (ignoreHydrationRef.current) {\n return;\n }\n\n const keepStream = isSendingRef.current;\n const sessionChanged = lastHydratedSessionIdRef.current !== sessionId;\n if (sessionChanged) {\n lastHydratedSessionIdRef.current = sessionId;\n // Do not merge the previous channel's in-memory thread into this one.\n if (!backendMessagesLoaded) {\n if (!keepStream) {\n setMessages([]);\n setResponse('');\n setQuickReply('');\n }\n return;\n }\n const formatted = formatBackendThread(backendMessages ?? []);\n stampHistoryPreview(formatted);\n setMessages((prev) => (keepStream ? mergeOptimisticGatewayMessages(prev, formatted) : formatted));\n if (!keepStream) {\n setResponse('');\n setQuickReply('');\n }\n return;\n }\n\n if (backendMessagesLoaded) {\n const formatted = formatBackendThread(backendMessages ?? []);\n stampHistoryPreview(formatted);\n // Positional merge first so assistant replies the gateway never persisted\n // (cdecli skill turns emit no chatMessageAdded) survive this snapshot instead\n // of being dropped, then preserve in-memory attachment previews on the result.\n setMessages((prev) => preserveAttachmentPreviews(prev, mergeOptimisticGatewayMessages(prev, formatted)));\n if (!keepStream) {\n setResponse('');\n setQuickReply('');\n }\n }\n }, [sessionId, backendMessages, backendMessagesLoaded, clearPendingStream, setQueue]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible = false,\n /** Set when this send is the release of an outbox entry; it owns that entry's fate. */\n queuedId: string | undefined = undefined,\n ): Promise<SendOutcome> => {\n if (!content.trim() && !attachments?.length) return 'failed';\n\n const effectiveSessionId = sessionIdOverride !== undefined ? sessionIdOverride : sessionId;\n const rt = routingRef.current;\n const trimmed = content.trim();\n const sendText =\n trimmed ||\n (attachments?.length\n ? `Attached: ${attachments\n .map((a) => a.name)\n .filter(Boolean)\n .join(', ')}`\n : '');\n\n const userMessage: ChatMessage = {\n role: 'user',\n content: sendText,\n attachments,\n };\n\n /**\n * The gateway is down. The turn is remembered, not erased: it stays in the\n * thread as a queued bubble and the outbox releases it in order the moment\n * the channel reports connected. Losing what the user typed here is the\n * whole reason this lane exists.\n */\n if (!rt.channelConnected) {\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n return 'failed';\n }\n // A release that raced the connection dropping stays where it is.\n if (queuedId) return 'queued';\n const result = queueGatewayMessage({\n channelId: effectiveSessionId,\n accountId: rt.accountId,\n text: sendText,\n attachments,\n });\n if (!result.ok) {\n setError(\n result.reason === 'full'\n ? `${MAX_QUEUED_MESSAGES} messages are already waiting for the gateway. They send as soon as it connects.`\n : 'Nothing to send.',\n );\n return 'failed';\n }\n if (alreadyVisible) setMessages((prev) => withoutTrailingUserMessage(prev, sendText));\n setError(null);\n return 'queued';\n }\n\n /**\n * A turn is already in flight. The gateway queues the message for the\n * agent, which answers it when the running turn ends; the running reply\n * is left alone. It waits above the composer (cancellable) until the\n * agent starts on it. A status question is answered on the spot, and a\n * turn that had already ended takes the message straight away.\n */\n if (isSendingRef.current) {\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n return 'failed';\n }\n const media = attachments?.length ? buildGatewayMedia(attachments, { includeData: true }) : [];\n const outcome = await sendQueuedCdecli(sendText, effectiveSessionId, media);\n if (outcome.status === 'failed') {\n setError(outcome.error || 'Could not send the message. Try again.');\n return 'failed';\n }\n if (queuedId) dropQueuedGatewayMessage(queuedId);\n setError(null);\n if (outcome.status === 'queued') {\n setQueue([\n ...queuedFollowUpsRef.current,\n { id: outcome.id, text: sendText, attachments: releasePreviewBytes(attachments) },\n ]);\n if (alreadyVisible) setMessages((prev) => withoutTrailingUserMessage(prev, sendText));\n } else if (!alreadyVisible) {\n setMessages((prev) => [...prev, userMessage]);\n }\n return 'sent';\n }\n\n isSendingRef.current = true;\n followUpRoundRef.current = false;\n ignoreHydrationRef.current = false;\n if (effectiveSessionId && sendText) {\n titlePatchedChannelsRef.current.add(effectiveSessionId);\n patchChannelTitle(effectiveSessionId, sendText, true);\n markChannelHistoryRunning(effectiveSessionId);\n }\n if (!alreadyVisible) {\n // The transcript keeps this turn for the rest of the session, so it\n // keeps the preview URI and not the base64 behind it. The bytes stay\n // on `userMsgForSaveRef` below, which is nulled when the turn ends -\n // a retry still has them, a backgrounded app no longer carries them.\n const retained: ChatMessage = {\n ...userMessage,\n attachments: releasePreviewBytes(userMessage.attachments),\n };\n setMessages((prev) => [...prev, retained]);\n authRetryUsedRef.current = false;\n }\n setResponse('');\n setQuickReply('');\n setIsLoading(true);\n setIsStreaming(true);\n setError(null);\n userMsgForSaveRef.current = userMessage;\n saveSessionIdRef.current = effectiveSessionId ?? null;\n cdecliRoundHandledRef.current = false;\n\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n if (!alreadyVisible) setMessages((p) => p.slice(0, -1));\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n userMsgForSaveRef.current = null;\n saveSessionIdRef.current = null;\n return 'failed';\n }\n\n if (sessionIdOverride) {\n setCdecliStreamOverrideId(sessionIdOverride);\n await new Promise<void>((resolve) => {\n setTimeout(resolve, 0);\n });\n }\n\n const inlineForHostedAgent = shouldInlineGatewayMediaForHostedAgent(\n config.GRAPHQL_URL,\n config.CDECLI_AGENT_ENDPOINT,\n );\n // Vision turns must carry inline bytes. URL-only media is what made\n // \"what is this\" + a photo look like a text-only question.\n const inlineImages = (attachments ?? []).some(isImageAttachment) || inlineForHostedAgent;\n let media = inlineImages\n ? buildGatewayMedia(attachments, { includeData: true })\n : await buildGatewayMediaPreferUrls(\n attachments,\n async (filenames) => {\n const result = await createAccountChatFileUploadLinksMutation({\n variables: { filenames },\n });\n return result.data?.createAccountChatFileUploadLinks || [];\n },\n async (urls) => {\n const result = await createAccountChatFileDownloadLinksMutation({\n variables: { urls },\n });\n return result.data?.createAccountChatFileDownloadLinks || [];\n },\n );\n if ((attachments?.length ?? 0) > 0 && media.length === 0) {\n media = buildGatewayMedia(attachments, { includeData: true });\n }\n const ok = await sendCdecliMessage(sendText, effectiveSessionId, media);\n if (!ok && !cdecliRoundHandledRef.current && !recoveringAuthRef.current) {\n cdecliRoundHandledRef.current = true;\n // The send never reached the agent. Park it rather than drop it - a\n // release keeps its place at the head of its own queue.\n const parked = queuedId\n ? { ok: true as const }\n : queueGatewayMessage({\n channelId: effectiveSessionId,\n accountId: rt.accountId,\n text: sendText,\n attachments,\n });\n setError(\n parked.ok\n ? 'Gateway unreachable - message queued. It sends as soon as the connection is back.'\n : 'Failed to send message via CDeCLI. Check gateway connection.',\n );\n // Queued: the queued row renders the turn, so the optimistic bubble goes.\n // Not queued: only drop a bubble this call put there.\n setMessages((p) => {\n if (parked.ok) return withoutTrailingUserMessage(p, sendText);\n return alreadyVisible ? p : p.slice(0, -1);\n });\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n userMsgForSaveRef.current = null;\n saveSessionIdRef.current = null;\n clearChannelHistoryRunning(effectiveSessionId);\n return parked.ok ? 'queued' : 'failed';\n }\n if (ok && queuedId) dropQueuedGatewayMessage(queuedId);\n return ok ? 'sent' : 'failed';\n },\n [\n sessionId,\n sendCdecliMessage,\n patchChannelTitle,\n sendQueuedCdecli,\n setQueue,\n createAccountChatFileUploadLinksMutation,\n createAccountChatFileDownloadLinksMutation,\n ],\n );\n\n sendMessageRef.current = sendMessage;\n\n /* ---------------------------------------------------------------------- *\n * Outbox: turns typed while the gateway was down.\n * ---------------------------------------------------------------------- */\n\n const queuedChannelId = sessionId || cdecliStreamOverrideId || null;\n const queuedSnapshot = useCallback(\n () => queuedGatewayMessages(queuedChannelId, routing.accountId),\n [queuedChannelId, routing.accountId],\n );\n const queuedMessages = useSyncExternalStore(subscribeQueuedGatewayMessages, queuedSnapshot, queuedSnapshot);\n\n useEffect(() => {\n void restoreQueuedGatewayMessages();\n }, []);\n\n /** One release at a time; a send that fails leaves its entry at the head for the next reconnect. */\n const flushingRef = useRef(false);\n const flushQueuedMessages = useCallback(async () => {\n if (flushingRef.current) return;\n flushingRef.current = true;\n try {\n // Bounded: the outbox can never hand out more than its own depth.\n for (let i = 0; i <= MAX_QUEUED_MESSAGES; i += 1) {\n const rt = routingRef.current;\n const sid = sessionIdRef.current;\n if (!rt.channelConnected || !sid) return;\n const next = queuedGatewayMessages(sid, rt.accountId)[0];\n if (!next) return;\n const outcome = await sendMessageRef.current(\n next.text,\n next.attachments,\n next.channelId,\n false,\n next.id,\n );\n if (outcome !== 'sent') return;\n }\n } finally {\n flushingRef.current = false;\n }\n }, []);\n\n /**\n * Release on the disconnected→connected edge, and when a channel with a queue\n * is opened on an already-live gateway. Deliberately not keyed on queue depth:\n * a send that fails puts its turn back, and depth would spin that into a loop.\n */\n const wasConnectedRef = useRef(routing.channelConnected);\n useEffect(() => {\n const connected = routing.channelConnected;\n const reconnected = connected && !wasConnectedRef.current;\n wasConnectedRef.current = connected;\n if (!connected || !queuedChannelId) return;\n if (!reconnected && queuedGatewayMessages(queuedChannelId, routing.accountId).length === 0) return;\n void flushQueuedMessages();\n }, [routing.channelConnected, routing.accountId, queuedChannelId, flushQueuedMessages]);\n\n const discardQueuedMessages = useCallback(() => {\n if (!queuedChannelId) return;\n clearQueuedGatewayMessages(queuedChannelId);\n setError(null);\n }, [queuedChannelId]);\n\n tryRecoverAndResendRef.current = async (reason: string) => {\n if (authRetryUsedRef.current || cdecliRoundHandledRef.current) return false;\n if (!isAgentJwtRejected(reason)) return false;\n const recover = routingRef.current.recoverAgentAuth;\n if (!recover) return false;\n authRetryUsedRef.current = true;\n recoveringAuthRef.current = true;\n try {\n setError('Refreshing CDeCLI credentials…');\n const recovered = await recover();\n if (!recovered) return false;\n const um = userMsgForSaveRef.current;\n const sid = saveSessionIdRef.current;\n cdecliRoundHandledRef.current = false;\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n setError(null);\n if (um && sid) {\n queueMicrotask(() => {\n void sendMessageRef.current(um.content, um.attachments, sid, true);\n });\n }\n return true;\n } catch (err) {\n console.error('[useChatStream] recoverAgentAuth failed:', err);\n return false;\n } finally {\n recoveringAuthRef.current = false;\n }\n };\n\n const cancel = useCallback(() => {\n clearPendingStream();\n const sid = saveSessionIdRef.current ?? sessionId;\n void cancelCdecliTurn(sid ?? 'messenger');\n if (!cdecliRoundHandledRef.current) {\n cdecliRoundHandledRef.current = true;\n finalizeCdecliRound(resolveAssistantReply(''));\n }\n }, [cancelCdecliTurn, finalizeCdecliRound, sessionId, clearPendingStream]);\n\n const clearMessages = useCallback(() => {\n clearPendingStream();\n const hadActiveTurn = isSendingRef.current;\n const sid = saveSessionIdRef.current ?? sessionId;\n isSendingRef.current = false;\n cdecliRoundHandledRef.current = true;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n // Only hit /cancel when a turn was live — otherwise cdecli logs\n // \"Cannot cancel: no active session\" (Research greet + trash).\n if (hadActiveTurn) {\n void cancelCdecliTurn(sid ?? 'messenger');\n }\n ignoreHydrationRef.current = true;\n // Emptying the thread empties its outbox too: a queued turn released after\n // the user cleared the chat would answer a conversation they threw away.\n if (sid) clearQueuedGatewayMessages(sid);\n // ...and what the gateway queued for the agent.\n for (const queued of queuedFollowUpsRef.current) void cancelQueuedCdecli(queued.id, sid ?? 'messenger');\n setQueue([]);\n setMessages([]);\n setResponse('');\n setQuickReply('');\n setError(null);\n setIsLoading(false);\n setIsStreaming(false);\n if (sid) clearChannelHistoryRunning(sid);\n }, [cancelCdecliTurn, cancelQueuedCdecli, clearPendingStream, sessionId, setQueue]);\n\n /** Take one queued message back before the agent gets to it. Too late once\n * the agent started it: it then joins the thread with its answer. */\n const cancelQueuedFollowUp = useCallback(\n async (id: string) => {\n const sid = sessionIdRef.current;\n if (!sid) return;\n const result = await cancelQueuedCdecli(id, sid);\n if (result.ok) {\n setQueue(queuedFollowUpsRef.current.filter((q) => q.id !== id));\n } else {\n setError(result.error || 'Could not cancel that message.');\n }\n },\n [cancelQueuedCdecli, setQueue],\n );\n\n /** Stop the running reply so the agent takes the queued messages now. */\n const sendQueuedNow = useCallback(() => {\n if (isSendingRef.current) cancel();\n }, [cancel]);\n\n const messagesLoading = !!sessionId && backendMessagesLoading && !backendMessagesLoaded;\n\n return {\n messages,\n response,\n quickReply,\n error,\n isLoading,\n isStreaming,\n messagesLoading,\n hasMessages:\n messages.length > 0 ||\n !!response ||\n !!quickReply ||\n queuedMessages.length > 0 ||\n queuedFollowUps.length > 0,\n /** Turns waiting on the gateway, oldest first. Rendered as queued bubbles. */\n queuedMessages,\n /** Send the queue now (the notice's retry), independent of the reconnect edge. */\n flushQueuedMessages,\n discardQueuedMessages,\n /** Sent while the agent was busy and queued for it, oldest first. */\n queuedFollowUps,\n cancelQueuedFollowUp,\n sendQueuedNow,\n sendMessage,\n cancel,\n clearMessages,\n };\n}\n"],"names":["media","_a"],"mappings":"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"}
1
+ {"version":3,"file":"useChatStream.js","sources":["../../src/hooks/useChatStream.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n useCreateAccountChatFileDownloadLinksMutation,\n useCreateAccountChatFileUploadLinksMutation,\n} from 'common/graphql';\nimport {\n clearChannelHistoryRunning,\n markChannelHistoryRunning,\n patchChannelHistoryPreview,\n useChatMutations,\n useChatMessages,\n} from './useChatApi';\nimport { useCdecliChannel } from './useCdecliChannel';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\nimport { isAgentJwtRejected, shouldInlineGatewayMediaForHostedAgent } from './systemTokenJwt';\nimport { config } from '../config';\nimport {\n MAX_QUEUED_MESSAGES,\n clearQueuedGatewayMessages,\n dropQueuedGatewayMessage,\n queueGatewayMessage,\n queuedGatewayMessages,\n restoreQueuedGatewayMessages,\n subscribeQueuedGatewayMessages,\n} from '../services/queuedGatewayMessages';\nimport { isImageAttachment } from '../features/attachments/isImageAttachment';\nimport { buildGatewayMedia, buildGatewayMediaPreferUrls } from '../features/attachments/buildGatewayMedia';\nimport { preserveAttachmentPreviews } from '../features/attachments/preserveAttachmentPreviews';\nimport { releasePreviewBytes } from '../features/attachments/releasePreviewBytes';\nimport { resolveAssistantReply } from '../features/chat/emptyChatResponse';\nimport { splitPreResponse } from '../features/chat/preResponse';\nimport {\n appendFollowUpAssistant,\n appendOrReplaceAssistant,\n collapseConsecutiveAssistants,\n mergeOptimisticGatewayMessages,\n} from '../state/chatThreadMerge';\n\n/** Agent returned an error while the cdecli-serve channel stayed connected (e.g. bad LLM API key). */\nfunction isCdecliAgentFailureOutput(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n return (\n /⚠\\s*Error:/.test(t) ||\n /LLM stream error/i.test(t) ||\n /Incorrect API key/i.test(t) ||\n /invalid_api_key/i.test(t) ||\n /authentication_error/i.test(t) ||\n isAgentJwtRejected(t)\n );\n}\n\nexport interface MessageAttachment {\n id: string;\n name: string;\n type: 'file' | 'screenshot';\n dataUrl?: string;\n mimeType?: string;\n size?: number;\n url?: string;\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n attachments?: MessageAttachment[];\n metadata?: {\n tokenUsage?: { inputTokens: number; outputTokens: number; totalTokens: number };\n model?: string;\n };\n}\n\n/** The queued row renders this turn now, so the optimistic bubble must not stay behind it. */\nfunction withoutTrailingUserMessage(prev: ChatMessage[], text: string): ChatMessage[] {\n const last = prev[prev.length - 1];\n return last?.role === 'user' && last.content === text ? prev.slice(0, -1) : prev;\n}\n\n/** A message the gateway queued for the agent while a turn was running. */\nexport interface QueuedFollowUp {\n /** The gateway's id for it - what cancels it. */\n id: string;\n text: string;\n attachments?: MessageAttachment[];\n}\n\n/** What became of a send: delivered to the gateway, parked in the outbox, or refused outright. */\nexport type SendOutcome = 'sent' | 'queued' | 'failed';\n\nfunction formatBackendThread(\n backendMessages: Array<{\n role: string;\n content?: string;\n // The generated `ChatMessageUI` types `type` as a plain string; it is narrowed\n // to the UI union in the map below, so take it wide rather than cast at the call.\n attachments?: Array<{ id: string; name: string; type: string; mimeType?: string; size?: number; url?: string }>;\n tokenCount?: number;\n model?: string;\n }>,\n): ChatMessage[] {\n return collapseConsecutiveAssistants(\n backendMessages.map((msg) => ({\n role: msg.role as 'user' | 'assistant',\n content: msg.content ?? '',\n attachments: msg.attachments?.map((a) => ({\n id: a.id,\n name: a.name,\n type: a.type === 'screenshot' ? 'screenshot' : 'file',\n mimeType: a.mimeType,\n size: a.size,\n url: a.url,\n })),\n metadata: msg.tokenCount\n ? {\n tokenUsage: {\n inputTokens: 0,\n outputTokens: msg.tokenCount,\n totalTokens: msg.tokenCount,\n },\n model: msg.model,\n }\n : undefined,\n })),\n );\n}\n\n/** Mobile chat routes exclusively through CDeCLI (messenger-gateway). */\nexport interface UseChatStreamRouting {\n channelConnected: boolean;\n accountId: string;\n /** When `'backend'`, the gateway persists posts — skip client `saveMessages`. */\n persistenceMode?: 'backend' | 'frontend';\n /** Remint the system JWT and reconnect after cdecli-agent 401s the session. */\n recoverAgentAuth?: () => Promise<boolean>;\n}\n\nexport function useChatStream(\n sessionId: string | null,\n routing: UseChatStreamRouting = {\n channelConnected: false,\n accountId: 'default',\n persistenceMode: 'backend',\n },\n) {\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [response, setResponse] = useState('');\n /** Brain assist — never the published agent stream. Shown as a Quick answer strip. */\n const [quickReply, setQuickReply] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const isSendingRef = useRef(false);\n /**\n * Messages sent while a turn was running, which the gateway queued for the\n * agent. Shown above the composer until the agent starts on them (the way\n * Claude Code shows a message typed mid-turn), then moved into the thread.\n * Kept out of `messages` so a backend hydration cannot drop or double them.\n */\n const [queuedFollowUps, setQueuedFollowUps] = useState<QueuedFollowUp[]>([]);\n const queuedFollowUpsRef = useRef<QueuedFollowUp[]>([]);\n const sendMessageRef = useRef<\n (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible?: boolean,\n queuedId?: string,\n ) => Promise<SendOutcome>\n >(async () => 'failed');\n\n /** Ensures GraphQL stream subscriptions use the id from createChannel+send before the next parent render. */\n const [cdecliStreamOverrideId, setCdecliStreamOverrideId] = useState<string | undefined>(undefined);\n const userMsgForSaveRef = useRef<ChatMessage | null>(null);\n const saveSessionIdRef = useRef<string | null>(null);\n const sessionIdRef = useRef<string | null>(sessionId);\n sessionIdRef.current = sessionId || cdecliStreamOverrideId || null;\n /** Blocks duplicate cdecli `onComplete` from appending assistant twice / saving twice per send. */\n const cdecliRoundHandledRef = useRef(false);\n /**\n * The round in flight was opened by the agent, not by a send: a follow-up,\n * e.g. the answer to a request the gateway queued while the agent was busy.\n * It completes as a new bubble instead of replacing the reply before it.\n */\n const followUpRoundRef = useRef(false);\n /** One remint+resend per turn when cdecli-agent 401s the JWT. */\n const authRetryUsedRef = useRef(false);\n const recoveringAuthRef = useRef(false);\n const routingRef = useRef(routing);\n routingRef.current = routing;\n\n const tryRecoverAndResendRef = useRef<(reason: string) => Promise<boolean>>(async () => false);\n\n /** Coalesce token deltas so Fabric is not committing a native tree every chunk. */\n const pendingStreamRef = useRef('');\n const streamFlushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearPendingStream = useCallback(() => {\n if (streamFlushTimerRef.current != null) {\n clearTimeout(streamFlushTimerRef.current);\n streamFlushTimerRef.current = null;\n }\n pendingStreamRef.current = '';\n }, []);\n\n const flushPendingStream = useCallback(() => {\n streamFlushTimerRef.current = null;\n const pending = pendingStreamRef.current;\n if (!pending) return;\n pendingStreamRef.current = '';\n setResponse((r) => {\n const next = r + pending;\n const sid = sessionIdRef.current;\n if (sid) markChannelHistoryRunning(sid, next);\n return next;\n });\n }, []);\n\n useEffect(() => () => clearPendingStream(), [clearPendingStream]);\n\n const { saveMessages, patchChannelTitle } = useChatMutations();\n const titlePatchedChannelsRef = useRef(new Set<string>());\n const { accountUserId } = usePrerequisiteIds();\n const [createAccountChatFileUploadLinksMutation] = useCreateAccountChatFileUploadLinksMutation();\n const [createAccountChatFileDownloadLinksMutation] = useCreateAccountChatFileDownloadLinksMutation();\n const {\n messages: backendMessages,\n loading: backendMessagesLoading,\n messagesLoaded: backendMessagesLoaded,\n } = useChatMessages(sessionId);\n const lastHydratedSessionIdRef = useRef<string | null>(null);\n /** Trash-clear: do not re-hydrate gateway history until the next send. */\n const ignoreHydrationRef = useRef(false);\n\n const streamChannelId = sessionId || cdecliStreamOverrideId;\n\n const finalizeCdecliRound = useCallback(\n (assistantContent?: string) => {\n const previewSid = saveSessionIdRef.current || sessionIdRef.current;\n clearPendingStream();\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n followUpRoundRef.current = false;\n setResponse('');\n setQuickReply('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n if (previewSid) clearChannelHistoryRunning(previewSid);\n if (assistantContent !== undefined) {\n setMessages((prev) =>\n appendOrReplaceAssistant(prev, { role: 'assistant' as const, content: assistantContent }),\n );\n if (previewSid) patchChannelHistoryPreview(previewSid, assistantContent);\n }\n },\n [clearPendingStream],\n );\n\n const cdecliCallbacks = useMemo(\n () => ({\n onChunk: (text: string) => {\n if (!isSendingRef.current) {\n // No send opened this round: the agent is speaking on its own.\n isSendingRef.current = true;\n followUpRoundRef.current = true;\n cdecliRoundHandledRef.current = false;\n saveSessionIdRef.current = sessionIdRef.current;\n setIsLoading(true);\n setIsStreaming(true);\n setError(null);\n const sid = sessionIdRef.current;\n if (sid) markChannelHistoryRunning(sid, text);\n // The agent has started on what was queued: those messages\n // join the thread now, above the answer they are getting.\n const started = queuedFollowUpsRef.current;\n if (started.length > 0) {\n queuedFollowUpsRef.current = [];\n setQueuedFollowUps([]);\n setMessages((prev) => [\n ...prev,\n ...started.map((q) => ({\n role: 'user' as const,\n content: q.text,\n attachments: q.attachments,\n })),\n ]);\n }\n }\n pendingStreamRef.current += text;\n if (streamFlushTimerRef.current == null) {\n streamFlushTimerRef.current = setTimeout(flushPendingStream, 50);\n }\n },\n // The brain's provisional answer is the WHOLE reply-so-far, not a chunk:\n // it is set outright, and set to '' when the real stream supersedes it.\n onQuickReply: (text: string) => {\n setQuickReply(text);\n },\n // The gateway's own words on the running work (a status answer, a\n // long-wait report) arrive as thread posts through hydration; the\n // callback only keeps them from ending the reply in progress.\n onNotice: () => undefined,\n onStreamRestart: () => {\n clearPendingStream();\n pendingStreamRef.current = '';\n setResponse('');\n },\n onComplete: (text: string) => {\n clearPendingStream();\n if (cdecliRoundHandledRef.current) {\n return;\n }\n\n // Judge the agent's own words: a quick answer in front of them is\n // not the agent failing, and never belongs in the error banner.\n const agentText = splitPreResponse(text).text;\n if (isCdecliAgentFailureOutput(agentText)) {\n void (async () => {\n if (await tryRecoverAndResendRef.current(agentText)) return;\n if (cdecliRoundHandledRef.current) return;\n cdecliRoundHandledRef.current = true;\n setError(\n isAgentJwtRejected(agentText)\n ? agentText\n : 'CDeCLI agent error. Check gateway status and server-side LLM configuration.',\n );\n finalizeCdecliRound(isAgentJwtRejected(agentText) ? undefined : text);\n })();\n return;\n }\n\n cdecliRoundHandledRef.current = true;\n authRetryUsedRef.current = false;\n\n const reply = resolveAssistantReply(text);\n const sid = saveSessionIdRef.current;\n const um = userMsgForSaveRef.current;\n const followUp = followUpRoundRef.current;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n followUpRoundRef.current = false;\n\n const assistant = { role: 'assistant' as const, content: reply };\n setMessages((prev) =>\n followUp ? appendFollowUpAssistant(prev, assistant) : appendOrReplaceAssistant(prev, assistant),\n );\n const previewSid = sid || sessionIdRef.current;\n if (previewSid) {\n clearChannelHistoryRunning(previewSid);\n patchChannelHistoryPreview(previewSid, reply);\n }\n setResponse('');\n setQuickReply('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n\n const rt = routingRef.current;\n const persistClientSide = rt.persistenceMode !== 'backend';\n\n if (sid && um && persistClientSide) {\n saveMessages({\n sessionId: sid,\n ...(accountUserId ? { createdBy: accountUserId } : {}),\n userMessage: {\n content: um.content,\n attachments: um.attachments?.map((a) => ({\n id: a.id,\n name: a.name,\n type: a.type,\n mimeType: a.mimeType,\n size: a.size,\n url: a.url,\n })),\n },\n assistantMessage: {\n content: reply,\n tokenCount: undefined,\n model: 'cdecli-serve',\n },\n }).catch((e) => {\n console.error('[useChatStream] saveMessages (cdecli):', e);\n });\n }\n },\n onError: (err: string) => {\n if (cdecliRoundHandledRef.current) return;\n void (async () => {\n if (await tryRecoverAndResendRef.current(err)) return;\n if (cdecliRoundHandledRef.current) return;\n cdecliRoundHandledRef.current = true;\n setError(err || 'CDeCLI stream error.');\n finalizeCdecliRound(resolveAssistantReply(''));\n })();\n },\n }),\n [saveMessages, accountUserId, finalizeCdecliRound, flushPendingStream, clearPendingStream],\n );\n\n const {\n sendMessage: sendCdecliMessage,\n sendQueued: sendQueuedCdecli,\n cancelQueued: cancelQueuedCdecli,\n cancel: cancelCdecliTurn,\n } = useCdecliChannel(routing.channelConnected, routing.accountId, streamChannelId, cdecliCallbacks);\n\n const setQueue = useCallback((next: QueuedFollowUp[]) => {\n queuedFollowUpsRef.current = next;\n setQueuedFollowUps(next);\n }, []);\n\n useEffect(() => {\n if (sessionId && cdecliStreamOverrideId && sessionId === cdecliStreamOverrideId) {\n setCdecliStreamOverrideId(undefined);\n }\n }, [sessionId, cdecliStreamOverrideId]);\n\n useEffect(() => {\n const prevSid = lastHydratedSessionIdRef.current;\n if (prevSid && sessionId && prevSid !== sessionId && isSendingRef.current) {\n // Switching threads: drop local send flags so this view can hydrate.\n // The previous channel's agent keeps running server-side; history still\n // shows it as running until that turn completes or we reopen it.\n clearPendingStream();\n setQueue([]);\n isSendingRef.current = false;\n followUpRoundRef.current = false;\n cdecliRoundHandledRef.current = false;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n setIsLoading(false);\n setIsStreaming(false);\n setResponse('');\n setQuickReply('');\n }\n\n if (!sessionId) {\n setMessages([]);\n setResponse('');\n setQuickReply('');\n lastHydratedSessionIdRef.current = null;\n return;\n }\n\n const stampHistoryPreview = (msgs: ChatMessage[]) => {\n const last = msgs[msgs.length - 1];\n const lastAssistant = [...msgs].reverse().find((msg) => msg.role === 'assistant' && msg.content.trim());\n if (lastAssistant && !isSendingRef.current) {\n patchChannelHistoryPreview(sessionId, lastAssistant.content);\n }\n // Finished thread (last post is assistant) — drop the history \"Running\" badge.\n // A live turn ends with a user post until the assistant lands.\n if (!isSendingRef.current && last?.role === 'assistant') {\n clearChannelHistoryRunning(sessionId);\n }\n };\n\n if (ignoreHydrationRef.current) {\n return;\n }\n\n const keepStream = isSendingRef.current;\n const sessionChanged = lastHydratedSessionIdRef.current !== sessionId;\n if (sessionChanged) {\n lastHydratedSessionIdRef.current = sessionId;\n // Do not merge the previous channel's in-memory thread into this one.\n if (!backendMessagesLoaded) {\n if (!keepStream) {\n setMessages([]);\n setResponse('');\n setQuickReply('');\n }\n return;\n }\n const formatted = formatBackendThread(backendMessages ?? []);\n stampHistoryPreview(formatted);\n setMessages((prev) => (keepStream ? mergeOptimisticGatewayMessages(prev, formatted) : formatted));\n if (!keepStream) {\n setResponse('');\n setQuickReply('');\n }\n return;\n }\n\n if (backendMessagesLoaded) {\n const formatted = formatBackendThread(backendMessages ?? []);\n stampHistoryPreview(formatted);\n // Positional merge first so assistant replies the gateway never persisted\n // (cdecli skill turns emit no chatMessageAdded) survive this snapshot instead\n // of being dropped, then preserve in-memory attachment previews on the result.\n setMessages((prev) => preserveAttachmentPreviews(prev, mergeOptimisticGatewayMessages(prev, formatted)));\n if (!keepStream) {\n setResponse('');\n setQuickReply('');\n }\n }\n }, [sessionId, backendMessages, backendMessagesLoaded, clearPendingStream, setQueue]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible = false,\n /** Set when this send is the release of an outbox entry; it owns that entry's fate. */\n queuedId: string | undefined = undefined,\n ): Promise<SendOutcome> => {\n if (!content.trim() && !attachments?.length) return 'failed';\n\n const effectiveSessionId = sessionIdOverride !== undefined ? sessionIdOverride : sessionId;\n const rt = routingRef.current;\n const trimmed = content.trim();\n const sendText =\n trimmed ||\n (attachments?.length\n ? `Attached: ${attachments\n .map((a) => a.name)\n .filter(Boolean)\n .join(', ')}`\n : '');\n\n const userMessage: ChatMessage = {\n role: 'user',\n content: sendText,\n attachments,\n };\n\n /**\n * The gateway is down. The turn is remembered, not erased: it stays in the\n * thread as a queued bubble and the outbox releases it in order the moment\n * the channel reports connected. Losing what the user typed here is the\n * whole reason this lane exists.\n */\n if (!rt.channelConnected) {\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n return 'failed';\n }\n // A release that raced the connection dropping stays where it is.\n if (queuedId) return 'queued';\n const result = queueGatewayMessage({\n channelId: effectiveSessionId,\n accountId: rt.accountId,\n text: sendText,\n attachments,\n });\n if (!result.ok) {\n setError(\n result.reason === 'full'\n ? `${MAX_QUEUED_MESSAGES} messages are already waiting for the gateway. They send as soon as it connects.`\n : 'Nothing to send.',\n );\n return 'failed';\n }\n if (alreadyVisible) setMessages((prev) => withoutTrailingUserMessage(prev, sendText));\n setError(null);\n return 'queued';\n }\n\n /**\n * A turn is already in flight. The gateway queues the message for the\n * agent, which answers it when the running turn ends; the running reply\n * is left alone. It waits above the composer (cancellable) until the\n * agent starts on it. A status question is answered on the spot, and a\n * turn that had already ended takes the message straight away.\n */\n if (isSendingRef.current) {\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n return 'failed';\n }\n const media = attachments?.length ? buildGatewayMedia(attachments, { includeData: true }) : [];\n const outcome = await sendQueuedCdecli(sendText, effectiveSessionId, media);\n if (outcome.status === 'failed') {\n setError(outcome.error || 'Could not send the message. Try again.');\n return 'failed';\n }\n if (queuedId) dropQueuedGatewayMessage(queuedId);\n setError(null);\n if (outcome.status === 'queued') {\n setQueue([\n ...queuedFollowUpsRef.current,\n { id: outcome.id, text: sendText, attachments: releasePreviewBytes(attachments) },\n ]);\n if (alreadyVisible) setMessages((prev) => withoutTrailingUserMessage(prev, sendText));\n } else if (!alreadyVisible) {\n setMessages((prev) => [...prev, userMessage]);\n }\n return 'sent';\n }\n\n isSendingRef.current = true;\n followUpRoundRef.current = false;\n ignoreHydrationRef.current = false;\n if (effectiveSessionId && sendText) {\n titlePatchedChannelsRef.current.add(effectiveSessionId);\n patchChannelTitle(effectiveSessionId, sendText, true);\n markChannelHistoryRunning(effectiveSessionId);\n }\n if (!alreadyVisible) {\n // The transcript keeps this turn for the rest of the session, so it\n // keeps the preview URI and not the base64 behind it. The bytes stay\n // on `userMsgForSaveRef` below, which is nulled when the turn ends -\n // a retry still has them, a backgrounded app no longer carries them.\n const retained: ChatMessage = {\n ...userMessage,\n attachments: releasePreviewBytes(userMessage.attachments),\n };\n setMessages((prev) => [...prev, retained]);\n authRetryUsedRef.current = false;\n }\n setResponse('');\n setQuickReply('');\n setIsLoading(true);\n setIsStreaming(true);\n setError(null);\n userMsgForSaveRef.current = userMessage;\n saveSessionIdRef.current = effectiveSessionId ?? null;\n cdecliRoundHandledRef.current = false;\n\n if (!effectiveSessionId) {\n setError('Missing chat session id.');\n if (!alreadyVisible) setMessages((p) => p.slice(0, -1));\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n userMsgForSaveRef.current = null;\n saveSessionIdRef.current = null;\n return 'failed';\n }\n\n if (sessionIdOverride) {\n setCdecliStreamOverrideId(sessionIdOverride);\n await new Promise<void>((resolve) => {\n setTimeout(resolve, 0);\n });\n }\n\n const inlineForHostedAgent = shouldInlineGatewayMediaForHostedAgent(\n config.GRAPHQL_URL,\n config.CDECLI_AGENT_ENDPOINT,\n );\n // Vision turns must carry inline bytes. URL-only media is what made\n // \"what is this\" + a photo look like a text-only question.\n const inlineImages = (attachments ?? []).some(isImageAttachment) || inlineForHostedAgent;\n let media = inlineImages\n ? buildGatewayMedia(attachments, { includeData: true })\n : await buildGatewayMediaPreferUrls(\n attachments,\n async (filenames) => {\n const result = await createAccountChatFileUploadLinksMutation({\n variables: { filenames },\n });\n return result.data?.createAccountChatFileUploadLinks || [];\n },\n async (urls) => {\n const result = await createAccountChatFileDownloadLinksMutation({\n variables: { urls },\n });\n return result.data?.createAccountChatFileDownloadLinks || [];\n },\n );\n if ((attachments?.length ?? 0) > 0 && media.length === 0) {\n media = buildGatewayMedia(attachments, { includeData: true });\n }\n const ok = await sendCdecliMessage(sendText, effectiveSessionId, media);\n if (!ok && !cdecliRoundHandledRef.current && !recoveringAuthRef.current) {\n cdecliRoundHandledRef.current = true;\n // The send never reached the agent. Park it rather than drop it - a\n // release keeps its place at the head of its own queue.\n const parked = queuedId\n ? { ok: true as const }\n : queueGatewayMessage({\n channelId: effectiveSessionId,\n accountId: rt.accountId,\n text: sendText,\n attachments,\n });\n setError(\n parked.ok\n ? 'Gateway unreachable - message queued. It sends as soon as the connection is back.'\n : 'Failed to send message via CDeCLI. Check gateway connection.',\n );\n // Queued: the queued row renders the turn, so the optimistic bubble goes.\n // Not queued: only drop a bubble this call put there.\n setMessages((p) => {\n if (parked.ok) return withoutTrailingUserMessage(p, sendText);\n return alreadyVisible ? p : p.slice(0, -1);\n });\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n userMsgForSaveRef.current = null;\n saveSessionIdRef.current = null;\n clearChannelHistoryRunning(effectiveSessionId);\n return parked.ok ? 'queued' : 'failed';\n }\n if (ok && queuedId) dropQueuedGatewayMessage(queuedId);\n return ok ? 'sent' : 'failed';\n },\n [\n sessionId,\n sendCdecliMessage,\n patchChannelTitle,\n sendQueuedCdecli,\n setQueue,\n createAccountChatFileUploadLinksMutation,\n createAccountChatFileDownloadLinksMutation,\n ],\n );\n\n sendMessageRef.current = sendMessage;\n\n /* ---------------------------------------------------------------------- *\n * Outbox: turns typed while the gateway was down.\n * ---------------------------------------------------------------------- */\n\n const queuedChannelId = sessionId || cdecliStreamOverrideId || null;\n const queuedSnapshot = useCallback(\n () => queuedGatewayMessages(queuedChannelId, routing.accountId),\n [queuedChannelId, routing.accountId],\n );\n const queuedMessages = useSyncExternalStore(subscribeQueuedGatewayMessages, queuedSnapshot, queuedSnapshot);\n\n useEffect(() => {\n void restoreQueuedGatewayMessages();\n }, []);\n\n /** One release at a time; a send that fails leaves its entry at the head for the next reconnect. */\n const flushingRef = useRef(false);\n const flushQueuedMessages = useCallback(async () => {\n if (flushingRef.current) return;\n flushingRef.current = true;\n try {\n // Bounded: the outbox can never hand out more than its own depth.\n for (let i = 0; i <= MAX_QUEUED_MESSAGES; i += 1) {\n const rt = routingRef.current;\n const sid = sessionIdRef.current;\n if (!rt.channelConnected || !sid) return;\n const next = queuedGatewayMessages(sid, rt.accountId)[0];\n if (!next) return;\n const outcome = await sendMessageRef.current(\n next.text,\n next.attachments,\n next.channelId,\n false,\n next.id,\n );\n if (outcome !== 'sent') return;\n }\n } finally {\n flushingRef.current = false;\n }\n }, []);\n\n /**\n * Release on the disconnected→connected edge, and when a channel with a queue\n * is opened on an already-live gateway. Deliberately not keyed on queue depth:\n * a send that fails puts its turn back, and depth would spin that into a loop.\n */\n const wasConnectedRef = useRef(routing.channelConnected);\n useEffect(() => {\n const connected = routing.channelConnected;\n const reconnected = connected && !wasConnectedRef.current;\n wasConnectedRef.current = connected;\n if (!connected || !queuedChannelId) return;\n if (!reconnected && queuedGatewayMessages(queuedChannelId, routing.accountId).length === 0) return;\n void flushQueuedMessages();\n }, [routing.channelConnected, routing.accountId, queuedChannelId, flushQueuedMessages]);\n\n const discardQueuedMessages = useCallback(() => {\n if (!queuedChannelId) return;\n clearQueuedGatewayMessages(queuedChannelId);\n setError(null);\n }, [queuedChannelId]);\n\n tryRecoverAndResendRef.current = async (reason: string) => {\n if (authRetryUsedRef.current || cdecliRoundHandledRef.current) return false;\n if (!isAgentJwtRejected(reason)) return false;\n const recover = routingRef.current.recoverAgentAuth;\n if (!recover) return false;\n authRetryUsedRef.current = true;\n recoveringAuthRef.current = true;\n try {\n setError('Refreshing CDeCLI credentials…');\n const recovered = await recover();\n if (!recovered) return false;\n const um = userMsgForSaveRef.current;\n const sid = saveSessionIdRef.current;\n cdecliRoundHandledRef.current = false;\n isSendingRef.current = false;\n setIsLoading(false);\n setIsStreaming(false);\n setError(null);\n if (um && sid) {\n queueMicrotask(() => {\n void sendMessageRef.current(um.content, um.attachments, sid, true);\n });\n }\n return true;\n } catch (err) {\n console.error('[useChatStream] recoverAgentAuth failed:', err);\n return false;\n } finally {\n recoveringAuthRef.current = false;\n }\n };\n\n const cancel = useCallback(() => {\n clearPendingStream();\n const sid = saveSessionIdRef.current ?? sessionId;\n void cancelCdecliTurn(sid ?? 'messenger');\n if (!cdecliRoundHandledRef.current) {\n cdecliRoundHandledRef.current = true;\n finalizeCdecliRound(resolveAssistantReply(''));\n }\n }, [cancelCdecliTurn, finalizeCdecliRound, sessionId, clearPendingStream]);\n\n const clearMessages = useCallback(() => {\n clearPendingStream();\n const hadActiveTurn = isSendingRef.current;\n const sid = saveSessionIdRef.current ?? sessionId;\n isSendingRef.current = false;\n cdecliRoundHandledRef.current = true;\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n // Only hit /cancel when a turn was live — otherwise cdecli logs\n // \"Cannot cancel: no active session\" (Research greet + trash).\n if (hadActiveTurn) {\n void cancelCdecliTurn(sid ?? 'messenger');\n }\n ignoreHydrationRef.current = true;\n // Emptying the thread empties its outbox too: a queued turn released after\n // the user cleared the chat would answer a conversation they threw away.\n if (sid) clearQueuedGatewayMessages(sid);\n // ...and what the gateway queued for the agent.\n for (const queued of queuedFollowUpsRef.current) void cancelQueuedCdecli(queued.id, sid ?? 'messenger');\n setQueue([]);\n setMessages([]);\n setResponse('');\n setQuickReply('');\n setError(null);\n setIsLoading(false);\n setIsStreaming(false);\n if (sid) clearChannelHistoryRunning(sid);\n }, [cancelCdecliTurn, cancelQueuedCdecli, clearPendingStream, sessionId, setQueue]);\n\n /** Take one queued message back before the agent gets to it. Too late once\n * the agent started it: it then joins the thread with its answer. */\n const cancelQueuedFollowUp = useCallback(\n async (id: string) => {\n const sid = sessionIdRef.current;\n if (!sid) return;\n const result = await cancelQueuedCdecli(id, sid);\n if (result.ok) {\n setQueue(queuedFollowUpsRef.current.filter((q) => q.id !== id));\n } else {\n setError(result.error || 'Could not cancel that message.');\n }\n },\n [cancelQueuedCdecli, setQueue],\n );\n\n /** Stop the running reply so the agent takes the queued messages now. */\n const sendQueuedNow = useCallback(() => {\n if (isSendingRef.current) cancel();\n }, [cancel]);\n\n const messagesLoading = !!sessionId && backendMessagesLoading && !backendMessagesLoaded;\n\n return {\n messages,\n response,\n quickReply,\n error,\n isLoading,\n isStreaming,\n messagesLoading,\n hasMessages:\n messages.length > 0 ||\n !!response ||\n !!quickReply ||\n queuedMessages.length > 0 ||\n queuedFollowUps.length > 0,\n /** Turns waiting on the gateway, oldest first. Rendered as queued bubbles. */\n queuedMessages,\n /** Send the queue now (the notice's retry), independent of the reconnect edge. */\n flushQueuedMessages,\n discardQueuedMessages,\n /** Sent while the agent was busy and queued for it, oldest first. */\n queuedFollowUps,\n cancelQueuedFollowUp,\n sendQueuedNow,\n sendMessage,\n cancel,\n clearMessages,\n };\n}\n"],"names":["media","_a"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useMemo,useLayoutEffect,useCallback,useState,useRef,useEffect}from'react';import {useWindowDimensions,Keyboard,View,StyleSheet,Pressable}from'react-native';import {getDefaultLeftItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MessageActionBar}from'../../features/chat/MessageActionBar.js';import {ChatTranscript}from'../../features/chat/ChatTranscript.js';import {AskUserCard}from'../../features/chat/AskUserCard.js';import {pendingAskUser}from'../../features/chat/askUser.js';import {PendingConnectorConnectCard}from'../../features/chat/ConnectorConnectPrompt.js';import {QueuedFollowUps}from'../../features/chat/QueuedFollowUps.js';import {displayConnectorConnectMessages,displayConnectorConnectText}from'common';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatLiveStream}from'../../contexts/ChatLiveStreamContext.js';import {KeyboardAwareScreen,KeyboardComposerDock}from'../../components/KeyboardComposerDock.js';import {YantraBrandLoader,YANTRA_LOADER_SIZE_COMPACT}from'../../components/YantraBrandLoader.js';import ThinkingIndicator from'../../components/ThinkingIndicator.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import DeepSearchModal from'../Home/components/DeepSearchModal.js';import {normalizeSummaryText,extractDeepSearchSources}from'../Home/deepSearchUtils.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {NativeDictationBar}from'../../features/audio-input/NativeDictationBar.js';import {isNativeDictationAvailable}from'../../features/audio-input/nativeDictation.js';import {useImageAttachments}from'../../features/attachments/useImageAttachments.js';import {ComposerAttachmentBar}from'../../features/attachments/ComposerAttachmentBar.js';import {useComposerAttachMenu}from'../../features/attachments/ComposerAttachMenu.js';import {hasComposerAttachments,takeComposerAttachments}from'../../features/attachments/composerAttachmentHandoff.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';import {shouldRedirectToShop}from'../../features/shopping/chat/homeShoppingIntent.js';import {replaceWithShopNative,shopHandoffParams,pushShopNative}from'../../features/shopping/chat/openShopNative.js';var __defProp = Object.defineProperty;
1
+ import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useMemo,useLayoutEffect,useCallback,useState,useRef,useEffect}from'react';import {useWindowDimensions,Keyboard,View,StyleSheet,Pressable}from'react-native';import {getDefaultLeftItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MessageActionBar}from'../../features/chat/MessageActionBar.js';import {ChatTranscript}from'../../features/chat/ChatTranscript.js';import {AskUserCard}from'../../features/chat/AskUserCard.js';import {pendingAskUser}from'../../features/chat/askUser.js';import {PendingConnectorConnectCard}from'../../features/chat/ConnectorConnectPrompt.js';import {QueuedFollowUps}from'../../features/chat/QueuedFollowUps.js';import {displayConnectorConnectMessages,displayConnectorConnectText}from'common';import {splitPreResponse}from'../../features/chat/preResponse.js';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatLiveStream}from'../../contexts/ChatLiveStreamContext.js';import {KeyboardAwareScreen,KeyboardComposerDock}from'../../components/KeyboardComposerDock.js';import {YantraBrandLoader,YANTRA_LOADER_SIZE_COMPACT}from'../../components/YantraBrandLoader.js';import ThinkingIndicator from'../../components/ThinkingIndicator.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import DeepSearchModal from'../Home/components/DeepSearchModal.js';import {normalizeSummaryText,extractDeepSearchSources}from'../Home/deepSearchUtils.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {NativeDictationBar}from'../../features/audio-input/NativeDictationBar.js';import {isNativeDictationAvailable}from'../../features/audio-input/nativeDictation.js';import {useImageAttachments}from'../../features/attachments/useImageAttachments.js';import {ComposerAttachmentBar}from'../../features/attachments/ComposerAttachmentBar.js';import {useComposerAttachMenu}from'../../features/attachments/ComposerAttachMenu.js';import {hasComposerAttachments,takeComposerAttachments}from'../../features/attachments/composerAttachmentHandoff.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';import {shouldRedirectToShop}from'../../features/shopping/chat/homeShoppingIntent.js';import {replaceWithShopNative,shopHandoffParams,pushShopNative}from'../../features/shopping/chat/openShopNative.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -336,12 +336,12 @@ function ChatScreen() {
336
336
  return initialQuery != null ? initialQuery : null;
337
337
  }, [messages, lastUserIndex, initialQuery]);
338
338
  const latestAssistantContent = useMemo(() => {
339
- var _a2, _b, _c;
339
+ var _a2, _b;
340
340
  if (response && response.trim()) return response;
341
341
  if (lastUserIndex < 0) return "";
342
342
  for (let i = lastUserIndex + 1; i < messages.length; i += 1) {
343
343
  if (((_a2 = messages[i]) == null ? void 0 : _a2.role) === "assistant") {
344
- return (_c = (_b = messages[i]) == null ? void 0 : _b.content) != null ? _c : "";
344
+ return splitPreResponse((_b = messages[i]) == null ? void 0 : _b.content).text;
345
345
  }
346
346
  }
347
347
  return "";
@@ -444,7 +444,7 @@ function ChatScreen() {
444
444
  /* @__PURE__ */ jsx(Text, { style: [styles.statusText, {
445
445
  color: secondaryTextColor
446
446
  }], children: "Connecting gateway\u2026" })
447
- ] }) : /* @__PURE__ */ jsx(View, { style: styles.transcriptPane, children: /* @__PURE__ */ jsx(ChatTranscript, { messages: transcriptDisplayRows, streamingContent: transcriptStreaming, listFooter: showSendingLoader && pinSendingLoaderNearComposer ? /* @__PURE__ */ jsx(View, { style: styles.thinkingInThread, children: /* @__PURE__ */ jsx(ThinkingIndicator, { variant: "awaiting", color: secondaryTextColor, isDark }) }) : null, renderMessageActions, isDark, listContentStyle: {
447
+ ] }) : /* @__PURE__ */ jsx(View, { style: styles.transcriptPane, children: /* @__PURE__ */ jsx(ChatTranscript, { messages: transcriptDisplayRows, streamingContent: transcriptStreaming, quickReply, listFooter: showSendingLoader && pinSendingLoaderNearComposer ? /* @__PURE__ */ jsx(View, { style: styles.thinkingInThread, children: /* @__PURE__ */ jsx(ThinkingIndicator, { variant: "awaiting", color: secondaryTextColor, isDark }) }) : null, renderMessageActions, isDark, listContentStyle: {
448
448
  paddingTop: 12,
449
449
  paddingBottom: 8,
450
450
  margin: 0,