@adminide-stack/yantra-mobile 12.0.51 → 12.0.52-alpha.1
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/lib/components/KeyboardComposerDock.js +4 -3
- package/lib/components/KeyboardComposerDock.js.map +1 -1
- package/lib/features/attachments/buildGatewayMedia.js +22 -15
- package/lib/features/attachments/buildGatewayMedia.js.map +1 -1
- package/lib/features/attachments/uploadChatAttachments.js +6 -4
- package/lib/features/attachments/uploadChatAttachments.js.map +1 -1
- package/lib/features/attachments/useImageAttachments.js +63 -17
- package/lib/features/attachments/useImageAttachments.js.map +1 -1
- package/lib/features/chat/AskUserCard.js +367 -0
- package/lib/features/chat/AskUserCard.js.map +1 -0
- package/lib/features/chat/ChatTranscript.js +203 -98
- package/lib/features/chat/ChatTranscript.js.map +1 -1
- package/lib/features/chat/ToolTimeline.js +118 -0
- package/lib/features/chat/ToolTimeline.js.map +1 -0
- package/lib/features/chat/askUser.js +136 -0
- package/lib/features/chat/askUser.js.map +1 -0
- package/lib/features/chat/streamingMarkdown.js +7 -0
- package/lib/features/chat/streamingMarkdown.js.map +1 -0
- package/lib/features/chat/toolActivity.js +77 -0
- package/lib/features/chat/toolActivity.js.map +1 -0
- package/lib/features/chat/transcriptGroups.js +29 -0
- package/lib/features/chat/transcriptGroups.js.map +1 -0
- package/lib/hooks/mintSurfaceSystemToken.js +28 -14
- package/lib/hooks/mintSurfaceSystemToken.js.map +1 -1
- package/lib/hooks/systemTokenJwt.js +75 -0
- package/lib/hooks/systemTokenJwt.js.map +1 -0
- package/lib/hooks/useCdecliAutoConnect.js +116 -138
- package/lib/hooks/useCdecliAutoConnect.js.map +1 -1
- package/lib/hooks/useChatApi.js +43 -17
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +61 -13
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/hooks/useObtainSystemToken.js +121 -36
- package/lib/hooks/useObtainSystemToken.js.map +1 -1
- package/lib/screens/Chat/index.js +29 -5
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +21 -6
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +46 -16
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatStream.js","sources":["../../src/hooks/useChatStream.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useCreateAccountChatFileDownloadLinksMutation,\n useCreateAccountChatFileUploadLinksMutation,\n} from 'common/graphql';\nimport { useChatMutations, useChatMessages } from './useChatApi';\nimport { isNoActiveSessionError, useCdecliChannel } from './useCdecliChannel';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\nimport { buildGatewayMediaPreferUrls } from '../features/attachments/buildGatewayMedia';\nimport { preserveAttachmentPreviews } from '../features/attachments/preserveAttachmentPreviews';\nimport { mergeOptimisticGatewayMessages } 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 );\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/** 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}\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 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 /** Follow-ups typed before cdecli has an active session. Flushed after the first token. */\n const pendingSteersRef = useRef<string[]>([]);\n /** True once this turn has produced at least one stream chunk (steer is valid). */\n const sessionLiveRef = useRef(false);\n const flushPendingSteersRef = useRef<() => Promise<void>>(async () => {});\n const sendMessageRef = useRef<\n (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible?: boolean,\n ) => Promise<void>\n >(async () => {});\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 /** Blocks duplicate cdecli `onComplete` from appending assistant twice / saving twice per send. */\n const cdecliRoundHandledRef = useRef(false);\n const routingRef = useRef(routing);\n routingRef.current = routing;\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) => r + pending);\n }, []);\n\n useEffect(() => () => clearPendingStream(), [clearPendingStream]);\n\n const { saveMessages } = useChatMutations();\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\n const streamChannelId = sessionId || cdecliStreamOverrideId;\n\n const finalizeCdecliRound = useCallback(\n (assistantContent?: string) => {\n clearPendingStream();\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n sessionLiveRef.current = false;\n setResponse('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n if (assistantContent !== undefined) {\n setMessages((prev) => [...prev, { role: 'assistant' as const, content: assistantContent }]);\n }\n },\n [clearPendingStream],\n );\n\n const cdecliCallbacks = useMemo(\n () => ({\n onChunk: (text: string) => {\n pendingStreamRef.current += text;\n if (!sessionLiveRef.current) {\n sessionLiveRef.current = true;\n void flushPendingSteersRef.current();\n }\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 // It deliberately does not mark the session live - steers wait for the\n // agent, which is the only side that can act on them.\n onQuickReply: (text: string) => {\n setResponse(text);\n },\n onComplete: (text: string) => {\n clearPendingStream();\n if (cdecliRoundHandledRef.current) {\n return;\n }\n\n if (isCdecliAgentFailureOutput(text)) {\n cdecliRoundHandledRef.current = true;\n pendingSteersRef.current = [];\n setError('CDeCLI agent error. Check gateway status and server-side LLM configuration.');\n finalizeCdecliRound(text);\n return;\n }\n\n cdecliRoundHandledRef.current = true;\n\n const sid = saveSessionIdRef.current;\n const um = userMsgForSaveRef.current;\n const leftover = pendingSteersRef.current;\n pendingSteersRef.current = [];\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n sessionLiveRef.current = false;\n\n setMessages((prev) => [...prev, { role: 'assistant' as const, content: text }]);\n setResponse('');\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: text,\n tokenCount: undefined,\n model: 'cdecli-serve',\n },\n }).catch((e) => {\n console.error('[useChatStream] saveMessages (cdecli):', e);\n });\n }\n\n if (leftover.length > 0) {\n const [first, ...rest] = leftover;\n pendingSteersRef.current = rest;\n queueMicrotask(() => {\n void sendMessageRef.current(first, undefined, sid, true);\n });\n }\n },\n onError: (err: string) => {\n if (cdecliRoundHandledRef.current) return;\n cdecliRoundHandledRef.current = true;\n pendingSteersRef.current = [];\n setError(err || 'CDeCLI stream error.');\n finalizeCdecliRound();\n },\n }),\n [saveMessages, accountUserId, finalizeCdecliRound, flushPendingStream, clearPendingStream],\n );\n\n const {\n sendMessage: sendCdecliMessage,\n steer: steerCdecliMessage,\n cancel: cancelCdecliTurn,\n } = useCdecliChannel(routing.channelConnected, routing.accountId, streamChannelId, cdecliCallbacks);\n\n const flushPendingSteers = useCallback(async () => {\n if (!sessionLiveRef.current || !isSendingRef.current) return;\n const sid = saveSessionIdRef.current;\n if (!sid) return;\n\n while (pendingSteersRef.current.length > 0 && sessionLiveRef.current && isSendingRef.current) {\n const next = pendingSteersRef.current[0];\n const result = await steerCdecliMessage(next, sid);\n if (result.ok) {\n pendingSteersRef.current.shift();\n continue;\n }\n if (isNoActiveSessionError(result.error)) {\n return;\n }\n pendingSteersRef.current.shift();\n setError(result.error || 'Could not send follow-up. Try again.');\n return;\n }\n }, [steerCdecliMessage]);\n\n flushPendingSteersRef.current = flushPendingSteers;\n\n useEffect(() => {\n if (sessionId && cdecliStreamOverrideId && sessionId === cdecliStreamOverrideId) {\n setCdecliStreamOverrideId(undefined);\n }\n }, [sessionId, cdecliStreamOverrideId]);\n\n useEffect(() => {\n if (isSendingRef.current) return;\n\n if (!sessionId) {\n setMessages([]);\n setResponse('');\n lastHydratedSessionIdRef.current = null;\n return;\n }\n\n const sessionChanged = lastHydratedSessionIdRef.current !== sessionId;\n if (sessionChanged) {\n lastHydratedSessionIdRef.current = sessionId;\n // Keep cached thread visible; only clear when this channel is a cache miss.\n if (!backendMessagesLoaded) {\n setMessages([]);\n setResponse('');\n }\n }\n\n if (backendMessagesLoaded) {\n const formatted: ChatMessage[] = (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 // 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 setResponse('');\n }\n }, [sessionId, backendMessages, backendMessagesLoaded]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible = false,\n ) => {\n if (!content.trim() && !attachments?.length) return;\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 * A turn is already in flight. Keep the follow-up visible and queue it.\n * cdecli rejects steer until the agent session exists (\"no active session\"),\n * which is after the first token. Flush then. Never error/LogBox for that race.\n */\n if (isSendingRef.current) {\n if (!rt.channelConnected || !effectiveSessionId) {\n setError(\n !rt.channelConnected\n ? 'CDeCLI is not connected yet. Check gateway status in the header.'\n : 'Missing chat session id.',\n );\n return;\n }\n setMessages((prev) => [...prev, userMessage]);\n setError(null);\n pendingSteersRef.current = [...pendingSteersRef.current, sendText];\n void flushPendingSteers();\n return;\n }\n\n isSendingRef.current = true;\n sessionLiveRef.current = false;\n if (!alreadyVisible) {\n setMessages((prev) => [...prev, userMessage]);\n }\n setResponse('');\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 (!rt.channelConnected) {\n setError('CDeCLI is not connected yet. Check gateway status in the header.');\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;\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;\n }\n\n if (sessionIdOverride) {\n setCdecliStreamOverrideId(sessionIdOverride);\n await new Promise<void>((resolve) => {\n setTimeout(resolve, 0);\n });\n }\n\n const ok = await sendCdecliMessage(\n sendText,\n effectiveSessionId,\n await buildGatewayMediaPreferUrls(\n attachments,\n async (filenames) => {\n const result = await createAccountChatFileUploadLinksMutation({ variables: { filenames } });\n return result.data?.createAccountChatFileUploadLinks || [];\n },\n async (urls) => {\n const result = await createAccountChatFileDownloadLinksMutation({ variables: { urls } });\n return result.data?.createAccountChatFileDownloadLinks || [];\n },\n ),\n );\n if (!ok && !cdecliRoundHandledRef.current) {\n cdecliRoundHandledRef.current = true;\n setError('Failed to send message via CDeCLI. Check gateway connection.');\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 }\n },\n [\n sessionId,\n sendCdecliMessage,\n flushPendingSteers,\n createAccountChatFileUploadLinksMutation,\n createAccountChatFileDownloadLinksMutation,\n ],\n );\n\n sendMessageRef.current = sendMessage;\n\n const cancel = useCallback(() => {\n clearPendingStream();\n pendingSteersRef.current = [];\n sessionLiveRef.current = false;\n const sid = saveSessionIdRef.current ?? sessionId;\n void cancelCdecliTurn(sid ?? 'messenger');\n if (!cdecliRoundHandledRef.current) {\n cdecliRoundHandledRef.current = true;\n finalizeCdecliRound();\n }\n }, [cancelCdecliTurn, finalizeCdecliRound, sessionId, clearPendingStream]);\n\n const clearMessages = useCallback(() => {\n clearPendingStream();\n setMessages([]);\n setResponse('');\n setError(null);\n }, [clearPendingStream]);\n\n const messagesLoading = !!sessionId && backendMessagesLoading && !backendMessagesLoaded;\n\n return {\n messages,\n response,\n error,\n isLoading,\n isStreaming,\n messagesLoading,\n hasMessages: messages.length > 0 || !!response,\n sendMessage,\n cancel,\n clearMessages,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useChatStream.js","sources":["../../src/hooks/useChatStream.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useCreateAccountChatFileDownloadLinksMutation,\n useCreateAccountChatFileUploadLinksMutation,\n} from 'common/graphql';\nimport { useChatMutations, useChatMessages } from './useChatApi';\nimport { isNoActiveSessionError, useCdecliChannel } from './useCdecliChannel';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\nimport { isAgentJwtRejected, shouldInlineGatewayMediaForHostedAgent } from './systemTokenJwt';\nimport { config } from '../config';\nimport { buildGatewayMedia, buildGatewayMediaPreferUrls } from '../features/attachments/buildGatewayMedia';\nimport { preserveAttachmentPreviews } from '../features/attachments/preserveAttachmentPreviews';\nimport { mergeOptimisticGatewayMessages } 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/** 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 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 /** Follow-ups typed before cdecli has an active session. Flushed after the first token. */\n const pendingSteersRef = useRef<string[]>([]);\n /** True once this turn has produced at least one stream chunk (steer is valid). */\n const sessionLiveRef = useRef(false);\n const flushPendingSteersRef = useRef<() => Promise<void>>(async () => {});\n const sendMessageRef = useRef<\n (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible?: boolean,\n ) => Promise<void>\n >(async () => {});\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 /** Blocks duplicate cdecli `onComplete` from appending assistant twice / saving twice per send. */\n const cdecliRoundHandledRef = 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) => r + pending);\n }, []);\n\n useEffect(() => () => clearPendingStream(), [clearPendingStream]);\n\n const { saveMessages } = useChatMutations();\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\n const streamChannelId = sessionId || cdecliStreamOverrideId;\n\n const finalizeCdecliRound = useCallback(\n (assistantContent?: string) => {\n clearPendingStream();\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n sessionLiveRef.current = false;\n setResponse('');\n setIsLoading(false);\n setIsStreaming(false);\n isSendingRef.current = false;\n if (assistantContent !== undefined) {\n setMessages((prev) => [...prev, { role: 'assistant' as const, content: assistantContent }]);\n }\n },\n [clearPendingStream],\n );\n\n const cdecliCallbacks = useMemo(\n () => ({\n onChunk: (text: string) => {\n pendingStreamRef.current += text;\n if (!sessionLiveRef.current) {\n sessionLiveRef.current = true;\n void flushPendingSteersRef.current();\n }\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 // It deliberately does not mark the session live - steers wait for the\n // agent, which is the only side that can act on them.\n onQuickReply: (text: string) => {\n setResponse(text);\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 pendingSteersRef.current = [];\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 sid = saveSessionIdRef.current;\n const um = userMsgForSaveRef.current;\n const leftover = pendingSteersRef.current;\n pendingSteersRef.current = [];\n saveSessionIdRef.current = null;\n userMsgForSaveRef.current = null;\n sessionLiveRef.current = false;\n\n setMessages((prev) => [...prev, { role: 'assistant' as const, content: text }]);\n setResponse('');\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: text,\n tokenCount: undefined,\n model: 'cdecli-serve',\n },\n }).catch((e) => {\n console.error('[useChatStream] saveMessages (cdecli):', e);\n });\n }\n\n if (leftover.length > 0) {\n const [first, ...rest] = leftover;\n pendingSteersRef.current = rest;\n queueMicrotask(() => {\n void sendMessageRef.current(first, undefined, sid, true);\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 pendingSteersRef.current = [];\n setError(err || 'CDeCLI stream error.');\n finalizeCdecliRound();\n })();\n },\n }),\n [saveMessages, accountUserId, finalizeCdecliRound, flushPendingStream, clearPendingStream],\n );\n\n const {\n sendMessage: sendCdecliMessage,\n steer: steerCdecliMessage,\n cancel: cancelCdecliTurn,\n } = useCdecliChannel(routing.channelConnected, routing.accountId, streamChannelId, cdecliCallbacks);\n\n const flushPendingSteers = useCallback(async () => {\n if (!sessionLiveRef.current || !isSendingRef.current) return;\n const sid = saveSessionIdRef.current;\n if (!sid) return;\n\n while (pendingSteersRef.current.length > 0 && sessionLiveRef.current && isSendingRef.current) {\n const next = pendingSteersRef.current[0];\n const result = await steerCdecliMessage(next, sid);\n if (result.ok) {\n pendingSteersRef.current.shift();\n continue;\n }\n if (isNoActiveSessionError(result.error)) {\n return;\n }\n pendingSteersRef.current.shift();\n setError(result.error || 'Could not send follow-up. Try again.');\n return;\n }\n }, [steerCdecliMessage]);\n\n flushPendingSteersRef.current = flushPendingSteers;\n\n useEffect(() => {\n if (sessionId && cdecliStreamOverrideId && sessionId === cdecliStreamOverrideId) {\n setCdecliStreamOverrideId(undefined);\n }\n }, [sessionId, cdecliStreamOverrideId]);\n\n useEffect(() => {\n if (isSendingRef.current) return;\n\n if (!sessionId) {\n setMessages([]);\n setResponse('');\n lastHydratedSessionIdRef.current = null;\n return;\n }\n\n const sessionChanged = lastHydratedSessionIdRef.current !== sessionId;\n if (sessionChanged) {\n lastHydratedSessionIdRef.current = sessionId;\n // Keep cached thread visible; only clear when this channel is a cache miss.\n if (!backendMessagesLoaded) {\n setMessages([]);\n setResponse('');\n }\n }\n\n if (backendMessagesLoaded) {\n const formatted: ChatMessage[] = (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 // 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 setResponse('');\n }\n }, [sessionId, backendMessages, backendMessagesLoaded]);\n\n const sendMessage = useCallback(\n async (\n content: string,\n attachments?: MessageAttachment[],\n sessionIdOverride?: string | null,\n alreadyVisible = false,\n ) => {\n if (!content.trim() && !attachments?.length) return;\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 * A turn is already in flight. Keep the follow-up visible and queue it.\n * cdecli rejects steer until the agent session exists (\"no active session\"),\n * which is after the first token. Flush then. Never error/LogBox for that race.\n */\n if (isSendingRef.current) {\n if (!rt.channelConnected || !effectiveSessionId) {\n setError(\n !rt.channelConnected\n ? 'CDeCLI is not connected yet. Check gateway status in the header.'\n : 'Missing chat session id.',\n );\n return;\n }\n setMessages((prev) => [...prev, userMessage]);\n setError(null);\n pendingSteersRef.current = [...pendingSteersRef.current, sendText];\n void flushPendingSteers();\n return;\n }\n\n isSendingRef.current = true;\n sessionLiveRef.current = false;\n if (!alreadyVisible) {\n setMessages((prev) => [...prev, userMessage]);\n authRetryUsedRef.current = false;\n }\n setResponse('');\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 (!rt.channelConnected) {\n setError('CDeCLI is not connected yet. Check gateway status in the header.');\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;\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;\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 const media = inlineForHostedAgent\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 const ok = await sendCdecliMessage(sendText, effectiveSessionId, media);\n if (!ok && !cdecliRoundHandledRef.current && !recoveringAuthRef.current) {\n cdecliRoundHandledRef.current = true;\n setError('Failed to send message via CDeCLI. Check gateway connection.');\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 }\n },\n [\n sessionId,\n sendCdecliMessage,\n flushPendingSteers,\n createAccountChatFileUploadLinksMutation,\n createAccountChatFileDownloadLinksMutation,\n ],\n );\n\n sendMessageRef.current = sendMessage;\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 pendingSteersRef.current = [];\n sessionLiveRef.current = false;\n const sid = saveSessionIdRef.current ?? sessionId;\n void cancelCdecliTurn(sid ?? 'messenger');\n if (!cdecliRoundHandledRef.current) {\n cdecliRoundHandledRef.current = true;\n finalizeCdecliRound();\n }\n }, [cancelCdecliTurn, finalizeCdecliRound, sessionId, clearPendingStream]);\n\n const clearMessages = useCallback(() => {\n clearPendingStream();\n setMessages([]);\n setResponse('');\n setError(null);\n }, [clearPendingStream]);\n\n const messagesLoading = !!sessionId && backendMessagesLoading && !backendMessagesLoaded;\n\n return {\n messages,\n response,\n error,\n isLoading,\n isStreaming,\n messagesLoading,\n hasMessages: messages.length > 0 || !!response,\n sendMessage,\n cancel,\n clearMessages,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import {useCallback}from'react';import {useCreateSecretApiTokenMutation,useRevealSecretApiTokenMutation,useGetUserSystemTokenQuery}from'common/graphql';import {SecretApiTokenAlgorithm}from'common';import {usePrerequisiteIds}from'./usePrerequisiteIds.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
1
|
+
import {useCallback}from'react';import {useCreateSecretApiTokenMutation,useRevealSecretApiTokenMutation,useRevokeSecretApiTokenMutation,useGetUserSystemTokenQuery}from'common/graphql';import {SecretApiTokenAlgorithm}from'common';import {usePrerequisiteIds}from'./usePrerequisiteIds.js';import {isSystemTokenRowStale,isMissingRs256KeyError,isAlreadyHasSystemTokenError,isMissingVaultSecretError,isJwtExpired}from'./systemTokenJwt.js';var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
6
17
|
function useObtainSystemToken(enabled = true) {
|
|
7
18
|
const {
|
|
8
19
|
orgName,
|
|
@@ -11,6 +22,7 @@ function useObtainSystemToken(enabled = true) {
|
|
|
11
22
|
} = usePrerequisiteIds();
|
|
12
23
|
const [createTokenMutation] = useCreateSecretApiTokenMutation();
|
|
13
24
|
const [revealTokenMutation] = useRevealSecretApiTokenMutation();
|
|
25
|
+
const [revokeTokenMutation] = useRevokeSecretApiTokenMutation();
|
|
14
26
|
const {
|
|
15
27
|
data: systemTokenData,
|
|
16
28
|
loading,
|
|
@@ -19,13 +31,43 @@ function useObtainSystemToken(enabled = true) {
|
|
|
19
31
|
skip: !enabled,
|
|
20
32
|
fetchPolicy: "network-only"
|
|
21
33
|
});
|
|
22
|
-
const
|
|
23
|
-
|
|
34
|
+
const createSystemToken = useCallback(async (algorithm) => {
|
|
35
|
+
return createTokenMutation({
|
|
36
|
+
variables: {
|
|
37
|
+
input: __spreadValues({
|
|
38
|
+
name: "System Token",
|
|
39
|
+
expiryInSeconds: 31536e3,
|
|
40
|
+
isSystemToken: true,
|
|
41
|
+
environmentTagId: tagId,
|
|
42
|
+
orgName: orgName || "default",
|
|
43
|
+
projectId: projectId || "default"
|
|
44
|
+
}, algorithm ? {
|
|
45
|
+
algorithm
|
|
46
|
+
} : {})
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}, [createTokenMutation, orgName, projectId, tagId]);
|
|
50
|
+
const obtainSystemToken = useCallback(async (opts = {}) => {
|
|
51
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
|
|
24
52
|
try {
|
|
25
53
|
let tokenId = (_b = (_a = systemTokenData == null ? void 0 : systemTokenData.getUserSystemToken) == null ? void 0 : _a.id) != null ? _b : null;
|
|
54
|
+
let expiresAt = (_d = (_c = systemTokenData == null ? void 0 : systemTokenData.getUserSystemToken) == null ? void 0 : _c.expiresAt) != null ? _d : null;
|
|
26
55
|
if (!tokenId) {
|
|
27
56
|
const refetchResult = await refetchSystemToken().catch(() => null);
|
|
28
|
-
tokenId = (
|
|
57
|
+
tokenId = (_g = (_f = (_e = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _e.getUserSystemToken) == null ? void 0 : _f.id) != null ? _g : null;
|
|
58
|
+
expiresAt = (_j = (_i = (_h = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _h.getUserSystemToken) == null ? void 0 : _i.expiresAt) != null ? _j : expiresAt;
|
|
59
|
+
}
|
|
60
|
+
if (tokenId && (opts.discardExistingRow || isSystemTokenRowStale(expiresAt))) {
|
|
61
|
+
try {
|
|
62
|
+
await revokeTokenMutation({
|
|
63
|
+
variables: {
|
|
64
|
+
id: tokenId
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
} catch (e) {
|
|
68
|
+
}
|
|
69
|
+
tokenId = null;
|
|
70
|
+
expiresAt = null;
|
|
29
71
|
}
|
|
30
72
|
if (!tokenId) {
|
|
31
73
|
if (!orgName || !projectId || !tagId) {
|
|
@@ -38,47 +80,90 @@ function useObtainSystemToken(enabled = true) {
|
|
|
38
80
|
try {
|
|
39
81
|
const {
|
|
40
82
|
data: createData
|
|
41
|
-
} = await
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
name: "System Token",
|
|
45
|
-
expiryInSeconds: 31536e3,
|
|
46
|
-
isSystemToken: true,
|
|
47
|
-
environmentTagId: tagId,
|
|
48
|
-
orgName,
|
|
49
|
-
projectId,
|
|
50
|
-
algorithm: SYSTEM_TOKEN_ALGORITHM
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
tokenId = (_g = (_f = createData == null ? void 0 : createData.createSecretApiToken) == null ? void 0 : _f.id) != null ? _g : null;
|
|
83
|
+
} = await createSystemToken();
|
|
84
|
+
tokenId = (_l = (_k = createData == null ? void 0 : createData.createSecretApiToken) == null ? void 0 : _k.id) != null ? _l : null;
|
|
85
|
+
expiresAt = (_n = (_m = createData == null ? void 0 : createData.createSecretApiToken) == null ? void 0 : _m.expiresAt) != null ? _n : expiresAt;
|
|
55
86
|
if (!tokenId) {
|
|
56
87
|
const afterCreate = await refetchSystemToken().catch(() => null);
|
|
57
|
-
tokenId = (
|
|
88
|
+
tokenId = (_q = (_p = (_o = afterCreate == null ? void 0 : afterCreate.data) == null ? void 0 : _o.getUserSystemToken) == null ? void 0 : _p.id) != null ? _q : null;
|
|
89
|
+
expiresAt = (_t = (_s = (_r = afterCreate == null ? void 0 : afterCreate.data) == null ? void 0 : _r.getUserSystemToken) == null ? void 0 : _s.expiresAt) != null ? _t : expiresAt;
|
|
58
90
|
}
|
|
59
91
|
} catch (createErr) {
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
92
|
+
if (isMissingRs256KeyError(createErr)) {
|
|
93
|
+
const {
|
|
94
|
+
data: hsData
|
|
95
|
+
} = await createSystemToken(SecretApiTokenAlgorithm.Hs256);
|
|
96
|
+
tokenId = (_v = (_u = hsData == null ? void 0 : hsData.createSecretApiToken) == null ? void 0 : _u.id) != null ? _v : null;
|
|
97
|
+
expiresAt = (_x = (_w = hsData == null ? void 0 : hsData.createSecretApiToken) == null ? void 0 : _w.expiresAt) != null ? _x : expiresAt;
|
|
98
|
+
} else if (isAlreadyHasSystemTokenError(createErr)) {
|
|
99
|
+
const refetchResult = await refetchSystemToken().catch(() => null);
|
|
100
|
+
tokenId = (_A = (_z = (_y = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _y.getUserSystemToken) == null ? void 0 : _z.id) != null ? _A : null;
|
|
101
|
+
expiresAt = (_D = (_C = (_B = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _B.getUserSystemToken) == null ? void 0 : _C.expiresAt) != null ? _D : expiresAt;
|
|
102
|
+
if (!tokenId) return null;
|
|
103
|
+
} else {
|
|
104
|
+
throw createErr;
|
|
105
|
+
}
|
|
64
106
|
}
|
|
65
107
|
}
|
|
66
108
|
if (!tokenId) return null;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
109
|
+
let token = null;
|
|
110
|
+
try {
|
|
111
|
+
const {
|
|
112
|
+
data: revealData
|
|
113
|
+
} = await revealTokenMutation({
|
|
114
|
+
variables: {
|
|
115
|
+
id: tokenId
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
token = (revealData == null ? void 0 : revealData.revealSecretApiToken) || null;
|
|
119
|
+
} catch (revealErr) {
|
|
120
|
+
const msg = revealErr instanceof Error ? revealErr.message : String(revealErr);
|
|
121
|
+
if (!isMissingVaultSecretError(msg) || !orgName || !projectId || !tagId) {
|
|
122
|
+
throw revealErr;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
await revokeTokenMutation({
|
|
126
|
+
variables: {
|
|
127
|
+
id: tokenId
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
} catch (e) {
|
|
72
131
|
}
|
|
73
|
-
|
|
74
|
-
|
|
132
|
+
let createData;
|
|
133
|
+
try {
|
|
134
|
+
createData = (await createSystemToken()).data;
|
|
135
|
+
} catch (retryErr) {
|
|
136
|
+
if (!isMissingRs256KeyError(retryErr)) throw retryErr;
|
|
137
|
+
createData = (await createSystemToken(SecretApiTokenAlgorithm.Hs256)).data;
|
|
138
|
+
}
|
|
139
|
+
const newTokenId = (_F = (_E = createData == null ? void 0 : createData.createSecretApiToken) == null ? void 0 : _E.id) != null ? _F : null;
|
|
140
|
+
if (!newTokenId) return null;
|
|
141
|
+
const {
|
|
142
|
+
data: revealData
|
|
143
|
+
} = await revealTokenMutation({
|
|
144
|
+
variables: {
|
|
145
|
+
id: newTokenId
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
token = (revealData == null ? void 0 : revealData.revealSecretApiToken) || null;
|
|
149
|
+
}
|
|
150
|
+
if (token && isJwtExpired(token) && !opts.discardExistingRow) {
|
|
151
|
+
return obtainSystemToken({
|
|
152
|
+
discardExistingRow: true
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return token;
|
|
75
156
|
} catch (err) {
|
|
76
157
|
console.error("[useObtainSystemToken] error:", err);
|
|
77
158
|
return null;
|
|
78
159
|
}
|
|
79
|
-
}, [systemTokenData,
|
|
160
|
+
}, [systemTokenData, createSystemToken, revealTokenMutation, revokeTokenMutation, refetchSystemToken, orgName, projectId, tagId]);
|
|
161
|
+
const regenerateSystemToken = useCallback(() => obtainSystemToken({
|
|
162
|
+
discardExistingRow: true
|
|
163
|
+
}), [obtainSystemToken]);
|
|
80
164
|
return {
|
|
81
165
|
loading,
|
|
82
|
-
obtainSystemToken
|
|
166
|
+
obtainSystemToken,
|
|
167
|
+
regenerateSystemToken
|
|
83
168
|
};
|
|
84
169
|
}export{useObtainSystemToken};//# sourceMappingURL=useObtainSystemToken.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObtainSystemToken.js","sources":["../../src/hooks/useObtainSystemToken.ts"],"sourcesContent":["/**\n * Mint / reveal the org-scoped system JWT (GetUserSystemToken → RevealSecretApiToken).\n * Same token the webbuilder surface expects as `cdecli_token` / `?token=`.\n */\n\nimport { useCallback } from 'react';\nimport {\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local + staging: HS256 matches backend JWT secret. RS256 needs a private key\n * many staging clusters do not ship — create then fails and Web Builder never opens. */\nconst SYSTEM_TOKEN_ALGORITHM = SecretApiTokenAlgorithm.Hs256;\n\nfunction isAlreadyHasSystemTokenError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n}\n\nexport interface UseObtainSystemTokenResult {\n /** True while the initial GetUserSystemToken query is in flight. */\n loading: boolean;\n /** Mint or reveal the current system token. Returns null on failure. */\n obtainSystemToken: () => Promise<string | null>;\n}\n\nexport function useObtainSystemToken(enabled = true): UseObtainSystemTokenResult {\n const { orgName, projectId, tagId } = usePrerequisiteIds();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !enabled,\n fetchPolicy: 'network-only',\n });\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n // Always re-check network — cached null from skip/loading must not short-circuit create.\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n }\n\n if (!tokenId) {\n if (!orgName || !projectId || !tagId) {\n return null;\n }\n // Never mint against the local testing UUID on staging/prod.\n if (!__DEV__ && projectId === '9a8ac704-1040-4836-9b72-48b771ca91b1') {\n console.warn('[useObtainSystemToken] refusing staging mint with testing project UUID');\n return null;\n }\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName,\n projectId,\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n if (!tokenId) {\n const afterCreate = await refetchSystemToken().catch(() => null);\n tokenId = afterCreate?.data?.getUserSystemToken?.id ?? null;\n }\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useObtainSystemToken] error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n return { loading, obtainSystemToken };\n}\n\n/**\n * Append `?token=&state=` for SurfaceLoginGate.captureLoginCallback(),\n * or replace existing token/state query params.\n */\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state = 'mobile-webview'): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\n/** Injected before page scripts so SurfaceLoginGate finds cdecli_token immediately. */\nexport function buildCdecliTokenInjection(token: string): string {\n const safe = JSON.stringify(token);\n return `\n(function () {\n try {\n localStorage.setItem('cdecli_token', ${safe});\n sessionStorage.setItem('cdecli_token', ${safe});\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useObtainSystemToken.js","sources":["../../src/hooks/useObtainSystemToken.ts"],"sourcesContent":["/**\n * Mint / reveal the org-scoped system JWT (GetUserSystemToken → RevealSecretApiToken).\n * Same token the webbuilder surface expects as `cdecli_token` / `?token=`.\n *\n * Matches web `useObtainSystemToken`: revoke a stale/rejected row before create\n * (one-per-user), and do not force HS256 — the backend default is HS256 when no\n * RS256 private key is present; forcing HS256 forever re-reveals a JWT signed\n * with a rotated secret.\n */\n\nimport { useCallback } from 'react';\nimport {\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n useRevokeSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\nimport {\n isAlreadyHasSystemTokenError,\n isJwtExpired,\n isMissingRs256KeyError,\n isMissingVaultSecretError,\n isSystemTokenRowStale,\n} from './systemTokenJwt';\n\nexport interface ObtainSystemTokenOptions {\n /** Revoke the server row first (dead signature, key rotation). */\n discardExistingRow?: boolean;\n}\n\nexport interface UseObtainSystemTokenResult {\n /** True while the initial GetUserSystemToken query is in flight. */\n loading: boolean;\n /** Mint or reveal the current system token. Returns null on failure. */\n obtainSystemToken: (opts?: ObtainSystemTokenOptions) => Promise<string | null>;\n /** Always revoke + remint. */\n regenerateSystemToken: () => Promise<string | null>;\n}\n\nexport function useObtainSystemToken(enabled = true): UseObtainSystemTokenResult {\n const { orgName, projectId, tagId } = usePrerequisiteIds();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const [revokeTokenMutation] = useRevokeSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !enabled,\n fetchPolicy: 'network-only',\n });\n\n const createSystemToken = useCallback(\n async (algorithm?: SecretApiTokenAlgorithm) => {\n return createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n ...(algorithm ? { algorithm } : {}),\n },\n },\n });\n },\n [createTokenMutation, orgName, projectId, tagId],\n );\n\n const obtainSystemToken = useCallback(\n async (opts: ObtainSystemTokenOptions = {}): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n let expiresAt: string | null = systemTokenData?.getUserSystemToken?.expiresAt ?? null;\n\n if (!tokenId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n expiresAt = refetchResult?.data?.getUserSystemToken?.expiresAt ?? expiresAt;\n }\n\n if (tokenId && (opts.discardExistingRow || isSystemTokenRowStale(expiresAt))) {\n try {\n await revokeTokenMutation({ variables: { id: tokenId } });\n } catch {\n /* best-effort — create below surfaces a real conflict */\n }\n tokenId = null;\n expiresAt = null;\n }\n\n if (!tokenId) {\n if (!orgName || !projectId || !tagId) {\n return null;\n }\n if (!__DEV__ && projectId === '9a8ac704-1040-4836-9b72-48b771ca91b1') {\n console.warn('[useObtainSystemToken] refusing staging mint with testing project UUID');\n return null;\n }\n try {\n const { data: createData } = await createSystemToken();\n tokenId = createData?.createSecretApiToken?.id ?? null;\n expiresAt = createData?.createSecretApiToken?.expiresAt ?? expiresAt;\n if (!tokenId) {\n const afterCreate = await refetchSystemToken().catch(() => null);\n tokenId = afterCreate?.data?.getUserSystemToken?.id ?? null;\n expiresAt = afterCreate?.data?.getUserSystemToken?.expiresAt ?? expiresAt;\n }\n } catch (createErr) {\n if (isMissingRs256KeyError(createErr)) {\n const { data: hsData } = await createSystemToken(SecretApiTokenAlgorithm.Hs256);\n tokenId = hsData?.createSecretApiToken?.id ?? null;\n expiresAt = hsData?.createSecretApiToken?.expiresAt ?? expiresAt;\n } else if (isAlreadyHasSystemTokenError(createErr)) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n expiresAt = refetchResult?.data?.getUserSystemToken?.expiresAt ?? expiresAt;\n if (!tokenId) return null;\n } else {\n throw createErr;\n }\n }\n }\n\n if (!tokenId) return null;\n\n let token: string | null = null;\n try {\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n token = (revealData?.revealSecretApiToken as string) || null;\n } catch (revealErr) {\n const msg = revealErr instanceof Error ? revealErr.message : String(revealErr);\n if (!isMissingVaultSecretError(msg) || !orgName || !projectId || !tagId) {\n throw revealErr;\n }\n try {\n await revokeTokenMutation({ variables: { id: tokenId } });\n } catch {\n /* continue with recreation */\n }\n let createData;\n try {\n createData = (await createSystemToken()).data;\n } catch (retryErr) {\n if (!isMissingRs256KeyError(retryErr)) throw retryErr;\n createData = (await createSystemToken(SecretApiTokenAlgorithm.Hs256)).data;\n }\n const newTokenId = createData?.createSecretApiToken?.id ?? null;\n if (!newTokenId) return null;\n const { data: revealData } = await revealTokenMutation({ variables: { id: newTokenId } });\n token = (revealData?.revealSecretApiToken as string) || null;\n }\n\n if (token && isJwtExpired(token) && !opts.discardExistingRow) {\n return obtainSystemToken({ discardExistingRow: true });\n }\n\n return token;\n } catch (err) {\n console.error('[useObtainSystemToken] error:', err);\n return null;\n }\n },\n [\n systemTokenData,\n createSystemToken,\n revealTokenMutation,\n revokeTokenMutation,\n refetchSystemToken,\n orgName,\n projectId,\n tagId,\n ],\n );\n\n const regenerateSystemToken = useCallback(\n () => obtainSystemToken({ discardExistingRow: true }),\n [obtainSystemToken],\n );\n\n return { loading, obtainSystemToken, regenerateSystemToken };\n}\n\n/**\n * Append `?token=&state=` for SurfaceLoginGate.captureLoginCallback(),\n * or replace existing token/state query params.\n */\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state = 'mobile-webview'): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\n/** Injected before page scripts so SurfaceLoginGate finds cdecli_token immediately. */\nexport function buildCdecliTokenInjection(token: string): string {\n const safe = JSON.stringify(token);\n return `\n(function () {\n try {\n localStorage.setItem('cdecli_token', ${safe});\n sessionStorage.setItem('cdecli_token', ${safe});\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useMemo,useEffect,useCallback,useState,useRef}from'react';import {useColorScheme,useWindowDimensions,Keyboard,StyleSheet,View}from'react-native';import {getDefaultLeftItems,getDefaultRightItems,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 {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatStream}from'../../hooks/useChatStream.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 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 {hasComposerAttachments,takeComposerAttachments}from'../../features/attachments/composerAttachmentHandoff.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useMemo,useEffect,useCallback,useState,useRef}from'react';import {useColorScheme,useWindowDimensions,Keyboard,StyleSheet,View}from'react-native';import {getDefaultLeftItems,getDefaultRightItems,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 {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatStream}from'../../hooks/useChatStream.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 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 {hasComposerAttachments,takeComposerAttachments}from'../../features/attachments/composerAttachmentHandoff.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -52,8 +52,9 @@ function ChatScreen() {
|
|
|
52
52
|
const chatRouting = useMemo(() => ({
|
|
53
53
|
channelConnected: cdecli.channelConnected,
|
|
54
54
|
accountId: cdecli.accountId,
|
|
55
|
-
persistenceMode: effectivePersistenceMode
|
|
56
|
-
|
|
55
|
+
persistenceMode: effectivePersistenceMode,
|
|
56
|
+
recoverAgentAuth: cdecli.recoverAgentAuth
|
|
57
|
+
}), [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, effectivePersistenceMode]);
|
|
57
58
|
const chat = useChatStream(channelId, chatRouting);
|
|
58
59
|
const transcriptRows = useMemo(() => chat.messages.map((msg, index) => ({
|
|
59
60
|
id: `msg-${index}-${msg.role}`,
|
|
@@ -110,12 +111,13 @@ function ChatScreen() {
|
|
|
110
111
|
if (!channelId) return;
|
|
111
112
|
if (cdecli.status !== "connected" && cdecli.status !== "error") return;
|
|
112
113
|
const stashed = hasComposerAttachments(channelId) ? takeComposerAttachments(channelId) : void 0;
|
|
113
|
-
|
|
114
|
+
const attachments = (stashed == null ? void 0 : stashed.length) ? stashed : initialAttachments;
|
|
115
|
+
if (!initialQuery && !(attachments == null ? void 0 : attachments.length)) return;
|
|
114
116
|
autoFiredRef.current = true;
|
|
115
117
|
if (isDeepSearchMode) {
|
|
116
118
|
setIsDeepSearchModalOpen(true);
|
|
117
119
|
}
|
|
118
|
-
void sendMessage(initialQuery != null ? initialQuery : "",
|
|
120
|
+
void sendMessage(initialQuery != null ? initialQuery : "", attachments, channelId);
|
|
119
121
|
try {
|
|
120
122
|
navigation.setParams({
|
|
121
123
|
initialQuery: null,
|
|
@@ -124,6 +126,17 @@ function ChatScreen() {
|
|
|
124
126
|
} catch (e) {
|
|
125
127
|
}
|
|
126
128
|
}, [channelId, initialQuery, initialAttachments, sendMessage, navigation, cdecli.status, isDeepSearchMode]);
|
|
129
|
+
const handleAskUserAnswer = useCallback((formatted) => {
|
|
130
|
+
const text = formatted.trim();
|
|
131
|
+
if (!text) return;
|
|
132
|
+
void sendMessage(text, void 0, channelId);
|
|
133
|
+
}, [sendMessage, channelId]);
|
|
134
|
+
const [resolvedAskIds, setResolvedAskIds] = useState({});
|
|
135
|
+
const pendingAsk = useMemo(() => pendingAskUser([...transcriptRows, ...(response == null ? void 0 : response.trim()) ? [{
|
|
136
|
+
role: "assistant",
|
|
137
|
+
content: response
|
|
138
|
+
}] : []]), [transcriptRows, response]);
|
|
139
|
+
const showAskCard = Boolean(pendingAsk && !resolvedAskIds[pendingAsk.requestId]);
|
|
127
140
|
const handleSend = useCallback((text) => {
|
|
128
141
|
var _a2;
|
|
129
142
|
const pending = imageAttachments.forSend();
|
|
@@ -373,6 +386,17 @@ function ChatScreen() {
|
|
|
373
386
|
return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
374
387
|
}, children: [
|
|
375
388
|
showSendingLoader && pinSendingLoaderNearComposer ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: styles.sendingLoaderInDock, children: /* @__PURE__ */ jsx(ThinkingIndicator, { color: secondaryTextColor }) }) : null,
|
|
389
|
+
showAskCard && pendingAsk ? /* @__PURE__ */ jsx(View, { style: {
|
|
390
|
+
width: contentMaxWidth,
|
|
391
|
+
paddingHorizontal: 8
|
|
392
|
+
}, children: /* @__PURE__ */ jsx(AskUserCard, { payload: pendingAsk, isDark, onAnswer: (formatted) => {
|
|
393
|
+
setResolvedAskIds((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
394
|
+
[pendingAsk.requestId]: true
|
|
395
|
+
}));
|
|
396
|
+
handleAskUserAnswer(formatted);
|
|
397
|
+
}, onDismiss: () => setResolvedAskIds((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
398
|
+
[pendingAsk.requestId]: true
|
|
399
|
+
})) }) }) : null,
|
|
376
400
|
/* @__PURE__ */ jsxs(View, { style: [styles.bottomComposerInner, {
|
|
377
401
|
width: contentMaxWidth
|
|
378
402
|
}], children: [
|