@truefoundry/assistant-ui-runtime 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useTrueFoundryAgentRuntime.ts","../src/constants.ts","../src/toolApproval.ts","../src/askUserQuestion.ts","../src/createSubAgent.ts","../src/modelMessageImageContent.ts","../src/modelMessageContent.ts","../src/foldPeerThreads.ts","../src/toolResponse.ts","../src/collectPending.ts","../src/listPages.ts","../src/extractTurnUserText.ts","../src/mcpAuth.ts","../src/turnEventHelpers.ts","../src/sessionSnapshot.ts","../src/convertTurnMessages.ts","../src/draft/draftSessionBridge.ts","../src/sessionListStartTimestamp.ts","../src/draft/agentSpec.ts","../src/sessionThreadMetadata.ts","../src/draft/truefoundryDraftThreadListAdapter.ts","../src/truefoundryExtras.ts","../src/sessions.ts","../src/truefoundryThreadListAdapter.ts","../src/types.ts","../src/draft/useDraftAgentSpec.ts","../src/useTrueFoundryAgentMessages.ts","../src/loadSessionSnapshot.ts","../src/requiredActionInputs.ts","../src/streamTurn.ts","../src/truefoundryOwnedSessionsThreadListAdapter.ts","../src/hooks.ts","../src/attachmentAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport {\n pickExternalStoreSharedOptions,\n type AppendMessage,\n type ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport {\n useExternalStoreRuntime,\n useRemoteThreadListRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { MutableRefObject } from \"react\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport type { AgentSpec } from \"./server/types.js\";\nimport {\n collectPendingApprovals,\n collectPendingToolResponses,\n derivePendingMcpAuth,\n deriveSandboxId,\n} from \"./collectPending.js\";\nimport {\n buildUserMessageContent,\n extractEditedText,\n parseTurnIdFromMessageId,\n userMessageContentToText,\n} from \"./convertTurnMessages.js\";\nimport {\n createDraftSessionBridge,\n DRAFT_SESSION_LAST_UPDATED_AT_HEADER,\n} from \"./draft/draftSessionBridge.js\";\nimport { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from \"./mcpAuth.js\";\nimport { createTrueFoundryDraftThreadListAdapter } from \"./draft/truefoundryDraftThreadListAdapter.js\";\nimport { trueFoundryExtras } from \"./truefoundryExtras.js\";\nimport { createTrueFoundryThreadListAdapter } from \"./truefoundryThreadListAdapter.js\";\nimport type { UseTrueFoundryAgentRuntimeOptions } from \"./types.js\";\nimport { resolveTrueFoundryAgentRuntimeOptions } from \"./types.js\";\nimport { useDraftAgentSpec } from \"./draft/useDraftAgentSpec.js\";\nimport { useTrueFoundryAgentMessages } from \"./useTrueFoundryAgentMessages.js\";\n\nfunction useTrueFoundryAgentRuntimeImpl(\n options: ReturnType<typeof resolveTrueFoundryAgentRuntimeOptions>,\n pendingAgentSpecRef: MutableRefObject<AgentSpec | undefined>,\n) {\n const {\n server,\n agent,\n adapters,\n onError,\n listEventsConcurrency,\n ...sharedOptions\n } = options;\n\n const draftBridgeRef = useRef(\n agent.mode === \"draft\" ? createDraftSessionBridge(server) : null,\n );\n\n const draftSessionId = useAuiState(\n (state) =>\n agent.mode === \"draft\"\n ? (state.threadListItem.remoteId ?? undefined)\n : undefined,\n );\n const sessionId = useAuiState((state) => state.threadListItem.remoteId ?? undefined);\n const isMain = useAuiState(\n (state) => state.threads.mainThreadId === state.threadListItem.id,\n );\n // On a hard refresh, the URL session runtime mounts before assistant-ui\n // promotes it to the main thread. Allow that one session to hydrate early.\n const isInitialSession =\n sessionId != null && sessionId === options.initialSessionId;\n\n const draftSpec = useDraftAgentSpec({\n draftSessionId,\n draftBridge: draftBridgeRef.current,\n defaultAgentSpec:\n agent.mode === \"draft\" ? agent.defaultAgentSpec : { model: { name: \"\" } },\n onAgentSpecChange: agent.mode === \"draft\" ? agent.onAgentSpecChange : undefined,\n onError,\n });\n\n const takeTurnHeaderTimestampRef = useRef(draftSpec.takeTurnHeaderTimestamp);\n takeTurnHeaderTimestampRef.current = draftSpec.takeTurnHeaderTimestamp;\n\n const getTurnHeaders = useCallback(async () => {\n if (agent.mode !== \"draft\") {\n return undefined;\n }\n const updatedAt = await takeTurnHeaderTimestampRef.current();\n if (updatedAt == null) {\n return undefined;\n }\n return { [DRAFT_SESSION_LAST_UPDATED_AT_HEADER]: updatedAt };\n }, [agent.mode]);\n\n const aui = useAui();\n const initializeSession = useCallback(\n () => aui.threadListItem().initialize(),\n [aui],\n );\n const runtimeAdapters = useRuntimeAdapters();\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const {\n messages,\n isRunning,\n isLoading,\n isLoadingOlderHistory,\n hasOlderHistory,\n loadOlderHistory,\n sendTurn,\n cancel,\n respondToToolApproval,\n respondToToolResponse,\n resumeRun,\n editFromTurn,\n resetFromTurn,\n retryLoad,\n } = useTrueFoundryAgentMessages({\n server,\n sessionId,\n isMain,\n isInitialSession,\n listEventsConcurrency,\n onError,\n initializeSession,\n getTurnHeaders: agent.mode === \"draft\" ? getTurnHeaders : undefined,\n });\n\n if (agent.mode === \"draft\" && draftSpec.agentSpec != null) {\n pendingAgentSpecRef.current = draftSpec.agentSpec;\n }\n\n const pendingApprovals = useMemo(\n () => collectPendingApprovals(messages),\n [messages],\n );\n const pendingToolResponses = useMemo(\n () => collectPendingToolResponses(messages),\n [messages],\n );\n const pendingMcpAuth = useMemo(() => derivePendingMcpAuth(messages), [messages]);\n const sandboxId = useMemo(() => deriveSandboxId(messages), [messages]);\n\n const resumeMcpAuth = useMemo(\n () => () => sendTurn({ resumeMcpAuth: true }),\n [sendTurn],\n );\n\n const downloadSandboxFile = useCallback(\n async ({ turnId, path }: { turnId: string; path: string }) => {\n if (server.downloadSandboxFile == null) {\n throw new Error(\n \"Downloading a sandbox file requires AgentChatServer.downloadSandboxFile.\",\n );\n }\n if (sessionId == null) {\n throw new Error(\n \"This session has not been saved yet, so its files cannot be downloaded.\",\n );\n }\n if (sandboxId == null) {\n throw new Error(\"No sandbox is available yet for this session.\");\n }\n return await server.downloadSandboxFile({\n sessionId,\n turnId,\n sandboxId,\n path,\n });\n },\n [server, sessionId, sandboxId],\n );\n\n const draftExtras = useMemo(() => {\n if (agent.mode !== \"draft\") {\n return null;\n }\n return {\n agentSpec: draftSpec.agentSpec,\n draftSessionId: draftSpec.draftSessionId,\n isSpecLoading: draftSpec.isSpecLoading,\n isSpecSyncing: draftSpec.isSpecSyncing,\n specError: draftSpec.specError,\n updateAgentSpec: draftSpec.updateAgentSpec,\n };\n }, [agent.mode, draftSpec]);\n\n return useExternalStoreRuntime({\n ...pickExternalStoreSharedOptions(sharedOptions),\n messages,\n isRunning,\n isLoading,\n extras: trueFoundryExtras.provide({\n pendingApprovals,\n pendingToolResponses,\n pendingMcpAuth,\n sandboxId,\n respondToToolApproval,\n respondToToolResponse,\n resumeMcpAuth,\n downloadSandboxFile,\n cancel,\n // resetFromTurn/branchFromTurn/sendTurn already report via onError.\n resetFromTurn: (turnId: string) =>\n resetFromTurn(turnId).catch(() => undefined),\n reload: retryLoad,\n hasOlderHistory,\n isLoadingOlderHistory,\n loadOlderHistory,\n draft: draftExtras,\n }),\n unstable_enableToolInvocations: true,\n setToolStatuses,\n adapters: {\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n },\n onNew: async (message: AppendMessage) => {\n if (!(message.startRun ?? message.role === \"user\")) {\n return;\n }\n\n const resumeMcpAuthFlag =\n message.runConfig?.custom?.[MCP_AUTH_RESUME_RUN_CUSTOM_KEY] === true;\n\n if (resumeMcpAuthFlag) {\n await sendTurn({ resumeMcpAuth: true });\n return;\n }\n\n const userMessage = buildUserMessageContent(message);\n await sendTurn({\n userMessage,\n // The composer clears before onNew runs. Restore its text only when\n // the turn failed before turn.created registered it in the backend.\n onPreTurnFailure: () => {\n const text = userMessageContentToText(userMessage);\n const composer = aui.thread().composer();\n if (text && !composer.getState().text.trim()) {\n composer.setText(text);\n }\n },\n });\n },\n onCancel: async () => {\n await cancel();\n },\n onRespondToToolApproval: async (response) => {\n respondToToolApproval(response);\n },\n onResume: async () => {\n await resumeRun();\n },\n onEdit: async (message: AppendMessage) => {\n const sourceId = message.sourceId;\n if (sourceId == null) {\n throw new Error(\"Could not resolve edited user message.\");\n }\n const turnId = parseTurnIdFromMessageId(sourceId);\n const editedText = extractEditedText(message);\n // editFromTurn/branchFromTurn/sendTurn already report via onError.\n await editFromTurn(turnId, editedText);\n },\n });\n}\n\nexport function useTrueFoundryAgentRuntime(options: UseTrueFoundryAgentRuntimeOptions) {\n const resolved = resolveTrueFoundryAgentRuntimeOptions(options);\n const { server, agent } = resolved;\n\n const pendingAgentSpecRef = useRef<AgentSpec | undefined>(\n agent.mode === \"draft\" ? agent.defaultAgentSpec : undefined,\n );\n\n const agentMode = agent.mode;\n const namedAgentName = agent.mode === \"named\" ? agent.agentName : undefined;\n const listSessionsAgentId = resolved.listSessionsAgentId;\n const threadListAdapter = useMemo(() => {\n if (agentMode === \"draft\") {\n const draftAgent = agent as Extract<typeof agent, { mode: \"draft\" }>;\n return createTrueFoundryDraftThreadListAdapter({\n server,\n defaultAgentSpec: draftAgent.defaultAgentSpec,\n getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec,\n listSessionsAgentId,\n });\n }\n return createTrueFoundryThreadListAdapter({\n server,\n agentName: namedAgentName!,\n listSessionsAgentId,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentMode, namedAgentName, listSessionsAgentId, server]);\n\n return useRemoteThreadListRuntime({\n allowNesting: true,\n adapter: threadListAdapter,\n initialThreadId: resolved.initialSessionId,\n threadId: resolved.threadId,\n onThreadIdChange: resolved.onThreadIdChange,\n runtimeHook: () => useTrueFoundryAgentRuntimeImpl(resolved, pendingAgentSpecRef),\n });\n}\n","/** Gateway root thread id — always the literal `\"main\"`. */\nexport const ROOT_THREAD_ID = \"main\";\n","import type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadAssistantMessagePart,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type {\n ToolApprovalRequiredEvent,\n Turn,\n UserToolApprovalEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { ToolApprovalMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\nexport type StoredApprovalDecision = {\n approved: boolean;\n reason?: string;\n};\n\nexport const TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY = \"toolApprovalThreadId\";\n\nexport type RespondToToolApprovalOptions = {\n approvalId: string;\n approved: boolean;\n optionId?: string;\n reason?: string;\n};\n\ntype ApprovalDecision = UserToolApprovalEvent[\"approval\"];\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\ntype AssistantToolCallPart = Extract<\n ThreadAssistantMessagePart,\n { type: \"tool-call\" }\n>;\n\nexport function hasPendingToolApproval(\n approval: ToolCallPart[\"approval\"] | undefined,\n): boolean {\n return (\n approval != null &&\n approval.approved === undefined &&\n approval.resolution === undefined\n );\n}\n\nfunction applyApprovalDecisionToToolCall(\n part: AssistantToolCallPart,\n options: RespondToToolApprovalOptions,\n): AssistantToolCallPart {\n const { approved, optionId, reason } = options;\n const targetApproval = part.approval!;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null ? { optionId } : {}),\n ...(reason != null ? { reason } : {}),\n };\n if (approved) {\n return { ...part, approval };\n }\n return {\n ...part,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n}\n\nfunction updateToolApprovalInContent(\n content: readonly ThreadAssistantMessagePart[],\n options: RespondToToolApprovalOptions,\n): { content: readonly ThreadAssistantMessagePart[]; found: boolean } {\n let found = false;\n const newContent = content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n if (part.approval?.id === options.approvalId) {\n found = true;\n return applyApprovalDecisionToToolCall(part, options);\n }\n\n if (part.messages == null) {\n return part;\n }\n\n const messages = part.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n const nested = updateToolApprovalInContent(message.content, options);\n if (!nested.found) {\n return message;\n }\n found = true;\n return { ...message, content: nested.content };\n });\n return { ...part, messages };\n });\n\n return { content: newContent, found };\n}\n\nexport function applyApprovalDecisionsToMessage(\n message: ThreadAssistantMessage,\n options: RespondToToolApprovalOptions,\n): ThreadAssistantMessage {\n const { content } = updateToolApprovalInContent(message.content, options);\n return { ...message, content: [...content] };\n}\n\nexport function toolApprovalStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"tool-calls\" };\n}\n\nexport function toolApprovalMessageCustom(\n threadId: string,\n): ToolApprovalMessageCustomMetadata {\n return {\n [TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY]:\n threadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : threadId,\n };\n}\n\nexport function getToolApprovalThreadId(\n message: ThreadMessage | undefined,\n): string | undefined {\n if (message?.role !== \"assistant\") {\n return undefined;\n }\n const threadId = message.metadata.custom[TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY];\n return typeof threadId === \"string\" ? threadId : undefined;\n}\n\nexport function findApprovalRequiredInTurn(\n turn: Pick<Turn, \"state\">,\n): ToolApprovalRequiredEvent | undefined {\n if (turn.state.status !== \"done\") {\n return undefined;\n }\n const found = turn.state.requiredActions?.find(\n (action) => action.type === \"tool.approval_required\",\n );\n return found?.type === \"tool.approval_required\" ? found : undefined;\n}\n\nfunction toolCallPartHasPendingApproval(part: ToolCallPart): boolean {\n return hasPendingToolApproval(part.approval);\n}\n\nfunction nestedMessagesHavePendingApprovals(\n messages: readonly ThreadMessage[],\n): boolean {\n for (const message of messages) {\n if (messageHasPendingApprovals(message)) {\n return true;\n }\n }\n return false;\n}\n\nexport function messageHasPendingApprovals(message: ThreadMessage | undefined): boolean {\n if (message?.role !== \"assistant\") {\n return false;\n }\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (toolCallPartHasPendingApproval(part)) {\n return true;\n }\n if (part.messages != null && nestedMessagesHavePendingApprovals(part.messages)) {\n return true;\n }\n }\n return false;\n}\n\nfunction walkAssistantToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: AssistantToolCallPart) => void,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role === \"assistant\") {\n walkAssistantToolCallParts(message.content, visit);\n }\n }\n }\n}\n\nexport function collectDecidedApprovalsFromContent(\n content: readonly ThreadAssistantMessagePart[],\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n walkAssistantToolCallParts(content, (part) => {\n const { approval } = part;\n if (approval?.id == null || approval.approved === undefined) {\n return;\n }\n decisions.set(approval.id, {\n approved: approval.approved,\n ...(approval.reason != null ? { reason: approval.reason } : {}),\n });\n });\n return decisions;\n}\n\nfunction applyApprovalDecisionsToMessages(\n messages: readonly ThreadMessage[],\n decisions: ReadonlyMap<string, StoredApprovalDecision>,\n): ThreadMessage[] {\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyApprovalDecisionsToContent(message.content, decisions),\n };\n });\n}\n\nexport function applyApprovalDecisionsToContent(\n content: readonly ThreadAssistantMessagePart[],\n decisions: ReadonlyMap<string, StoredApprovalDecision>,\n): ThreadAssistantMessagePart[] {\n return content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n const decision =\n part.approval?.id != null ? decisions.get(part.approval.id) : undefined;\n let nextPart: AssistantToolCallPart = part;\n\n if (\n decision != null &&\n part.approval != null &&\n part.approval.approved === undefined\n ) {\n nextPart = applyApprovalDecisionToToolCall(part, {\n approvalId: part.approval.id,\n approved: decision.approved,\n reason: decision.reason,\n });\n }\n\n if (nextPart.messages == null) {\n return nextPart;\n }\n\n return {\n ...nextPart,\n messages: applyApprovalDecisionsToMessages(nextPart.messages, decisions),\n };\n });\n}\n\nexport function mergeDecidedApprovalsIntoContent(\n incoming: readonly ThreadAssistantMessagePart[],\n existing: readonly ThreadAssistantMessagePart[],\n): ThreadAssistantMessagePart[] {\n const decided = collectDecidedApprovalsFromContent(existing);\n if (decided.size === 0) {\n return [...incoming];\n }\n return applyApprovalDecisionsToContent(incoming, decided);\n}\n\nexport function extractToolApprovalsFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): UserToolApprovalEvent[] {\n const events: UserToolApprovalEvent[] = [];\n for (const item of input ?? []) {\n if (item.type === \"user.tool_approval\") {\n events.push(item);\n }\n }\n return events;\n}\n\nexport function collectSubsequentApprovalDecisions(\n turns: readonly Pick<Turn, \"input\">[],\n fromIndex: number,\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n\n for (let index = fromIndex + 1; index < turns.length; index++) {\n const input = turns[index]?.input ?? [];\n if (input.some((item) => item.type === \"user.message\")) {\n break;\n }\n\n for (const event of extractToolApprovalsFromTurnInput(input)) {\n decisions.set(event.toolCallId, {\n approved: event.approval.status === \"allow\",\n ...(event.approval.status === \"deny\" && event.approval.reason != null\n ? { reason: event.approval.reason }\n : {}),\n });\n }\n }\n\n return decisions;\n}\n\nexport function collectApprovalDecisionsFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n for (const event of extractToolApprovalsFromTurnInput(input)) {\n decisions.set(event.toolCallId, {\n approved: event.approval.status === \"allow\",\n ...(event.approval.status === \"deny\" && event.approval.reason != null\n ? { reason: event.approval.reason }\n : {}),\n });\n }\n return decisions;\n}\n\nfunction contentHasPendingApprovals(\n content: readonly ThreadAssistantMessagePart[],\n): boolean {\n return messageHasPendingApprovals({\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n });\n}\n\nexport function resolveToolApprovalUpdate(\n update: TurnStreamUpdate,\n priorDecisions?: ReadonlyMap<string, StoredApprovalDecision>,\n): TurnStreamUpdate {\n let { content } = update;\n if (priorDecisions != null && priorDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, priorDecisions);\n }\n\n if (\n contentHasPendingApprovals(content) ||\n update.status?.type !== \"requires-action\" ||\n update.status.reason !== \"tool-calls\"\n ) {\n return { ...update, content };\n }\n\n const { status: _status, metadata: _metadata, ...rest } = update;\n return { ...rest, content };\n}\n\nexport function mapApprovalDecision(\n approved: boolean,\n reason?: string,\n): ApprovalDecision {\n if (approved) {\n return { status: \"allow\" };\n }\n return { status: \"deny\", ...(reason != null ? { reason } : {}) };\n}\n\nfunction isDecidedApprovalAwaitingSdk(part: ToolCallPart): boolean {\n const { approval, result, isError } = part;\n if (approval?.id == null || approval.approved === undefined) {\n return false;\n }\n if (approval.approved === true) {\n return result === undefined;\n }\n return isError === true;\n}\n\nfunction collectApprovalInputsFromMessages(\n messages: readonly ThreadMessage[],\n defaultThreadId: string,\n): UserToolApprovalEvent[] {\n const events: UserToolApprovalEvent[] = [];\n for (const message of messages) {\n events.push(...collectApprovalInputs(message, defaultThreadId));\n }\n return events;\n}\n\nexport function collectApprovalInputs(\n message: ThreadMessage,\n threadId: string,\n): UserToolApprovalEvent[] {\n if (message.role !== \"assistant\" || !threadId) {\n return [];\n }\n if (messageHasPendingApprovals(message)) {\n return [];\n }\n\n const scopedThreadId = getToolApprovalThreadId(message) ?? threadId;\n const events: UserToolApprovalEvent[] = [];\n\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (isDecidedApprovalAwaitingSdk(part)) {\n const { approval } = part;\n if (approval == null) {\n continue;\n }\n events.push({\n type: \"user.tool_approval\",\n threadId: scopedThreadId,\n toolCallId: approval.id,\n approval: mapApprovalDecision(approval.approved!, approval.reason),\n });\n }\n if (part.messages != null) {\n events.push(\n ...collectApprovalInputsFromMessages(part.messages, scopedThreadId),\n );\n }\n }\n return events;\n}\n\nexport function toTrueFoundryApprovalInputs(\n message: Extract<ThreadMessage, { role: \"assistant\" }>,\n response: RespondToToolApprovalOptions,\n defaultThreadId: string = ROOT_THREAD_ID,\n): UserToolApprovalEvent[] {\n const updated = applyApprovalDecisionsToMessage(message, response);\n return collectApprovalInputs(updated, defaultThreadId);\n}\n","import type { ToolCall } from \"./server/index.js\";\n\nexport function isAskUserQuestionToolCall(\n toolCall: Pick<ToolCall, \"toolInfo\">,\n): boolean {\n return (\n toolCall.toolInfo?.type === \"truefoundry-system\" &&\n toolCall.toolInfo?.name === \"ask_user_question\"\n );\n}\n\nexport type AskUserQuestionArgs = {\n question?: string;\n options?: string[];\n};\n\nexport function parseAskUserQuestionArgs(\n argsText: string | undefined,\n): AskUserQuestionArgs {\n if (!argsText) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(argsText);\n if (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n const record = parsed as Record<string, unknown>;\n const question = typeof record.question === \"string\" ? record.question : undefined;\n const options = Array.isArray(record.options)\n ? record.options.filter((item): item is string => typeof item === \"string\")\n : undefined;\n return { question, options };\n } catch {\n return {};\n }\n}\n","import type { ToolCall } from \"./server/index.js\";\n\nexport function isCreateSubAgentToolCall(\n toolCall: Pick<ToolCall, \"toolInfo\" | \"function\">,\n): boolean {\n // Gateway may attach truefoundry-system toolInfo on persisted turns, but streamed\n // model.message tool calls often only carry function.name. Without the fallback,\n // foldPeerThreads never nests child threads under the spawning tool call.\n if (\n toolCall.toolInfo?.type === \"truefoundry-system\" &&\n toolCall.toolInfo?.name === \"create_sub_agent\"\n ) {\n return true;\n }\n return toolCall.function?.name === \"create_sub_agent\";\n}\n","import type { CompleteAttachment } from \"@assistant-ui/core\";\nimport {\n isEventDelta,\n mergeEventDelta,\n type ModelMessageEvent,\n type TurnEvent,\n type TurnStreamingEvent,\n} from \"./server/index.js\";\n\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\n\nexport type ImageUrlContentPart = {\n type: \"image_url\";\n image_url: { url: string };\n};\n\ntype ModelMessageContentPart =\n | { type: \"text\"; text: string }\n | { type: \"refusal\"; refusal: string }\n | ImageUrlContentPart;\n\ntype ContentBlockDelta = {\n index: number;\n delta:\n | { type: \"text\"; text?: string }\n | { type: \"image_url\"; image_url?: { url?: string } };\n};\n\ntype ModelMessageDeltaWithContentBlocks = {\n type: \"model.message.delta\";\n id: string;\n contentBlocks?: ContentBlockDelta[];\n content_blocks?: ContentBlockDelta[];\n};\n\nfunction parseDataUriMime(data: string): string {\n if (!data.startsWith(\"data:\")) {\n return \"image/png\";\n }\n const match = /^data:([^;,]+)/.exec(data);\n return match?.[1] ?? \"image/png\";\n}\n\nfunction imageFilenameFromUrl(url: string, index: number): string {\n const mimeType = parseDataUriMime(url);\n const ext = mimeType.split(\"/\")[1] ?? \"png\";\n return `image-${index + 1}.${ext}`;\n}\n\nexport function isImageUrlContentPart(\n part: unknown,\n): part is ImageUrlContentPart {\n return (\n part != null &&\n typeof part === \"object\" &&\n (part as ImageUrlContentPart).type === \"image_url\" &&\n typeof (part as ImageUrlContentPart).image_url?.url === \"string\"\n );\n}\n\nfunction normalizeModelMessageContent(\n message: ModelMessageEvent,\n): ModelMessageContentPart[] {\n const { content } = message;\n if (content == null) {\n return [];\n }\n if (typeof content === \"string\") {\n return content.length > 0 ? [{ type: \"text\", text: content }] : [];\n }\n return content as ModelMessageContentPart[];\n}\n\nfunction ensureModelMessageContentArray(message: ModelMessageEvent): void {\n if (Array.isArray(message.content)) {\n return;\n }\n // Gateway may stream `image_url` content blocks that aren't in the SDK content union yet.\n (message as { content?: ModelMessageContentPart[] }).content =\n normalizeModelMessageContent(message);\n}\n\nfunction mergeContentBlockDeltas(\n message: ModelMessageEvent,\n blocks: readonly ContentBlockDelta[],\n): void {\n ensureModelMessageContentArray(message);\n const content = message.content as ModelMessageContentPart[];\n\n for (const block of blocks) {\n const index = block.index;\n while (content.length <= index) {\n content.push({ type: \"text\", text: \"\" });\n }\n\n const delta = block.delta;\n if (delta.type === \"text\") {\n const existing = content[index];\n if (existing?.type === \"text\") {\n existing.text += delta.text ?? \"\";\n } else {\n content[index] = { type: \"text\", text: delta.text ?? \"\" };\n }\n continue;\n }\n\n if (delta.type !== \"image_url\") {\n continue;\n }\n\n const chunk = delta.image_url?.url ?? \"\";\n const existing = content[index];\n if (isImageUrlContentPart(existing)) {\n existing.image_url.url += chunk;\n } else {\n content[index] = { type: \"image_url\", image_url: { url: chunk } };\n }\n }\n}\n\nexport function mergeStreamEventDelta(\n base: TurnEvent,\n delta: TurnStreamingEvent,\n): void {\n if (!isEventDelta(delta)) {\n return;\n }\n\n mergeEventDelta(base, delta);\n\n if (base.type !== \"model.message\" || delta.type !== \"model.message.delta\") {\n return;\n }\n\n const extended = delta as ModelMessageDeltaWithContentBlocks;\n const blocks = extended.contentBlocks ?? extended.content_blocks;\n if (blocks == null || blocks.length === 0) {\n return;\n }\n\n mergeContentBlockDeltas(base, blocks);\n}\n\nexport function imageUrlToAttachment(\n url: string,\n attachmentId: string,\n): CompleteAttachment {\n const mimeType = parseDataUriMime(url);\n return {\n id: attachmentId,\n type: \"image\",\n name: imageFilenameFromUrl(url, 0),\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: url, filename: imageFilenameFromUrl(url, 0) }],\n };\n}\n\nexport function imagePartToAssistantImage(url: string, index: number): AssistantContentPart {\n return {\n type: \"image\",\n image: url,\n filename: imageFilenameFromUrl(url, index),\n };\n}\n\nexport function extractImagePartsFromModelMessage(\n message: ModelMessageEvent,\n): AssistantContentPart[] {\n const parts: AssistantContentPart[] = [];\n let imageIndex = 0;\n\n for (const part of normalizeModelMessageContent(message)) {\n if (!isImageUrlContentPart(part)) {\n continue;\n }\n const url = part.image_url.url.trim();\n if (url.length === 0) {\n continue;\n }\n parts.push(imagePartToAssistantImage(url, imageIndex));\n imageIndex += 1;\n }\n\n return parts;\n}\n\nexport function extractImageUrlFromUserContentItem(\n part: unknown,\n): string | undefined {\n if (isImageUrlContentPart(part)) {\n const url = part.image_url.url.trim();\n return url.length > 0 ? url : undefined;\n }\n return undefined;\n}","import type { ThreadAssistantMessagePart } from \"@assistant-ui/core\";\nimport type { ModelMessageEvent } from \"./server/index.js\";\nimport type { PendingResponseRef } from \"./foldPeerThreads.js\";\nimport { extractImagePartsFromModelMessage } from \"./modelMessageImageContent.js\";\n\nexport type AssistantContentPart = ThreadAssistantMessagePart;\n\nexport type ToolCallContext = {\n toolResults?: ReadonlyMap<string, string>;\n pendingApprovals?: ReadonlyMap<string, { id: string }>;\n approvalDecisions?: ReadonlyMap<\n string,\n { id: string; approved: boolean; reason?: string }\n >;\n pendingResponses?: ReadonlyMap<string, PendingResponseRef>;\n};\n\nexport type SdkToolCall = NonNullable<ModelMessageEvent[\"toolCalls\"]>[number];\n\nfunction parseToolArgs(argsText: string): Record<string, string | number | boolean | null> {\n if (!argsText) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(argsText);\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, string | number | boolean | null>;\n }\n return {};\n } catch {\n return {};\n }\n}\n\ntype ToolCallPart = Extract<AssistantContentPart, { type: \"tool-call\" }>;\n\nfunction toolCallToPart(\n toolCall: SdkToolCall,\n context?: ToolCallContext,\n): ToolCallPart {\n const argsText = toolCall.function.arguments ?? \"\";\n const toolResult = context?.toolResults?.get(toolCall.id);\n const pendingResponse = context?.pendingResponses?.get(toolCall.id);\n const pendingApproval = context?.pendingApprovals?.get(toolCall.id);\n const approvalDecision = context?.approvalDecisions?.get(toolCall.id);\n\n let interrupt: ToolCallPart[\"interrupt\"];\n if (pendingResponse != null && toolResult === undefined) {\n interrupt = {\n type: \"human\",\n payload: {\n ...(pendingResponse.question != null\n ? { question: pendingResponse.question }\n : {}),\n ...(pendingResponse.options != null\n ? { options: pendingResponse.options }\n : {}),\n },\n };\n }\n\n let approval: ToolCallPart[\"approval\"];\n if (approvalDecision != null) {\n approval = {\n id: approvalDecision.id,\n approved: approvalDecision.approved,\n ...(approvalDecision.reason != null\n ? { reason: approvalDecision.reason }\n : {}),\n };\n } else if (pendingApproval != null) {\n approval = { id: pendingApproval.id };\n }\n\n let result: ToolCallPart[\"result\"];\n let isError = false;\n if (toolResult !== undefined) {\n result = toolResult;\n } else if (approvalDecision?.approved === false) {\n result = { error: approvalDecision.reason || \"Tool approval denied\" };\n isError = true;\n }\n\n return {\n type: \"tool-call\",\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n argsText,\n args: parseToolArgs(argsText),\n ...(result !== undefined ? { result } : {}),\n ...(isError ? { isError: true } : {}),\n ...(approval != null ? { approval } : {}),\n ...(interrupt != null ? { interrupt } : {}),\n };\n}\n\nfunction extractText(message: ModelMessageEvent): string {\n const { content, refusal } = message;\n if (content == null) {\n return refusal ?? \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n return content\n .map((part) => {\n if (part.type === \"text\") {\n return part.text;\n }\n if (part.type === \"refusal\") {\n return part.refusal;\n }\n return \"\";\n })\n .join(\"\");\n}\n\nexport function buildAssistantContent(\n message: ModelMessageEvent,\n context?: ToolCallContext,\n): AssistantContentPart[] {\n const parts: AssistantContentPart[] = [];\n if (message.reasoningContent) {\n parts.push({ type: \"reasoning\", text: message.reasoningContent });\n }\n const text = extractText(message);\n if (text) {\n parts.push({ type: \"text\", text });\n }\n parts.push(...extractImagePartsFromModelMessage(message));\n for (const toolCall of message.toolCalls ?? []) {\n parts.push(toolCallToPart(toolCall, context));\n }\n return parts;\n}\n","import type { MessageStatus, ThreadMessage } from \"@assistant-ui/core\";\nimport {\n isEventDelta,\n type ThreadCreatedEvent,\n type ToolResponseRequiredEvent,\n type TurnEvent,\n type TurnStreamingEvent,\n} from \"./server/index.js\";\n\nimport { parseAskUserQuestionArgs } from \"./askUserQuestion.js\";\nimport { isCreateSubAgentToolCall } from \"./createSubAgent.js\";\nimport {\n buildAssistantContent,\n type AssistantContentPart,\n type SdkToolCall,\n} from \"./modelMessageContent.js\";\nimport { mergeStreamEventDelta } from \"./modelMessageImageContent.js\";\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { SubAgentMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport { toolApprovalMessageCustom, toolApprovalStatus } from \"./toolApproval.js\";\nimport { toolResponseMessageCustom, toolResponseStatus } from \"./toolResponse.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\ntype AgentInfo = ThreadCreatedEvent[\"agentInfo\"];\n\nexport type SubAgentCustomMetadata = {\n threadId: string;\n title?: string;\n name?: string;\n model?: string;\n input?: string;\n};\n\nexport type SubAgentArtifact = {\n subAgents: Array<{\n threadId: string;\n title?: string;\n agentInfo?: AgentInfo;\n }>;\n};\n\ntype ToolCallRef = ToolResponseRequiredEvent[\"toolCalls\"][number];\n\nexport type PendingResponseRef = {\n id: string;\n sourceEventId: string;\n question?: string;\n options?: string[];\n};\n\nexport type ApprovalDecisionRef = {\n id: string;\n approved: boolean;\n reason?: string;\n};\n\nexport type ThreadBucket = {\n events: Map<string, TurnEvent>;\n modelMessageIds: string[];\n toolResults: Map<string, string>;\n pendingApprovals: Map<string, { id: string }>;\n approvalDecisions: Map<string, ApprovalDecisionRef>;\n pendingResponses: Map<string, PendingResponseRef>;\n done: boolean;\n title?: string;\n agentInfo?: AgentInfo;\n};\n\nexport type ThreadParentLink = {\n parentThreadId: string;\n toolCallId: string;\n};\n\nconst isDev =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction warnUnexpectedRootThread(threadId: string, eventType: string): void {\n if (!isDev) {\n return;\n }\n console.warn(\n `[@truefoundry/assistant-ui-runtime] Expected root thread \"${ROOT_THREAD_ID}\" but received \"${threadId}\" on ${eventType}.`,\n );\n}\n\nfunction assertRootThreadEvent(threadId: string, eventType: string): void {\n if (threadId === ROOT_THREAD_ID) {\n return;\n }\n if (isDev) {\n throw new Error(\n `[@truefoundry/assistant-ui-runtime] Root-looking event ${eventType} arrived on thread \"${threadId}\" instead of \"${ROOT_THREAD_ID}\".`,\n );\n }\n warnUnexpectedRootThread(threadId, eventType);\n}\n\nexport class PeerThreadFoldState {\n readonly threads = new Map<string, ThreadBucket>();\n readonly threadParents = new Map<string, ThreadParentLink>();\n\n getOrCreateBucket(threadId: string): ThreadBucket {\n let bucket = this.threads.get(threadId);\n if (bucket == null) {\n bucket = {\n events: new Map(),\n modelMessageIds: [],\n toolResults: new Map(),\n pendingApprovals: new Map(),\n approvalDecisions: new Map(),\n pendingResponses: new Map(),\n done: false,\n };\n this.threads.set(threadId, bucket);\n }\n return bucket;\n }\n}\n\nfunction isTurnScopedEvent(message: TurnStreamingEvent): boolean {\n return message.type === \"turn.created\" || message.type === \"turn.done\";\n}\n\nfunction ingestEventIntoBucket(\n bucket: ThreadBucket,\n message: TurnStreamingEvent,\n): void {\n if (isTurnScopedEvent(message)) {\n return;\n }\n\n if (isEventDelta(message)) {\n const base = bucket.events.get(message.id);\n if (base != null) {\n mergeStreamEventDelta(base, message);\n }\n return;\n }\n\n bucket.events.set(message.id, message as TurnEvent);\n\n if (message.type === \"model.message\") {\n if (!bucket.modelMessageIds.includes(message.id)) {\n bucket.modelMessageIds.push(message.id);\n }\n return;\n }\n\n if (message.type === \"tool.response\") {\n bucket.toolResults.set(message.toolCallId, message.content);\n bucket.pendingResponses.delete(message.toolCallId);\n return;\n }\n\n if (message.type === \"tool.approval_required\") {\n for (const ref of message.toolCalls) {\n bucket.pendingApprovals.set(ref.id, { id: ref.id });\n }\n return;\n }\n\n if (message.type === \"tool.response_required\") {\n for (const ref of message.toolCalls) {\n const resolved = resolveAskUserQuestionFromBucket(bucket, ref);\n bucket.pendingResponses.set(ref.id, {\n id: ref.id,\n sourceEventId: ref.sourceEventId,\n ...(resolved?.question != null ? { question: resolved.question } : {}),\n ...(resolved?.options != null ? { options: resolved.options } : {}),\n });\n }\n return;\n }\n\n if (message.type === \"thread.done\") {\n bucket.done = true;\n if (message.title) {\n bucket.title = message.title;\n }\n }\n}\n\nfunction isContentAffectingEvent(message: TurnStreamingEvent): boolean {\n return (\n message.type === \"thread.created\" ||\n message.type === \"thread.done\" ||\n message.type === \"model.message\" ||\n message.type === \"model.message.delta\" ||\n message.type === \"tool.response\" ||\n message.type === \"tool.approval_required\" ||\n message.type === \"tool.response_required\"\n );\n}\n\nexport function ingestStreamEvent(\n state: PeerThreadFoldState,\n message: TurnStreamingEvent,\n): boolean {\n if (message.type === \"mcp.auth_required\" || isTurnScopedEvent(message)) {\n return false;\n }\n\n if (message.threadId == null) {\n return false;\n }\n\n if (message.type === \"thread.created\") {\n state.threadParents.set(message.threadId, {\n parentThreadId: message.parent.threadId,\n toolCallId: message.parent.toolCallId,\n });\n const bucket = state.getOrCreateBucket(message.threadId);\n bucket.title = message.title;\n bucket.agentInfo = message.agentInfo;\n return true;\n }\n\n if (message.type === \"model.message\" && message.threadId === ROOT_THREAD_ID) {\n assertRootThreadEvent(message.threadId, message.type);\n }\n\n const bucket = state.getOrCreateBucket(message.threadId);\n ingestEventIntoBucket(bucket, message);\n\n return isContentAffectingEvent(message);\n}\n\nexport function ingestTurnEvent(state: PeerThreadFoldState, event: TurnEvent): void {\n if (event.threadId == null) {\n return;\n }\n\n if (event.type === \"thread.created\") {\n state.threadParents.set(event.threadId, {\n parentThreadId: event.parent.threadId,\n toolCallId: event.parent.toolCallId,\n });\n const bucket = state.getOrCreateBucket(event.threadId);\n bucket.title = event.title;\n bucket.agentInfo = event.agentInfo;\n } else if (event.type === \"model.message\" && event.threadId === ROOT_THREAD_ID) {\n assertRootThreadEvent(event.threadId, event.type);\n }\n\n ingestEventIntoBucket(state.getOrCreateBucket(event.threadId), event);\n}\n\nfunction resolveAskUserQuestionFromBucket(\n bucket: ThreadBucket,\n ref: Pick<ToolCallRef, \"id\" | \"sourceEventId\">,\n): { question?: string; options?: string[] } | undefined {\n const modelMessage = bucket.events.get(ref.sourceEventId);\n if (modelMessage?.type !== \"model.message\") {\n return undefined;\n }\n const toolCall = modelMessage.toolCalls?.find((call) => call.id === ref.id);\n if (toolCall == null) {\n return undefined;\n }\n return parseAskUserQuestionArgs(toolCall.function.arguments);\n}\n\nfunction findToolCallInBucket(\n bucket: ThreadBucket,\n toolCallId: string,\n): SdkToolCall | undefined {\n for (const id of bucket.modelMessageIds) {\n const event = bucket.events.get(id);\n if (event?.type !== \"model.message\") {\n continue;\n }\n const match = event.toolCalls?.find((toolCall) => toolCall.id === toolCallId);\n if (match != null) {\n return match;\n }\n }\n return undefined;\n}\n\nfunction isLinkedCreateSubAgentThread(\n state: PeerThreadFoldState,\n subThreadId: string,\n): boolean {\n const link = state.threadParents.get(subThreadId);\n if (link == null) {\n return false;\n }\n const parentBucket = state.threads.get(link.parentThreadId);\n if (parentBucket == null) {\n return false;\n }\n const toolCall = findToolCallInBucket(parentBucket, link.toolCallId);\n return toolCall != null && isCreateSubAgentToolCall(toolCall);\n}\n\nfunction childSubThreadIds(\n state: PeerThreadFoldState,\n parentThreadId: string,\n toolCallId: string,\n): string[] {\n const ids: string[] = [];\n for (const [subThreadId, link] of state.threadParents) {\n if (\n link.parentThreadId === parentThreadId &&\n link.toolCallId === toolCallId &&\n isLinkedCreateSubAgentThread(state, subThreadId)\n ) {\n ids.push(subThreadId);\n }\n }\n return ids;\n}\n\nfunction bucketHasUnresolvedPendingResponses(bucket: ThreadBucket): boolean {\n for (const id of bucket.pendingResponses.keys()) {\n if (!bucket.toolResults.has(id)) {\n return true;\n }\n }\n return false;\n}\n\nfunction bucketAssistantStatus(bucket: ThreadBucket): MessageStatus {\n if (bucket.pendingApprovals.size > 0) {\n return toolApprovalStatus();\n }\n if (bucketHasUnresolvedPendingResponses(bucket)) {\n return toolResponseStatus();\n }\n if (!bucket.done && bucket.modelMessageIds.length > 0) {\n return { type: \"running\" };\n }\n return { type: \"complete\", reason: \"stop\" };\n}\n\nfunction buildSubAgentCustomMetadata(\n threadId: string,\n bucket: ThreadBucket,\n): SubAgentMessageCustomMetadata {\n const metadata: SubAgentCustomMetadata = {\n threadId,\n ...(bucket.title != null ? { title: bucket.title } : {}),\n ...(bucket.agentInfo?.name != null ? { name: bucket.agentInfo.name } : {}),\n ...(bucket.agentInfo?.model != null ? { model: bucket.agentInfo.model } : {}),\n ...(bucket.agentInfo?.input != null ? { input: bucket.agentInfo.input } : {}),\n };\n return { subAgent: metadata };\n}\n\nfunction attachSubAgentMessages(\n state: PeerThreadFoldState,\n parentThreadId: string,\n parts: AssistantContentPart[],\n): AssistantContentPart[] {\n const parentBucket = state.threads.get(parentThreadId);\n\n return parts.map((part) => {\n if (part.type !== \"tool-call\" || parentBucket == null) {\n return part;\n }\n\n const sdkToolCall = findToolCallInBucket(parentBucket, part.toolCallId);\n if (sdkToolCall == null || !isCreateSubAgentToolCall(sdkToolCall)) {\n return part;\n }\n\n const childIds = childSubThreadIds(state, parentThreadId, part.toolCallId);\n if (childIds.length === 0) {\n return part;\n }\n\n const messages: ThreadMessage[] = [];\n const subAgents: SubAgentArtifact[\"subAgents\"] = [];\n for (const childId of childIds) {\n const childMessages = buildSubThreadMessages(state, childId);\n if (childMessages.length > 0) {\n messages.push(...childMessages);\n }\n const childBucket = state.threads.get(childId);\n if (childBucket != null) {\n subAgents.push({\n threadId: childId,\n ...(childBucket.title != null ? { title: childBucket.title } : {}),\n ...(childBucket.agentInfo != null\n ? { agentInfo: childBucket.agentInfo }\n : {}),\n });\n }\n }\n if (messages.length === 0 && subAgents.length === 0) {\n return part;\n }\n\n const artifact: SubAgentArtifact = { subAgents };\n // thread.created (title, agentInfo) arrives before the child's first model.message.\n // Attach artifact-only so UI can render the sub-agent header immediately; see README\n // SubAgentArtifact / MessagePartPrimitive.Messages in agent-ui ToolCallContainer.\n if (messages.length === 0) {\n return { ...part, artifact };\n }\n return { ...part, messages, artifact };\n });\n}\n\nfunction buildThreadAssistantParts(\n state: PeerThreadFoldState,\n threadId: string,\n modelMessageIds?: readonly string[],\n): AssistantContentPart[] {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return [];\n }\n\n const ids =\n threadId === ROOT_THREAD_ID && modelMessageIds != null\n ? modelMessageIds\n : bucket.modelMessageIds;\n\n const parts: AssistantContentPart[] = [];\n // A single tool call can appear in more than one `model.message` event (e.g.\n // once in the paused turn and again in the resumed turn after a tool\n // approval). assistant-ui keys tool parts by `toolCallId` within a message,\n // so emitting the same id twice crashes the render. Collapse duplicates,\n // letting the latest occurrence win while preserving the original position.\n const toolCallIndexById = new Map<string, number>();\n for (const id of ids) {\n const event = bucket.events.get(id);\n if (event?.type !== \"model.message\") {\n continue;\n }\n for (const part of buildAssistantContent(event, {\n toolResults: bucket.toolResults,\n pendingApprovals: bucket.pendingApprovals,\n approvalDecisions: bucket.approvalDecisions,\n pendingResponses: bucket.pendingResponses,\n })) {\n if (part.type === \"tool-call\") {\n const existingIndex = toolCallIndexById.get(part.toolCallId);\n if (existingIndex != null) {\n parts[existingIndex] = part;\n continue;\n }\n toolCallIndexById.set(part.toolCallId, parts.length);\n }\n parts.push(part);\n }\n }\n\n return attachSubAgentMessages(state, threadId, parts);\n}\n\nfunction buildSubThreadMessages(\n state: PeerThreadFoldState,\n threadId: string,\n): ThreadMessage[] {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return [];\n }\n\n const content = buildThreadAssistantParts(state, threadId);\n if (content.length === 0) {\n return [];\n }\n\n const custom = {\n ...buildSubAgentCustomMetadata(threadId, bucket),\n ...(bucket.pendingApprovals.size > 0\n ? toolApprovalMessageCustom(threadId)\n : {}),\n ...(bucketHasUnresolvedPendingResponses(bucket)\n ? toolResponseMessageCustom(threadId)\n : {}),\n };\n\n return [\n {\n id: `${threadId}-assistant`,\n role: \"assistant\",\n content,\n status: bucketAssistantStatus(bucket),\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom,\n },\n },\n ];\n}\n\nexport function buildRootAssistantContent(\n state: PeerThreadFoldState,\n): AssistantContentPart[] {\n return buildThreadAssistantParts(state, ROOT_THREAD_ID);\n}\n\nexport function buildRootAssistantContentForIds(\n state: PeerThreadFoldState,\n modelMessageIds: readonly string[],\n): AssistantContentPart[] {\n return buildThreadAssistantParts(state, ROOT_THREAD_ID, modelMessageIds);\n}\n\nexport function findFirstPendingApprovalThreadId(\n state: PeerThreadFoldState,\n): string | undefined {\n for (const [threadId, bucket] of state.threads) {\n if (bucket.pendingApprovals.size > 0) {\n return threadId;\n }\n }\n return undefined;\n}\n\nexport function findFirstPendingResponseThreadId(\n state: PeerThreadFoldState,\n): string | undefined {\n for (const [threadId, bucket] of state.threads) {\n if (bucketHasUnresolvedPendingResponses(bucket)) {\n return threadId;\n }\n }\n return undefined;\n}\n\nexport function resolveAskUserQuestion(\n state: PeerThreadFoldState,\n threadId: string,\n ref: Pick<ToolCallRef, \"id\" | \"sourceEventId\">,\n): { question?: string; options?: string[] } | undefined {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return undefined;\n }\n return resolveAskUserQuestionFromBucket(bucket, ref);\n}\n\nexport function isRootThreadId(threadId: string | undefined): boolean {\n return threadId === ROOT_THREAD_ID;\n}\n\nexport function recordToolApprovalInFold(\n fold: PeerThreadFoldState,\n decision: { toolCallId: string; approved: boolean; reason?: string },\n): void {\n const record: ApprovalDecisionRef = {\n id: decision.toolCallId,\n approved: decision.approved,\n ...(decision.reason != null ? { reason: decision.reason } : {}),\n };\n let applied = false;\n for (const bucket of fold.threads.values()) {\n if (!bucket.pendingApprovals.has(decision.toolCallId)) {\n continue;\n }\n bucket.pendingApprovals.delete(decision.toolCallId);\n bucket.approvalDecisions.set(decision.toolCallId, record);\n applied = true;\n }\n if (applied) {\n return;\n }\n const rootBucket = fold.getOrCreateBucket(ROOT_THREAD_ID);\n rootBucket.approvalDecisions.set(decision.toolCallId, record);\n}\n\n/** Persist a user.tool_response answer into fold state (clears pending ask-user). */\nexport function recordToolResponseInFold(\n fold: PeerThreadFoldState,\n response: { toolCallId: string; content: string },\n): void {\n let applied = false;\n for (const bucket of fold.threads.values()) {\n if (!bucket.pendingResponses.has(response.toolCallId)) {\n continue;\n }\n bucket.toolResults.set(response.toolCallId, response.content);\n bucket.pendingResponses.delete(response.toolCallId);\n applied = true;\n }\n if (applied) {\n return;\n }\n const rootBucket = fold.getOrCreateBucket(ROOT_THREAD_ID);\n rootBucket.toolResults.set(response.toolCallId, response.content);\n rootBucket.pendingResponses.delete(response.toolCallId);\n}\n","import type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadAssistantMessagePart,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type {\n ToolResponseRequiredEvent,\n Turn,\n TurnInputItem,\n UserToolResponseEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n recordToolApprovalInFold,\n recordToolResponseInFold,\n type PeerThreadFoldState,\n} from \"./foldPeerThreads.js\";\nimport type { ToolResponseMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\nexport const TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY = \"toolResponseThreadId\";\n\nexport type AskUserQuestionInterruptPayload = {\n question?: string;\n options?: string[];\n};\n\nexport type StoredToolResponse = Pick<UserToolResponseEvent, \"content\">;\n\nexport type RespondToToolResponseOptions = Pick<\n UserToolResponseEvent,\n \"toolCallId\" | \"content\"\n>;\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\ntype AssistantToolCallPart = Extract<\n ThreadAssistantMessagePart,\n { type: \"tool-call\" }\n>;\n\nexport function hasPendingToolResponse(\n part: Pick<ToolCallPart, \"interrupt\" | \"result\">,\n): boolean {\n return part.interrupt != null && part.result === undefined;\n}\n\nfunction isStagedResponseAwaitingSdk(part: ToolCallPart): boolean {\n return part.interrupt != null && part.result !== undefined;\n}\n\nexport function toolResponseStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"tool-calls\" };\n}\n\nexport function toolResponseMessageCustom(\n threadId: string,\n): ToolResponseMessageCustomMetadata {\n return {\n [TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY]:\n threadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : threadId,\n };\n}\n\nexport function getToolResponseThreadId(\n message: ThreadMessage | undefined,\n): string | undefined {\n if (message?.role !== \"assistant\") {\n return undefined;\n }\n const threadId = message.metadata.custom[TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY];\n return typeof threadId === \"string\" ? threadId : undefined;\n}\n\nexport function findResponseRequiredInTurn(\n turn: Pick<Turn, \"state\">,\n): ToolResponseRequiredEvent | undefined {\n if (turn.state.status !== \"done\") {\n return undefined;\n }\n const found = turn.state.requiredActions?.find(\n (action) => action.type === \"tool.response_required\",\n );\n return found?.type === \"tool.response_required\" ? found : undefined;\n}\n\nfunction applyToolResponseToToolCall(\n part: AssistantToolCallPart,\n content: string,\n): AssistantToolCallPart {\n return { ...part, result: content };\n}\n\nfunction updateToolResponseInContent(\n content: readonly ThreadAssistantMessagePart[],\n options: RespondToToolResponseOptions,\n): { content: readonly ThreadAssistantMessagePart[]; found: boolean } {\n let found = false;\n const newContent = content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n if (part.toolCallId === options.toolCallId && hasPendingToolResponse(part)) {\n found = true;\n return applyToolResponseToToolCall(part, options.content);\n }\n\n if (part.messages == null) {\n return part;\n }\n\n const messages = part.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n const nested = updateToolResponseInContent(message.content, options);\n if (!nested.found) {\n return message;\n }\n found = true;\n return { ...message, content: nested.content };\n });\n return { ...part, messages };\n });\n\n return { content: newContent, found };\n}\n\nexport function applyToolResponseToMessage(\n message: ThreadAssistantMessage,\n options: RespondToToolResponseOptions,\n): ThreadAssistantMessage {\n const { content } = updateToolResponseInContent(message.content, options);\n return { ...message, content: [...content] };\n}\n\nfunction nestedMessagesHavePendingResponses(\n messages: readonly ThreadMessage[],\n): boolean {\n for (const message of messages) {\n if (messageHasPendingResponses(message)) {\n return true;\n }\n }\n return false;\n}\n\nexport function messageHasPendingResponses(message: ThreadMessage | undefined): boolean {\n if (message?.role !== \"assistant\") {\n return false;\n }\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (hasPendingToolResponse(part)) {\n return true;\n }\n if (part.messages != null && nestedMessagesHavePendingResponses(part.messages)) {\n return true;\n }\n }\n return false;\n}\n\nfunction collectResponseInputsFromMessages(\n messages: readonly ThreadMessage[],\n defaultThreadId: string,\n): UserToolResponseEvent[] {\n const events: UserToolResponseEvent[] = [];\n for (const message of messages) {\n events.push(...collectResponseInputs(message, defaultThreadId));\n }\n return events;\n}\n\nexport function collectResponseInputs(\n message: ThreadMessage,\n threadId: string,\n): UserToolResponseEvent[] {\n if (message.role !== \"assistant\" || !threadId) {\n return [];\n }\n if (messageHasPendingResponses(message)) {\n return [];\n }\n\n const scopedThreadId = getToolResponseThreadId(message) ?? threadId;\n const events: UserToolResponseEvent[] = [];\n\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (isStagedResponseAwaitingSdk(part)) {\n events.push({\n type: \"user.tool_response\",\n threadId: scopedThreadId,\n toolCallId: part.toolCallId,\n content: String(part.result),\n });\n }\n if (part.messages != null) {\n events.push(\n ...collectResponseInputsFromMessages(part.messages, scopedThreadId),\n );\n }\n }\n return events;\n}\n\nfunction contentHasPendingResponses(\n content: readonly ThreadAssistantMessagePart[],\n): boolean {\n return messageHasPendingResponses({\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n });\n}\n\nexport function resolveToolResponseUpdate(update: TurnStreamUpdate): TurnStreamUpdate {\n if (\n contentHasPendingResponses(update.content) ||\n update.status?.type !== \"requires-action\" ||\n update.status.reason !== \"tool-calls\"\n ) {\n return update;\n }\n\n const { status: _status, metadata: _metadata, ...rest } = update;\n return rest;\n}\n\nfunction walkAssistantToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: AssistantToolCallPart) => void,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role === \"assistant\") {\n walkAssistantToolCallParts(message.content, visit);\n }\n }\n }\n}\n\nfunction collectStagedResponsesFromContent(\n content: readonly ThreadAssistantMessagePart[],\n): Map<string, string> {\n const staged = new Map<string, string>();\n walkAssistantToolCallParts(content, (part) => {\n if (isStagedResponseAwaitingSdk(part)) {\n staged.set(part.toolCallId, String(part.result));\n }\n });\n return staged;\n}\n\nfunction applyStagedResponsesToContentMap(\n content: readonly ThreadAssistantMessagePart[],\n staged: ReadonlyMap<string, string>,\n): ThreadAssistantMessagePart[] {\n return content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n const contentValue = staged.get(part.toolCallId);\n let nextPart: AssistantToolCallPart = part;\n if (contentValue != null && hasPendingToolResponse(part)) {\n nextPart = applyToolResponseToToolCall(part, contentValue);\n }\n\n if (nextPart.messages == null) {\n return nextPart;\n }\n\n return {\n ...nextPart,\n messages: nextPart.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyStagedResponsesToContentMap(message.content, staged),\n };\n }),\n };\n });\n}\n\nexport function mergeStagedResponsesIntoContent(\n incoming: readonly ThreadAssistantMessagePart[],\n existing: readonly ThreadAssistantMessagePart[],\n): ThreadAssistantMessagePart[] {\n const staged = collectStagedResponsesFromContent(existing);\n if (staged.size === 0) {\n return [...incoming];\n }\n return applyStagedResponsesToContentMap(incoming, staged);\n}\n\nexport function extractToolResponsesFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): UserToolResponseEvent[] {\n const events: UserToolResponseEvent[] = [];\n for (const item of input ?? []) {\n if (item.type === \"user.tool_response\") {\n events.push(item);\n }\n }\n return events;\n}\n\nexport function applyUserToolResponsesToFold(\n fold: PeerThreadFoldState,\n inputs: readonly TurnInputItem[],\n): void {\n for (const item of inputs) {\n if (item.type === \"user.tool_response\") {\n recordToolResponseInFold(fold, {\n toolCallId: item.toolCallId,\n content: item.content,\n });\n } else if (item.type === \"user.tool_approval\") {\n recordToolApprovalInFold(fold, {\n toolCallId: item.toolCallId,\n approved: item.approval.status === \"allow\",\n ...(item.approval.status === \"deny\" && item.approval.reason != null\n ? { reason: item.approval.reason }\n : {}),\n });\n }\n }\n}\n\nexport function collectSubsequentToolResponses(\n turns: readonly Pick<Turn, \"input\">[],\n fromIndex: number,\n): Map<string, StoredToolResponse> {\n const responses = new Map<string, StoredToolResponse>();\n\n for (let index = fromIndex + 1; index < turns.length; index++) {\n const input = turns[index]?.input ?? [];\n if (input.some((item) => item.type === \"user.message\")) {\n break;\n }\n\n for (const event of extractToolResponsesFromTurnInput(input)) {\n responses.set(event.toolCallId, { content: event.content });\n }\n }\n\n return responses;\n}\n\nexport function collectToolResponsesFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): Map<string, StoredToolResponse> {\n const responses = new Map<string, StoredToolResponse>();\n for (const event of extractToolResponsesFromTurnInput(input)) {\n responses.set(event.toolCallId, { content: event.content });\n }\n return responses;\n}\n\nfunction applyStagedResponsesToMessages(\n messages: readonly ThreadMessage[],\n responses: ReadonlyMap<string, StoredToolResponse>,\n): ThreadMessage[] {\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyStagedResponsesToContentMap(\n message.content,\n new Map(\n [...responses.entries()].map(([toolCallId, value]) => [\n toolCallId,\n value.content,\n ]),\n ),\n ),\n };\n });\n}\n\nexport function applyStagedResponsesToContent(\n content: readonly ThreadAssistantMessagePart[],\n responses: ReadonlyMap<string, StoredToolResponse>,\n): ThreadAssistantMessagePart[] {\n const staged = new Map(\n [...responses.entries()].map(([toolCallId, value]) => [\n toolCallId,\n value.content,\n ]),\n );\n return applyStagedResponsesToContentMap(content, staged);\n}\n","import type { ThreadAssistantMessagePart, ThreadMessage } from \"@assistant-ui/core\";\nimport type { McpAuthRequiredEvent } from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n getToolApprovalThreadId,\n hasPendingToolApproval,\n} from \"./toolApproval.js\";\nimport {\n getToolResponseThreadId,\n hasPendingToolResponse,\n type AskUserQuestionInterruptPayload,\n} from \"./toolResponse.js\";\n\nexport type PendingApproval = {\n approvalId: string;\n threadId: string;\n toolName: string;\n args: Record<string, unknown>;\n argsText: string;\n};\n\nexport type PendingToolResponse = {\n toolCallId: string;\n threadId: string;\n toolName: string;\n args: Record<string, unknown>;\n argsText: string;\n question?: string;\n options?: string[];\n};\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\nfunction walkToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: ToolCallPart, threadId: string) => void,\n threadId: string,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part, threadId);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const nestedThreadId =\n getToolApprovalThreadId(message) ??\n getToolResponseThreadId(message) ??\n threadId;\n walkToolCallParts(message.content, visit, nestedThreadId);\n }\n }\n}\n\nexport function collectPendingApprovals(\n messages: readonly ThreadMessage[],\n): PendingApproval[] {\n const pending: PendingApproval[] = [];\n\n for (const message of messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const rootThreadId = getToolApprovalThreadId(message) ?? ROOT_THREAD_ID;\n walkToolCallParts(message.content, (part, threadId) => {\n if (!hasPendingToolApproval(part.approval)) {\n return;\n }\n pending.push({\n approvalId: part.approval!.id,\n threadId,\n toolName: part.toolName,\n args: { ...part.args },\n argsText: part.argsText,\n });\n }, rootThreadId);\n }\n\n return pending;\n}\n\nexport function collectPendingToolResponses(\n messages: readonly ThreadMessage[],\n): PendingToolResponse[] {\n const pending: PendingToolResponse[] = [];\n\n for (const message of messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const rootThreadId = getToolResponseThreadId(message) ?? ROOT_THREAD_ID;\n walkToolCallParts(message.content, (part, threadId) => {\n if (!hasPendingToolResponse(part)) {\n return;\n }\n const payload = part.interrupt?.payload as\n | AskUserQuestionInterruptPayload\n | undefined;\n pending.push({\n toolCallId: part.toolCallId,\n threadId,\n toolName: part.toolName,\n args: { ...part.args },\n argsText: part.argsText,\n ...(payload?.question != null ? { question: payload.question } : {}),\n ...(payload?.options != null ? { options: payload.options } : {}),\n });\n }, rootThreadId);\n }\n\n return pending;\n}\n\nexport function derivePendingMcpAuth(\n messages: readonly ThreadMessage[],\n): { mcpServers: McpAuthRequiredEvent[\"mcpServers\"] } | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message?.role !== \"assistant\") {\n continue;\n }\n if (message.status?.type !== \"requires-action\") {\n continue;\n }\n const custom = message.metadata.custom as TrueFoundryMessageCustomMetadata;\n if (custom.pendingMcpAuth !== true) {\n continue;\n }\n const servers = custom.mcpServers;\n if (!Array.isArray(servers)) {\n return { mcpServers: [] };\n }\n return { mcpServers: servers };\n }\n return null;\n}\n\n/**\n * Most recent `sandboxId` observed anywhere in the conversation, scanning backward.\n * Unlike `derivePendingMcpAuth`, this isn't gated on message status: once a sandbox\n * is created it stays valid for the rest of the session, not just the paused message.\n */\nexport function deriveSandboxId(messages: readonly ThreadMessage[]): string | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message?.role !== \"assistant\") {\n continue;\n }\n const custom = message.metadata.custom as TrueFoundryMessageCustomMetadata;\n if (typeof custom.sandboxId === \"string\") {\n return custom.sandboxId;\n }\n }\n return undefined;\n}\n","import type { ListResult } from \"./server/types.js\";\n\n/**\n * Drains all pages of a token-paginated list into a single array.\n * Newest-first APIs should reverse after calling this.\n */\nexport async function drainListPages<T>(\n fetchPage: (pageToken?: string) => Promise<ListResult<T>>,\n): Promise<T[]> {\n const items: T[] = [];\n let pageToken: string | undefined;\n for (;;) {\n const page = await fetchPage(pageToken);\n items.push(...page.data);\n if (page.nextPageToken == null || page.nextPageToken === \"\") {\n break;\n }\n pageToken = page.nextPageToken;\n }\n return items;\n}\n","import type { Turn } from \"./server/index.js\";\n\nexport function extractTurnUserText(input: Turn[\"input\"]): string {\n const parts: string[] = [];\n for (const item of input ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const { content } = item;\n if (typeof content === \"string\") {\n parts.push(content);\n continue;\n }\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n }\n }\n }\n return parts.join(\"\\n\").trim();\n}\n","import type { MessageStatus } from \"@assistant-ui/core\";\nimport type { McpAuthRequiredEvent, TurnStateDone } from \"./server/index.js\";\n\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport type { McpAuthMessageCustomMetadata } from \"./messageCustomMetadata.js\";\n\n/** `runConfig.custom` flag: resume after MCP OAuth with an empty SDK turn input. */\nexport const MCP_AUTH_RESUME_RUN_CUSTOM_KEY = \"resumeMcpAuth\";\n\ntype McpServerAuthInfo = McpAuthRequiredEvent[\"mcpServers\"][number];\n\nexport function buildMcpAuthTextParts(\n servers: readonly McpServerAuthInfo[],\n): AssistantContentPart[] {\n const linkLines = servers.map(\n (server) => `- [Authorize ${server.name}](${server.authUrl})`,\n );\n const text = [\n \"This agent needs access to external services before it can continue.\",\n \"\",\n ...linkLines,\n \"\",\n \"Open each link to sign in, then press **Continue** below.\",\n ].join(\"\\n\");\n return [{ type: \"text\", text }];\n}\n\nexport function findMcpAuthRequired(\n requiredActions: TurnStateDone[\"requiredActions\"] | undefined,\n): McpAuthRequiredEvent | undefined {\n const found = requiredActions?.find(\n (action) => action.type === \"mcp.auth_required\",\n );\n return found?.type === \"mcp.auth_required\"\n ? (found as McpAuthRequiredEvent)\n : undefined;\n}\n\nexport function mcpAuthAssistantStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"interrupt\" };\n}\n\nexport function mcpAuthMessageCustom(\n servers: readonly McpServerAuthInfo[],\n): McpAuthMessageCustomMetadata {\n return { pendingMcpAuth: true, mcpServers: [...servers] };\n}\n","import type { Turn } from \"./server/index.js\";\n\nimport {\n buildMcpAuthTextParts,\n findMcpAuthRequired,\n mcpAuthAssistantStatus,\n mcpAuthMessageCustom,\n} from \"./mcpAuth.js\";\nimport {\n findApprovalRequiredInTurn,\n toolApprovalMessageCustom,\n toolApprovalStatus,\n} from \"./toolApproval.js\";\nimport {\n findResponseRequiredInTurn,\n toolResponseMessageCustom,\n toolResponseStatus,\n} from \"./toolResponse.js\";\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nfunction buildToolApprovalUpdate(\n content: AssistantContentPart[],\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingApproval = findApprovalRequiredInTurn(turn);\n if (pendingApproval == null) {\n return { content };\n }\n return {\n content,\n status: toolApprovalStatus(),\n metadata: { custom: toolApprovalMessageCustom(pendingApproval.threadId) },\n };\n}\n\nfunction buildToolResponseUpdate(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingResponse = findResponseRequiredInTurn(turn);\n if (pendingResponse == null) {\n return update;\n }\n return {\n ...update,\n content: update.content,\n status: toolResponseStatus(),\n metadata: {\n custom: {\n ...update.metadata?.custom,\n ...toolResponseMessageCustom(pendingResponse.threadId),\n },\n },\n };\n}\n\nexport function appendToolResponseToTurnContent(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n if (update.status?.type === \"requires-action\") {\n return update;\n }\n return buildToolResponseUpdate(update, turn);\n}\n\nexport function appendToolApprovalToTurnContent(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n if (update.status?.type === \"requires-action\") {\n return update;\n }\n const approvalUpdate = buildToolApprovalUpdate(update.content, turn);\n return appendToolResponseToTurnContent(approvalUpdate, turn);\n}\n\nexport function appendMcpAuthToTurnContent(\n content: AssistantContentPart[],\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingMcpAuth = findMcpAuthRequired(\n turn.state.status === \"done\" ? turn.state.requiredActions : undefined,\n );\n if (pendingMcpAuth == null) {\n return appendToolApprovalToTurnContent({ content }, turn);\n }\n\n return appendToolApprovalToTurnContent(\n {\n content: [...content, ...buildMcpAuthTextParts(pendingMcpAuth.mcpServers)],\n status: mcpAuthAssistantStatus(),\n metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) },\n },\n turn,\n );\n}\n","import type {\n McpAuthRequiredEvent,\n Turn,\n TurnCreatedEvent,\n TurnDoneEvent,\n TurnEvent,\n TurnInputItem,\n} from \"./server/index.js\";\n\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport { PeerThreadFoldState } from \"./foldPeerThreads.js\";\nimport type { StoredApprovalDecision } from \"./toolApproval.js\";\nimport type { StoredToolResponse } from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\n/** Session-level event item from `AgentSession.listEvents`. */\nexport type GatewaySessionEventItem = {\n turnId: string;\n event: TurnCreatedEvent | TurnDoneEvent | TurnEvent;\n};\n\n/** Cursor for fetching older `listEvents` pages (scroll-up history). */\nexport type SessionHistoryPagination = {\n /** Token for the next older page; omit when exhausted. */\n olderPageToken?: string;\n hasOlder: boolean;\n};\n\n/** Turn metadata retained for cross-turn projection and subsequent required-action replay. */\nexport type SessionTurnRecord = Pick<\n Turn,\n \"id\" | \"createdAt\" | \"state\" | \"input\"\n> & {\n /** Denormalized from `input` for user/assistant interleaving during projection. */\n userText?: string;\n /** Root-thread `model.message` ids ingested with this turn (for per-group projection). */\n rootModelMessageIds?: readonly string[];\n /** sandboxId observed via a `sandbox.created` event during this turn (session-scoped, latest wins). */\n sandboxId?: string;\n};\n\nexport type RequiredActionsOverlay = {\n approvals: Map<string, StoredApprovalDecision>;\n toolResponses: Map<string, StoredToolResponse>;\n};\n\nexport type ActiveStreamState = {\n turnId: string;\n update: TurnStreamUpdate;\n isContinuation: boolean;\n streamComplete?: boolean;\n};\n\nexport type PendingUserMessage = {\n turnId: string;\n /** Gateway user.message content (text-only string or text/file parts). */\n content: Extract<TurnInputItem, { type: \"user.message\" }>[\"content\"];\n createdAt: Date;\n};\n\nexport type SessionSnapshot = {\n fold: PeerThreadFoldState;\n turns: SessionTurnRecord[];\n pendingMcpAuth?: McpAuthRequiredEvent;\n pendingUser?: PendingUserMessage;\n activeStream?: ActiveStreamState;\n /** Root `model.message` ids present before the active turn group started (streaming scope). */\n groupRootBaseline?: readonly string[];\n requiredActions: RequiredActionsOverlay;\n runningTurn?: Turn;\n unstable_resume?: boolean;\n /**\n * Chronological `listEvents` items loaded so far (for prepend-on-scroll rebuild).\n * Live stream commits are not appended here — they live in `turns` / `fold`.\n */\n historyEvents?: readonly GatewaySessionEventItem[];\n historyPagination?: SessionHistoryPagination;\n};\n\nexport type ProjectSessionMessagesOptions = {\n getCreatedAt?: (messageId: string, fallback: Date) => Date;\n};\n\nexport function emptyRequiredActionsOverlay(): RequiredActionsOverlay {\n return {\n approvals: new Map(),\n toolResponses: new Map(),\n };\n}\n\nexport function createEmptySessionSnapshot(): SessionSnapshot {\n return {\n fold: new PeerThreadFoldState(),\n turns: [],\n requiredActions: emptyRequiredActionsOverlay(),\n };\n}\n\nexport function turnToSessionRecord(turn: Turn): SessionTurnRecord {\n const userText = extractTurnUserText(turn.input);\n return {\n id: turn.id,\n ...(userText ? { userText } : {}),\n createdAt: turn.createdAt,\n state: turn.state,\n input: turn.input,\n };\n}\n\n/** Builds a SessionTurnRecord from session-level TurnCreatedEvent + TurnDoneEvent data. */\nexport function sessionEventsToSessionRecord(\n turnId: string,\n createdEvent: TurnCreatedEvent,\n doneEvent: TurnDoneEvent,\n rootModelMessageIds: readonly string[],\n sandboxId?: string,\n): SessionTurnRecord {\n const userText = extractTurnUserText(createdEvent.input);\n return {\n id: turnId,\n ...(userText ? { userText } : {}),\n createdAt: createdEvent.createdAt,\n state: doneEvent.state,\n input: createdEvent.input,\n rootModelMessageIds,\n ...(sandboxId != null ? { sandboxId } : {}),\n };\n}\n\n/** Returns a new snapshot wrapper; fold maps may be mutated in place before calling. */\nexport function replaceSessionSnapshot(\n snapshot: SessionSnapshot,\n patch: Partial<Omit<SessionSnapshot, \"requiredActions\">> & {\n requiredActions?: RequiredActionsOverlay;\n },\n): SessionSnapshot {\n return {\n ...snapshot,\n ...patch,\n ...(patch.requiredActions != null\n ? { requiredActions: patch.requiredActions }\n : {}),\n };\n}\n\nexport function cloneRequiredActionsOverlay(\n overlay: RequiredActionsOverlay,\n): RequiredActionsOverlay {\n return {\n approvals: new Map(overlay.approvals),\n toolResponses: new Map(overlay.toolResponses),\n };\n}\n","import type {\n AppendMessage,\n CompleteAttachment,\n ExportedMessageRepositoryItem,\n MessageStatus,\n ThreadMessage,\n ThreadUserMessagePart,\n} from \"@assistant-ui/core\";\nimport type {\n McpAuthRequiredEvent,\n Turn,\n TurnCreatedEvent,\n TurnDoneEvent,\n TurnEvent,\n TurnInputItem,\n TurnStreamData,\n} from \"./server/index.js\";\nimport type { AgentChatServer } from \"./server/types.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport { drainListPages } from \"./listPages.js\";\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport {\n buildRootAssistantContent,\n buildRootAssistantContentForIds,\n findFirstPendingApprovalThreadId,\n findFirstPendingResponseThreadId,\n ingestStreamEvent,\n ingestTurnEvent,\n PeerThreadFoldState,\n type ThreadBucket,\n} from \"./foldPeerThreads.js\";\nimport {\n appendMcpAuthToTurnContent,\n appendToolApprovalToTurnContent,\n} from \"./turnEventHelpers.js\";\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport {\n extractImageUrlFromUserContentItem,\n imageUrlToAttachment,\n} from \"./modelMessageImageContent.js\";\nimport {\n type SessionSnapshot,\n type ProjectSessionMessagesOptions,\n type SessionTurnRecord,\n type RequiredActionsOverlay,\n type GatewaySessionEventItem,\n type SessionHistoryPagination,\n createEmptySessionSnapshot,\n emptyRequiredActionsOverlay,\n replaceSessionSnapshot,\n sessionEventsToSessionRecord,\n turnToSessionRecord,\n} from \"./sessionSnapshot.js\";\nimport {\n applyApprovalDecisionsToContent,\n collectApprovalDecisionsFromTurnInput,\n collectSubsequentApprovalDecisions,\n messageHasPendingApprovals,\n TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY,\n toolApprovalMessageCustom,\n toolApprovalStatus,\n} from \"./toolApproval.js\";\nimport {\n applyStagedResponsesToContent,\n applyUserToolResponsesToFold,\n collectSubsequentToolResponses,\n collectToolResponsesFromTurnInput,\n messageHasPendingResponses,\n TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,\n toolResponseMessageCustom,\n toolResponseStatus,\n} from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\nimport {\n buildMcpAuthTextParts,\n mcpAuthAssistantStatus,\n mcpAuthMessageCustom,\n} from \"./mcpAuth.js\";\n\n/**\n * Turn / event → assistant-ui normalization\n *\n * This module is the projection layer: it turns gateway session state into\n * `ThreadMessage[]` for `@assistant-ui/core`. The hook in\n * `useTrueFoundryAgentMessages.ts` owns the mutable `SessionSnapshot`; this\n * file defines how that snapshot is built and rendered.\n *\n * ## Data model\n *\n * Gateway side:\n * - A **session** has ordered **turns** (each with `input`, `state`, `listEvents`).\n * - A turn's **input** is either a user message (`user.message`) or a continuation\n * (`user.tool_response`, `user.tool_approval`, …).\n * - **Events** (`model.message`, `tool.*`, `thread.created`, …) arrive on a\n * **thread id**; the root conversation uses `ROOT_THREAD_ID` (`\"main\"`).\n *\n * Local side (`SessionSnapshot` in `sessionSnapshot.ts`):\n * - `fold` — accumulated events across all threads (see `foldPeerThreads.ts`).\n * - `turns` — committed turn records, each optionally storing\n * `rootModelMessageIds` (root-thread `model.message` ids ingested with that turn).\n * - `pendingUser` / `activeStream` — optimistic UI while a turn is in flight.\n * - `groupRootBaseline` — root `model.message` ids that existed before the active\n * turn group started; used to scope live streaming to the current group only.\n * - `requiredActions` — locally staged approval/response decisions before resume.\n *\n * Output:\n * - Alternating **user** / **assistant** `ThreadMessage` pairs.\n * - One assistant message per **turn group** (user turn + its continuation turns).\n *\n * ## Turn groups\n *\n * A **turn group** starts at a turn whose input contains `user.message`. Later\n * turns with only continuation inputs (tool response, tool approval, MCP resume)\n * belong to the same group and are folded into the same assistant message.\n *\n * Root content for a group is the union of `rootModelMessageIds` on every turn\n * in that group. Prior groups must not leak in: scope with\n * `rootModelMessageIdsSinceBaseline(fold, baseline)` where\n * `baseline = groupRootBaseline ?? computeGroupRootBaseline(turns)`.\n *\n * ## Pipeline\n *\n * 1. **Ingest** — `ingestStreamEvent` / `ingestTurnEvent` append events into\n * per-thread buckets in `PeerThreadFoldState`. Deltas merge in place.\n *\n * 2. **Fold to content** — `buildRootAssistantContentForIds` walks scoped\n * `model.message` ids and emits assistant-ui parts (reasoning, text, tool-call).\n * Sub-agent child threads are attached under `create_sub_agent` tool-calls as\n * nested `messages` (see `attachSubAgentMessages` in `foldPeerThreads.ts`).\n *\n * 3. **History projection** — `projectHistoryTurns` walks committed `turns`:\n * - User turn → push user message; push assistant if the group has content.\n * - Continuation turn → merge assistant content into the last assistant message\n * in the group (same `*-assistant` id as the user turn that opened the group).\n * - Apply answers from later continuation turns onto earlier tool-calls via\n * `collectSubsequentApprovalDecisions` / `collectSubsequentToolResponses`.\n * - A paused group's assistant message keeps `requires-action` until a later\n * continuation turn resolves all its approvals/responses, then downgrades\n * to the turn-state status (`complete`, `error`, `cancelled`).\n *\n * 4. **Live projection** — `projectSessionMessages` = history + `pendingUser` +\n * `activeStream`. While streaming, `streamTurnEvents` yields content scoped to\n * `groupRootBaseline`. When `streamComplete`, `projectActiveStreamUpdate`\n * rebuilds from the fold (same baseline scoping as streaming).\n *\n * 5. **Staged overlay** — Before the SDK resume turn is sent, user decisions sit\n * in `requiredActions` and are merged onto messages by\n * `applyRequiredActionsOverlayToMessages` so the UI shows interrupt + result\n * together. Resume is batched: all pending approvals and ask-user answers in\n * a paused message must be resolved before `sendTurn({ inputs })`.\n *\n * ## Required actions (assistant-ui mapping)\n *\n * | Gateway event / input | assistant-ui representation |\n * |-----------------------------|------------------------------------------------------|\n * | `tool.approval_required` | `tool-call` with `approval: { id }`, status |\n * | | `requires-action` / `tool-calls`, custom thread id |\n * | `user.tool_approval` | closes `tool.approval_required`: sets `approval.approved` |\n * | | (+ optional reason) on tool-call |\n * | `tool.response_required` | `tool-call` with `interrupt: { type: \"human\", … }` |\n * | (ask_user_question) | payload parsed from tool args (`askUserQuestion.ts`) |\n * | `user.tool_response` | closes `tool.response_required`: sets `result` on |\n * | | tool-call and clears the pending `interrupt` |\n * | `mcp.auth_required` | Appended auth link text parts; status `interrupt` |\n *\n * Sub-agent threads can have their own pending approval/response; metadata\n * `toolApprovalThreadId` / `toolResponseThreadId` on nested assistant messages\n * scopes resume inputs to the correct thread.\n *\n * A sub-agent stays attached under the `create_sub_agent` tool-call that spawned\n * it, which lives in the root `model.message` of the turn that opened the group.\n * The child thread keeps producing events across several turns (spawn turn, then\n * continuation turns that answer its required actions), and all of them render\n * under that single tool-call in the group's one assistant message.\n *\n * INVARIANT — while a sub-agent is active the parent agent is paused awaiting a\n * required action, so every following turn until it finishes is a continuation\n * (`user.tool_response` / `user.tool_approval` / MCP resume), NOT a `user.message`.\n * If a sub-agent is spawned/active in turn 1, turn 2 cannot carry `user.message`\n * input. A `user.message` there would open a new turn group (`userText` boundary)\n * and split the still-running sub-agent's events away from its tool-call. The\n * gateway enforces this; the projection relies on it for correct nesting.\n *\n * ## Assumptions\n *\n * - Root-thread model messages use `threadId === ROOT_THREAD_ID`.\n * - Turn order in `snapshot.turns` matches gateway chronological order.\n * - `rootModelMessageIds` on committed turns is accurate (set in\n * `commitActiveStream` when a stream completes).\n * - Continuation turns never carry `user.message`; that boundary defines groups.\n * In particular, while a sub-agent (or any tool) is mid-flight awaiting a\n * required action, the next turn is always a continuation, never a new\n * `user.message`.\n * - Tool-call identity is stable via `toolCallId` across events, fold state, and\n * assistant-ui parts.\n * - Reload (`buildSnapshotFromSessionEvents`) and live paths must produce the same\n * per-group scoping; history uses cumulative `groupRootIds` per turn index,\n * live uses `groupRootBaseline`.\n */\n\nconst TURN_EVENTS_PAGE_SIZE = 25;\nconst SESSION_EVENTS_PAGE_SIZE = 100;\n/** Cap how many event pages initial load / load-older may chain for a group boundary. */\nconst MAX_HISTORY_BOUNDARY_PAGES = 10;\n\ntype FetchSessionEventsOptions = {\n /**\n * Newest turn in the listing window (initial load only). Lists that turn and\n * its ancestors. Omit to use the session last turn. Running-turn events are\n * excluded by the API — subscribe to that turn for live events.\n */\n lastTurnId?: string;\n};\n\ntype SessionEventsPageResult = {\n /** Newest-first items from this request. */\n itemsNewestFirst: GatewaySessionEventItem[];\n olderPageToken?: string;\n hasOlder: boolean;\n};\n\n/**\n * Drops a leading incomplete turn (events before the first `turn.created`) that\n * appears when a page boundary splits a turn.\n */\nfunction trimIncompleteLeadingEvents(\n itemsAsc: GatewaySessionEventItem[],\n): GatewaySessionEventItem[] {\n const start = itemsAsc.findIndex((item) => item.event.type === \"turn.created\");\n if (start === -1) {\n return [];\n }\n return itemsAsc.slice(start);\n}\n\n/**\n * Whether the oldest complete turn in a chronological window opens a user group.\n * `incomplete` means we still lack a finished oldest turn (need an older page).\n */\nfunction oldestCompleteTurnGroupState(\n itemsAsc: GatewaySessionEventItem[],\n): \"user-group\" | \"continuation\" | \"incomplete\" {\n const trimmed = trimIncompleteLeadingEvents(itemsAsc);\n if (trimmed.length === 0) {\n return \"incomplete\";\n }\n const created = trimmed[0];\n if (created?.event.type !== \"turn.created\") {\n return \"incomplete\";\n }\n const hasDone = trimmed.some(\n (item) => item.turnId === created.turnId && item.event.type === \"turn.done\",\n );\n if (!hasDone) {\n return \"incomplete\";\n }\n return extractTurnUserText(created.event.input) != null\n ? \"user-group\"\n : \"continuation\";\n}\n\nasync function fetchSessionEventsPage(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions & { pageToken?: string },\n): Promise<SessionEventsPageResult> {\n const page = await server.listEvents({\n sessionId,\n limit: SESSION_EVENTS_PAGE_SIZE,\n ...(options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}),\n ...(options?.pageToken != null ? { pageToken: options.pageToken } : {}),\n });\n const olderPageToken = page.nextPageToken;\n const hasOlder = olderPageToken != null && olderPageToken !== \"\";\n return {\n itemsNewestFirst: page.data as GatewaySessionEventItem[],\n ...(olderPageToken != null && olderPageToken !== \"\"\n ? { olderPageToken }\n : {}),\n hasOlder,\n };\n}\n\n/**\n * Fetches pages until the chronological window starts on a complete user-message\n * turn group (or history is exhausted).\n */\nasync function fetchSessionEventsWindow(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions & { pageToken?: string },\n): Promise<{\n itemsAsc: GatewaySessionEventItem[];\n olderPageToken?: string;\n hasOlder: boolean;\n}> {\n let itemsNewestFirst: GatewaySessionEventItem[] = [];\n let pageToken = options?.pageToken;\n let olderPageToken: string | undefined;\n let hasOlder = false;\n\n for (let pageCount = 0; pageCount < MAX_HISTORY_BOUNDARY_PAGES; pageCount++) {\n const page = await fetchSessionEventsPage(server, sessionId, {\n ...options,\n ...(pageToken != null ? { pageToken } : {}),\n });\n itemsNewestFirst = [...itemsNewestFirst, ...page.itemsNewestFirst];\n olderPageToken = page.olderPageToken;\n hasOlder = page.hasOlder;\n\n const itemsAsc = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());\n const groupState = oldestCompleteTurnGroupState(itemsAsc);\n if (groupState === \"user-group\" || !hasOlder) {\n return {\n itemsAsc,\n ...(olderPageToken != null ? { olderPageToken } : {}),\n hasOlder,\n };\n }\n\n if (olderPageToken == null) {\n return { itemsAsc, hasOlder: false };\n }\n pageToken = olderPageToken;\n }\n\n const itemsAsc = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());\n return {\n itemsAsc,\n ...(olderPageToken != null ? { olderPageToken } : {}),\n hasOlder,\n };\n}\n\n/**\n * Fetches session-level events via `server.listEvents()`. The API returns pages\n * in desc order (newest first); the collected array is reversed before returning\n * so callers receive events in chronological (asc) order.\n *\n * Used by rewind/edit paths that need the full ancestor window.\n */\nasync function fetchAllSessionEvents(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions,\n): Promise<GatewaySessionEventItem[]> {\n const items = await drainListPages((pageToken) =>\n server.listEvents({\n sessionId,\n limit: SESSION_EVENTS_PAGE_SIZE,\n ...(options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}),\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n items.reverse();\n return items as GatewaySessionEventItem[];\n}\n\nfunction cloneThreadBucket(bucket: ThreadBucket): ThreadBucket {\n return {\n events: new Map(bucket.events),\n modelMessageIds: [...bucket.modelMessageIds],\n toolResults: new Map(bucket.toolResults),\n pendingApprovals: new Map(bucket.pendingApprovals),\n approvalDecisions: new Map(bucket.approvalDecisions),\n pendingResponses: new Map(bucket.pendingResponses),\n done: bucket.done,\n ...(bucket.title != null ? { title: bucket.title } : {}),\n ...(bucket.agentInfo != null ? { agentInfo: bucket.agentInfo } : {}),\n };\n}\n\n/** Prepends older fold state ahead of the currently loaded fold (scroll-up). */\nexport function prependFoldState(\n older: PeerThreadFoldState,\n newer: PeerThreadFoldState,\n): PeerThreadFoldState {\n const result = new PeerThreadFoldState();\n const threadIds = new Set([...older.threads.keys(), ...newer.threads.keys()]);\n for (const threadId of threadIds) {\n const olderBucket = older.threads.get(threadId);\n const newerBucket = newer.threads.get(threadId);\n if (olderBucket == null && newerBucket != null) {\n result.threads.set(threadId, cloneThreadBucket(newerBucket));\n continue;\n }\n if (newerBucket == null && olderBucket != null) {\n result.threads.set(threadId, cloneThreadBucket(olderBucket));\n continue;\n }\n if (olderBucket == null || newerBucket == null) {\n continue;\n }\n result.threads.set(threadId, {\n events: new Map([...olderBucket.events, ...newerBucket.events]),\n modelMessageIds: [\n ...olderBucket.modelMessageIds,\n ...newerBucket.modelMessageIds,\n ],\n toolResults: new Map([\n ...olderBucket.toolResults,\n ...newerBucket.toolResults,\n ]),\n pendingApprovals: new Map([\n ...olderBucket.pendingApprovals,\n ...newerBucket.pendingApprovals,\n ]),\n approvalDecisions: new Map([\n ...olderBucket.approvalDecisions,\n ...newerBucket.approvalDecisions,\n ]),\n pendingResponses: new Map([\n ...olderBucket.pendingResponses,\n ...newerBucket.pendingResponses,\n ]),\n done: newerBucket.done || olderBucket.done,\n ...(newerBucket.title != null || olderBucket.title != null\n ? { title: newerBucket.title ?? olderBucket.title }\n : {}),\n ...(newerBucket.agentInfo != null || olderBucket.agentInfo != null\n ? { agentInfo: newerBucket.agentInfo ?? olderBucket.agentInfo }\n : {}),\n });\n }\n for (const [threadId, link] of older.threadParents) {\n result.threadParents.set(threadId, link);\n }\n for (const [threadId, link] of newer.threadParents) {\n result.threadParents.set(threadId, link);\n }\n return result;\n}\n\n/**\n * Ingests a chronologically ordered list of session-level event items into the\n * snapshot. `turn.created` marks the start of a turn (provides user input),\n * content events are folded as usual, and `turn.done` finalises the turn record\n * and pushes it to `snapshot.turns`.\n *\n * `onTurnComplete` is called after each `turn.done` with the partially-built\n * snapshot so callers can update UI progressively. The fold state is correct at\n * that point for every turn up to and including the just-completed one.\n */\nfunction ingestSessionEventsIntoSnapshot(\n snapshot: SessionSnapshot,\n items: GatewaySessionEventItem[],\n onTurnComplete?: (snap: SessionSnapshot) => void,\n): void {\n let currentTurnId: string | null = null;\n let currentCreatedEvent: TurnCreatedEvent | null = null;\n let currentContentEvents: TurnEvent[] = [];\n let beforeCount = 0;\n\n for (const item of items) {\n const { turnId, event } = item;\n\n if (event.type === \"turn.created\") {\n currentTurnId = turnId;\n currentCreatedEvent = event;\n currentContentEvents = [];\n beforeCount =\n snapshot.fold.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;\n } else if (event.type === \"turn.done\") {\n if (currentTurnId == null || currentCreatedEvent == null) {\n continue;\n }\n\n const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(\n beforeCount,\n );\n\n const sandboxEvent = currentContentEvents.find(\n (ev): ev is Extract<TurnEvent, { type: \"sandbox.created\" }> =>\n ev.type === \"sandbox.created\",\n );\n\n applyUserToolResponsesToFold(\n snapshot.fold,\n currentCreatedEvent.input ?? [],\n );\n snapshot.turns.push(\n sessionEventsToSessionRecord(\n currentTurnId,\n currentCreatedEvent,\n event,\n rootModelMessageIds,\n sandboxEvent?.sandboxId,\n ),\n );\n\n // Pass a new object reference so React's Object.is check in\n // useState sees a changed value and schedules a re-render.\n // The snapshot is mutated in place throughout this loop, so\n // passing `snapshot` directly would make every tick look identical\n // to React after the first setSnapshot call.\n onTurnComplete?.(replaceSessionSnapshot(snapshot, {}));\n\n currentTurnId = null;\n currentCreatedEvent = null;\n currentContentEvents = [];\n } else {\n if (currentTurnId != null) {\n ingestTurnEvent(snapshot.fold, event as TurnEvent);\n currentContentEvents.push(event as TurnEvent);\n }\n }\n }\n}\n\nfunction attachRunningTurn(\n snapshot: SessionSnapshot,\n runningTurn: Turn | undefined,\n): SessionSnapshot {\n if (runningTurn == null) {\n return snapshot;\n }\n // Session-level history excludes the running turn. Apply continuation inputs\n // from the turn listing so answered approvals / ask-user prompts are not\n // restored as pending while reconnecting to that turn after a refresh.\n applyUserToolResponsesToFold(snapshot.fold, runningTurn.input ?? []);\n const pendingUserText = extractTurnUserText(runningTurn.input);\n return replaceSessionSnapshot(snapshot, {\n runningTurn,\n unstable_resume: true as const,\n groupRootBaseline: computeGroupRootBaseline(snapshot.turns),\n ...(pendingUserText\n ? {\n pendingUser: {\n turnId: runningTurn.id,\n content: extractTurnUserMessageContent(runningTurn.input),\n createdAt: new Date(runningTurn.createdAt),\n },\n }\n : {}),\n });\n}\n\n/**\n * Builds a session snapshot using the session-level `listEvents` API.\n *\n * Loads the newest event page (extending only when a page boundary splits a\n * turn group), then leaves older pages for `prependOlderSessionHistory`.\n * Only `listTurns({ limit: 1 })` is called first to detect a currently-running\n * turn (the session-level API does not return events for the running turn).\n *\n * `onProgress` is called after each complete turn is ingested so callers can\n * update the UI progressively while the processing loop runs.\n */\nexport async function buildSnapshotFromSessionEvents(\n server: AgentChatServer,\n sessionId: string,\n onProgress?: (snap: SessionSnapshot) => void,\n): Promise<SessionSnapshot> {\n // Detect a running turn with a single listTurns page — do not drain pagination.\n const turnsPage = await server.listTurns({ sessionId, limit: 1 });\n const newestTurn = turnsPage.data[0] as Turn | undefined;\n const runningTurn =\n newestTurn?.state?.status === \"running\" ? newestTurn : undefined;\n\n const window = await fetchSessionEventsWindow(server, sessionId);\n const historyPagination: SessionHistoryPagination = {\n hasOlder: window.hasOlder,\n ...(window.olderPageToken != null\n ? { olderPageToken: window.olderPageToken }\n : {}),\n };\n\n const snapshot = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(snapshot, window.itemsAsc, onProgress);\n\n const withHistory = replaceSessionSnapshot(snapshot, {\n historyEvents: window.itemsAsc,\n historyPagination,\n });\n\n return attachRunningTurn(withHistory, runningTurn);\n}\n\n/**\n * Fetches the next older `listEvents` window and prepends it onto `snapshot`\n * without tearing down live stream / pending UI state.\n */\nexport async function prependOlderSessionHistory(\n server: AgentChatServer,\n sessionId: string,\n snapshot: SessionSnapshot,\n): Promise<SessionSnapshot> {\n const pagination = snapshot.historyPagination;\n if (pagination?.hasOlder !== true || pagination.olderPageToken == null) {\n return snapshot;\n }\n\n const window = await fetchSessionEventsWindow(server, sessionId, {\n pageToken: pagination.olderPageToken,\n });\n if (window.itemsAsc.length === 0) {\n return replaceSessionSnapshot(snapshot, {\n historyPagination: { hasOlder: false },\n });\n }\n\n const olderSnap = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(olderSnap, window.itemsAsc);\n\n const existingIds = new Set(snapshot.turns.map((turn) => turn.id));\n const olderTurns = olderSnap.turns.filter((turn) => !existingIds.has(turn.id));\n const mergedFold = prependFoldState(olderSnap.fold, snapshot.fold);\n const historyEvents = [\n ...window.itemsAsc,\n ...(snapshot.historyEvents ?? []),\n ];\n const olderRootIds = olderTurns.flatMap(\n (turn) => turn.rootModelMessageIds ?? [],\n );\n\n return replaceSessionSnapshot(snapshot, {\n fold: mergedFold,\n turns: [...olderTurns, ...snapshot.turns],\n historyEvents,\n historyPagination: {\n hasOlder: window.hasOlder,\n ...(window.olderPageToken != null\n ? { olderPageToken: window.olderPageToken }\n : {}),\n },\n ...(snapshot.groupRootBaseline != null\n ? {\n groupRootBaseline: [\n ...olderRootIds,\n ...snapshot.groupRootBaseline,\n ],\n }\n : {}),\n });\n}\n\nexport type ConvertTurnsResult = {\n messages: ThreadMessage[];\n foldState: PeerThreadFoldState;\n runningTurn?: Turn;\n unstable_resume?: boolean;\n};\n\nfunction assistantStatusFromTurnState(state: Turn[\"state\"]): MessageStatus {\n switch (state.status) {\n case \"done\":\n return { type: \"complete\", reason: \"stop\" };\n case \"error\":\n return { type: \"incomplete\", reason: \"error\", error: state.message };\n case \"cancelled\":\n return { type: \"incomplete\", reason: \"cancelled\" };\n case \"running\":\n return { type: \"running\" };\n default:\n return { type: \"complete\", reason: \"unknown\" };\n }\n}\n\nfunction resolveCreatedAt(\n messageId: string,\n fallback: Date,\n options?: ProjectSessionMessagesOptions,\n): Date {\n return options?.getCreatedAt?.(messageId, fallback) ?? fallback;\n}\n\nfunction parseDataUriMime(data: string): string {\n if (!data.startsWith(\"data:\")) {\n return \"application/octet-stream\";\n }\n const match = /^data:([^;,]+)/.exec(data);\n return match?.[1] ?? \"application/octet-stream\";\n}\n\nfunction fileContentToAttachment(\n file: FileContent,\n attachmentId: string,\n): CompleteAttachment {\n const mimeType = parseDataUriMime(file.data);\n if (mimeType.startsWith(\"image/\")) {\n return {\n id: attachmentId,\n type: \"image\",\n name: file.name,\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: file.data, filename: file.name }],\n };\n }\n return {\n id: attachmentId,\n type: \"file\",\n name: file.name,\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n mimeType,\n filename: file.name,\n data: file.data,\n },\n ],\n };\n}\n\n/** Projects gateway turn input onto an assistant-ui user message (text + attachments). */\nexport function buildUserMessageFromTurnInput(\n turnId: string,\n input: Turn[\"input\"],\n createdAt: string | Date,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const fallback = createdAt instanceof Date ? createdAt : new Date(createdAt);\n const id = `${turnId}-user`;\n const content: ThreadUserMessagePart[] = [];\n const attachments: CompleteAttachment[] = [];\n\n for (const item of input ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const messageContent = item.content;\n if (typeof messageContent === \"string\") {\n content.push({ type: \"text\", text: messageContent });\n continue;\n }\n for (const part of messageContent) {\n if (part.type === \"text\") {\n content.push({ type: \"text\", text: part.text });\n } else if (part.type === \"file\") {\n attachments.push(\n fileContentToAttachment(\n part,\n `${turnId}-file-${attachments.length}`,\n ),\n );\n } else {\n const imageUrl = extractImageUrlFromUserContentItem(part);\n if (imageUrl != null) {\n attachments.push(\n imageUrlToAttachment(\n imageUrl,\n `${turnId}-file-${attachments.length}`,\n ),\n );\n }\n }\n }\n }\n\n return {\n id,\n role: \"user\",\n content: content.length > 0 ? content : [{ type: \"text\", text: \"\" }],\n attachments,\n createdAt: resolveCreatedAt(id, fallback, options),\n metadata: { custom: {} },\n };\n}\n\nfunction buildAssistantMessage(\n turnId: string,\n content: AssistantContentPart[],\n createdAt: string | Date,\n status: MessageStatus,\n custom: Record<string, unknown> = {},\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const fallback = createdAt instanceof Date ? createdAt : new Date(createdAt);\n const id = `${turnId}-assistant`;\n return {\n id,\n role: \"assistant\",\n content,\n status,\n createdAt: resolveCreatedAt(id, fallback, options),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom,\n },\n };\n}\n\nasync function ingestTurnEventsIntoFold(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n foldState: PeerThreadFoldState,\n): Promise<void> {\n if (server.listTurnEvents == null) {\n return;\n }\n const events = await drainListPages((pageToken) =>\n server.listTurnEvents!({\n sessionId,\n turnId,\n order: \"asc\",\n limit: TURN_EVENTS_PAGE_SIZE,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n for (const event of events) {\n ingestTurnEvent(foldState, event as TurnEvent);\n }\n}\n\nasync function fetchTurnEvents(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n): Promise<TurnEvent[]> {\n if (server.listTurnEvents == null) {\n return [];\n }\n const events = await drainListPages((pageToken) =>\n server.listTurnEvents!({\n sessionId,\n turnId,\n order: \"asc\",\n limit: TURN_EVENTS_PAGE_SIZE,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n return events as TurnEvent[];\n}\n\nfunction ingestCollectedEventsIntoFold(\n foldState: PeerThreadFoldState,\n events: TurnEvent[],\n): void {\n for (const event of events) {\n ingestTurnEvent(foldState, event);\n }\n}\n\nasync function fetchAllTurnEventsWithConcurrency(\n server: AgentChatServer,\n sessionId: string,\n turns: Turn[],\n concurrency: number,\n): Promise<TurnEvent[][]> {\n const results: TurnEvent[][] = new Array(turns.length);\n const pool = new Set<Promise<void>>();\n for (let i = 0; i < turns.length; i++) {\n const idx = i;\n const turn = turns[idx]!;\n const p: Promise<void> = fetchTurnEvents(server, sessionId, turn.id).then(\n (events) => {\n results[idx] = events;\n pool.delete(p);\n },\n );\n pool.add(p);\n if (pool.size >= concurrency) await Promise.race(pool);\n }\n await Promise.all(pool);\n return results;\n}\n\nexport function rootModelMessageIdsSinceBaseline(\n foldState: PeerThreadFoldState,\n baseline: readonly string[],\n): string[] {\n const bucket = foldState.threads.get(ROOT_THREAD_ID);\n if (bucket == null) {\n return [];\n }\n if (baseline.length === 0) {\n return [...bucket.modelMessageIds];\n }\n const baselineSet = new Set(baseline);\n return bucket.modelMessageIds.filter((id) => !baselineSet.has(id));\n}\n\nexport function computeGroupRootBaseline(turns: SessionTurnRecord[]): string[] {\n let groupStartIndex = turns.length - 1;\n while (groupStartIndex >= 0 && turns[groupStartIndex]?.userText == null) {\n groupStartIndex--;\n }\n const baseline: string[] = [];\n for (let i = 0; i < groupStartIndex; i++) {\n baseline.push(...(turns[i]?.rootModelMessageIds ?? []));\n }\n return baseline;\n}\n\nfunction buildTurnUpdateFromFold(\n foldState: PeerThreadFoldState,\n turn: Pick<Turn, \"state\">,\n rootModelMessageIds: readonly string[],\n): TurnStreamUpdate {\n const content = buildRootAssistantContentForIds(foldState, rootModelMessageIds);\n let update: TurnStreamUpdate = { content };\n update = appendMcpAuthToTurnContent(update.content, turn);\n update = appendToolApprovalToTurnContent(update, turn);\n return update;\n}\n\nfunction contentHasPendingRequiredActions(\n content: readonly AssistantContentPart[],\n): boolean {\n const message: ThreadMessage = {\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n };\n return messageHasPendingApprovals(message) || messageHasPendingResponses(message);\n}\n\nfunction resolveProjectedRequiredActionState(\n turnUpdate: TurnStreamUpdate,\n content: readonly AssistantContentPart[],\n record: Pick<Turn, \"state\">,\n): { status: MessageStatus; custom: Record<string, unknown> } {\n let status = turnUpdate.status ?? assistantStatusFromTurnState(record.state);\n let custom = { ...(turnUpdate.metadata?.custom ?? {}) };\n\n if (\n status.type === \"requires-action\" &&\n status.reason === \"tool-calls\" &&\n !contentHasPendingRequiredActions(content)\n ) {\n status = assistantStatusFromTurnState(record.state);\n const {\n [TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY]: _approvalThreadId,\n [TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY]: _responseThreadId,\n ...restCustom\n } = custom;\n custom = restCustom;\n }\n\n return { status, custom };\n}\n\nfunction projectActiveStreamUpdate(snapshot: SessionSnapshot): TurnStreamUpdate {\n const activeStream = snapshot.activeStream;\n if (activeStream == null) {\n throw new Error(\"projectActiveStreamUpdate requires an active stream\");\n }\n\n const hasStagedOverlay =\n snapshot.requiredActions.approvals.size > 0 ||\n snapshot.requiredActions.toolResponses.size > 0;\n\n // While the user has staged a response locally, keep the paused stream update\n // so required-action collection can pair interrupt + result before resume.\n if (hasStagedOverlay) {\n return activeStream.update;\n }\n\n const baseline =\n snapshot.groupRootBaseline ?? computeGroupRootBaseline(snapshot.turns);\n const rootModelMessageIds = rootModelMessageIdsSinceBaseline(\n snapshot.fold,\n baseline,\n );\n\n const foldContent = buildRootAssistantContentForIds(\n snapshot.fold,\n rootModelMessageIds,\n );\n const content =\n foldContent.length > 0 ? foldContent : activeStream.update.content;\n\n const turnRecord = snapshot.turns.find((turn) => turn.id === activeStream.turnId);\n const turnLike = turnRecord ?? snapshot.runningTurn;\n\n const rebuilt =\n turnLike != null\n ? buildTurnUpdateFromFold(snapshot.fold, turnLike, rootModelMessageIds)\n : { content };\n\n return {\n ...activeStream.update,\n content,\n metadata: rebuilt.metadata ?? activeStream.update.metadata,\n status: rebuilt.status ?? activeStream.update.status,\n };\n}\n\nfunction applyRequiredActionsOverlayToMessages(\n messages: ThreadMessage[],\n overlay: RequiredActionsOverlay,\n): ThreadMessage[] {\n if (overlay.approvals.size === 0 && overlay.toolResponses.size === 0) {\n return messages;\n }\n\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n\n let { content } = message;\n if (overlay.approvals.size > 0) {\n content = applyApprovalDecisionsToContent(content, overlay.approvals);\n }\n if (overlay.toolResponses.size > 0) {\n content = applyStagedResponsesToContent(content, overlay.toolResponses);\n }\n\n if (content === message.content) {\n return message;\n }\n\n return { ...message, content: [...content] };\n });\n}\n\nfunction projectHistoryTurns(\n snapshot: SessionSnapshot,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage[] {\n const messages: ThreadMessage[] = [];\n let lastAssistantIndex: number | undefined;\n let groupRootIds: string[] = [];\n let sandboxId: string | undefined;\n\n for (let turnIndex = 0; turnIndex < snapshot.turns.length; turnIndex++) {\n const record = snapshot.turns[turnIndex]!;\n const turnRootIds = record.rootModelMessageIds ?? [];\n sandboxId = record.sandboxId ?? sandboxId;\n\n if (record.userText) {\n groupRootIds = [...turnRootIds];\n } else {\n groupRootIds = [...groupRootIds, ...turnRootIds];\n }\n\n const turnUpdate = buildTurnUpdateFromFold(snapshot.fold, record, groupRootIds);\n let content = turnUpdate.content;\n\n const subsequentDecisions = collectSubsequentApprovalDecisions(\n snapshot.turns,\n turnIndex,\n );\n if (subsequentDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, subsequentDecisions);\n }\n\n const subsequentResponses = collectSubsequentToolResponses(\n snapshot.turns,\n turnIndex,\n );\n if (subsequentResponses.size > 0) {\n content = applyStagedResponsesToContent(content, subsequentResponses);\n }\n\n const currentResponses = collectToolResponsesFromTurnInput(record.input);\n if (currentResponses.size > 0) {\n content = applyStagedResponsesToContent(content, currentResponses);\n }\n\n const currentDecisions = collectApprovalDecisionsFromTurnInput(record.input);\n if (currentDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, currentDecisions);\n }\n\n const { status, custom: baseCustom } = resolveProjectedRequiredActionState(\n turnUpdate,\n content,\n record,\n );\n // Continuation turns fold into the previous assistant message and overwrite this custom,\n // so a folded message reports the latest turn that contributed to it — the one whose\n // sandbox wrote the newest artifacts.\n const custom = {\n ...baseCustom,\n turnId: record.id,\n ...(sandboxId != null ? { sandboxId } : {}),\n };\n\n if (record.userText) {\n messages.push(\n buildUserMessageFromTurnInput(\n record.id,\n record.input,\n record.createdAt,\n options,\n ),\n );\n\n if (record.state.status === \"running\") {\n if (content.length > 0) {\n messages.push(\n buildAssistantMessage(\n record.id,\n content,\n record.createdAt,\n status,\n custom,\n options,\n ),\n );\n lastAssistantIndex = messages.length - 1;\n }\n break;\n }\n\n if (content.length > 0) {\n messages.push(\n buildAssistantMessage(\n record.id,\n content,\n record.createdAt,\n status,\n custom,\n options,\n ),\n );\n lastAssistantIndex = messages.length - 1;\n }\n } else if (content.length > 0 && lastAssistantIndex != null) {\n if (record.state.status === \"running\") {\n break;\n }\n const existing = messages[lastAssistantIndex] as Extract<\n ThreadMessage,\n { role: \"assistant\" }\n >;\n messages[lastAssistantIndex] = {\n ...existing,\n content,\n status,\n metadata: {\n ...existing.metadata,\n custom,\n },\n };\n } else if (record.state.status === \"running\") {\n break;\n }\n }\n\n return messages;\n}\n\nexport function projectSessionMessages(\n snapshot: SessionSnapshot,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage[] {\n let messages = projectHistoryTurns(snapshot, options);\n\n if (snapshot.pendingUser != null) {\n messages.push(\n buildUserMessageFromTurnInput(\n snapshot.pendingUser.turnId,\n [{ type: \"user.message\", content: snapshot.pendingUser.content }],\n snapshot.pendingUser.createdAt,\n options,\n ),\n );\n }\n\n if (snapshot.activeStream != null) {\n const { turnId, update, isContinuation, streamComplete } =\n snapshot.activeStream;\n const resolvedUpdate =\n streamComplete === true ? projectActiveStreamUpdate(snapshot) : update;\n\n const last = messages.at(-1);\n const existingAssistant =\n isContinuation && last?.role === \"assistant\" ? last : undefined;\n let assistantMessage = turnStreamUpdateToAssistantMessage(\n turnId,\n resolvedUpdate,\n existingAssistant,\n options,\n );\n if (streamComplete === true && resolvedUpdate.status == null) {\n assistantMessage = {\n ...assistantMessage,\n status: { type: \"complete\", reason: \"stop\" },\n };\n }\n\n if (isContinuation && last?.role === \"assistant\") {\n messages = [...messages.slice(0, -1), assistantMessage];\n } else {\n messages = [...messages, assistantMessage];\n }\n }\n\n return applyRequiredActionsOverlayToMessages(\n messages,\n snapshot.requiredActions,\n );\n}\n\nconst DEFAULT_LIST_EVENTS_CONCURRENCY = 5;\n\nfunction ingestTurnsIntoSnapshot(\n snapshot: SessionSnapshot,\n turns: Turn[],\n eventArrays: TurnEvent[][],\n): Turn | undefined {\n let runningTurn: Turn | undefined;\n\n for (let i = 0; i < turns.length; i++) {\n const turn = turns[i]!;\n const rootBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const beforeCount = rootBucket?.modelMessageIds.length ?? 0;\n\n ingestCollectedEventsIntoFold(snapshot.fold, eventArrays[i] ?? []);\n applyUserToolResponsesToFold(snapshot.fold, turn.input ?? []);\n\n const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(\n beforeCount,\n );\n\n const sandboxEvent = (eventArrays[i] ?? []).find(\n (event): event is Extract<TurnEvent, { type: \"sandbox.created\" }> =>\n event.type === \"sandbox.created\",\n );\n\n snapshot.turns.push({\n ...turnToSessionRecord(turn),\n rootModelMessageIds,\n ...(sandboxEvent != null ? { sandboxId: sandboxEvent.sandboxId } : {}),\n });\n\n if (turn.state.status === \"running\") {\n runningTurn = turn;\n break;\n }\n }\n\n return runningTurn;\n}\n\nexport async function buildSnapshotFromSession(\n server: AgentChatServer,\n sessionId: string,\n concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n): Promise<SessionSnapshot> {\n // Completed history comes from session-level listEvents. The session API\n // excludes the running turn — hydrate that turn via listTurnEvents so\n // convertTurnsToThreadMessages still surfaces in-flight content.\n const snapshot = await buildSnapshotFromSessionEvents(server, sessionId);\n if (snapshot.runningTurn == null) {\n return snapshot;\n }\n\n const turn = snapshot.runningTurn;\n const eventArrays = await fetchAllTurnEventsWithConcurrency(\n server,\n sessionId,\n [turn],\n concurrency,\n );\n ingestTurnsIntoSnapshot(snapshot, [turn], eventArrays);\n\n // Hydrated in-flight content lives in `turns` / `fold` now — drop the\n // reconnect seed so projection does not duplicate the user bubble.\n return replaceSessionSnapshot(snapshot, {\n runningTurn: turn,\n unstable_resume: true as const,\n groupRootBaseline: computeGroupRootBaseline(snapshot.turns),\n pendingUser: undefined,\n });\n}\n\n/** Rebuilds session state from turns strictly before `beforeTurnId` (excludes that turn). */\nexport async function buildSnapshotBeforeTurn(\n server: AgentChatServer,\n sessionId: string,\n beforeTurnId: string,\n concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n): Promise<SessionSnapshot> {\n const turns = await listSessionTurnsOrdered(server, sessionId);\n\n const beforeIndex = turns.findIndex((turn) => turn.id === beforeTurnId);\n if (beforeIndex === -1) {\n throw new Error(`Turn ${beforeTurnId} not found in session`);\n }\n\n return buildSnapshotBeforeTurnIndex(\n server,\n sessionId,\n beforeIndex,\n concurrency,\n turns,\n );\n}\n\n/** Rebuilds session state from the first `turnIndex` turns (excludes that turn). */\nexport async function buildSnapshotBeforeTurnIndex(\n server: AgentChatServer,\n sessionId: string,\n turnIndex: number,\n _concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n orderedTurns?: Turn[],\n): Promise<SessionSnapshot> {\n if (turnIndex <= 0) {\n return createEmptySessionSnapshot();\n }\n\n const turns = orderedTurns ?? (await listSessionTurnsOrdered(server, sessionId));\n const turnsToInclude = turns.slice(0, turnIndex);\n const lastTurnId = turnsToInclude.at(-1)?.id;\n if (lastTurnId == null) {\n return createEmptySessionSnapshot();\n }\n\n // Anchor the session events window at the newest included turn so the\n // ancestor chain matches `[turns[0], …, turns[turnIndex - 1]]`.\n const items = await fetchAllSessionEvents(server, sessionId, { lastTurnId });\n const snapshot = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(snapshot, items);\n return snapshot;\n}\n\n/** Turn id to branch from when resubmitting at `turnIndex` (`\"none\"` for first turn). */\nexport async function resolveGatewayBranchPreviousTurnId(\n server: AgentChatServer,\n sessionId: string,\n turnIndex: number,\n orderedTurns?: Turn[],\n): Promise<string> {\n if (turnIndex <= 0) {\n return \"none\";\n }\n const turns = orderedTurns ?? (await listSessionTurnsOrdered(server, sessionId));\n return turns[turnIndex - 1]?.id ?? \"none\";\n}\n\n/** Resolves `previousTurnId` by turn id so partial history windows stay correct. */\nexport async function resolveGatewayBranchPreviousTurnIdForTurn(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n): Promise<string> {\n const turns = await listSessionTurnsOrdered(server, sessionId);\n const turnIndex = turns.findIndex((turn) => turn.id === turnId);\n return resolveGatewayBranchPreviousTurnId(server, sessionId, turnIndex, turns);\n}\n\nasync function listSessionTurnsOrdered(\n server: AgentChatServer,\n sessionId: string,\n): Promise<Turn[]> {\n const turns = await drainListPages((pageToken) =>\n server.listTurns({\n sessionId,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n turns.reverse();\n return turns;\n}\n\nexport async function buildTurnAssistantContent(\n server: AgentChatServer,\n sessionId: string,\n turn: Pick<Turn, \"id\" | \"state\">,\n foldState?: PeerThreadFoldState,\n): Promise<AssistantContentPart[]> {\n const state = foldState ?? new PeerThreadFoldState();\n const beforeCount =\n state.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;\n await ingestTurnEventsIntoFold(server, sessionId, turn.id, state);\n const afterIds = state.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n const rootModelMessageIds = afterIds.slice(beforeCount);\n return buildTurnUpdateFromFold(state, turn, rootModelMessageIds).content;\n}\n\nexport async function convertTurnsToThreadMessages(\n server: AgentChatServer,\n sessionId: string,\n): Promise<ConvertTurnsResult> {\n const snapshot = await buildSnapshotFromSession(server, sessionId);\n const messages = projectSessionMessages(snapshot);\n\n return {\n messages,\n foldState: snapshot.fold,\n ...(snapshot.runningTurn != null\n ? {\n runningTurn: snapshot.runningTurn,\n unstable_resume: true as const,\n }\n : {}),\n };\n}\n\nexport function getTurnMessageContent(message: AppendMessage): string {\n const parts: string[] = [];\n for (const part of message.content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n }\n }\n const text = parts.join(\"\\n\").trim();\n if (!text) {\n throw new Error(\"User message must contain text content.\");\n }\n return text;\n}\n\n/**\n * Gateway `user.message` content (string for text-only, or text/file parts).\n * Derived from SDK `TurnInputItem` so it tracks API changes.\n */\nexport type UserMessageContent = Extract<\n TurnInputItem,\n { type: \"user.message\" }\n>[\"content\"];\n\ntype UserMessageContentItem = Exclude<UserMessageContent, string>[number];\ntype FileContent = Extract<UserMessageContentItem, { type: \"file\" }>;\ntype TextContent = Extract<UserMessageContentItem, { type: \"text\" }>;\n\nfunction toFileDataUri(data: string, mimeType: string): string {\n // FileContent expects a data URI (`data:<mime>;base64,<payload>`).\n // Attachment adapters typically already produce one via FileReader.readAsDataURL;\n // only wrap bare base64 payloads.\n if (data.startsWith(\"data:\")) {\n return data;\n }\n return `data:${mimeType};base64,${data}`;\n}\n\nfunction toFileContent(name: string, data: string, mimeType: string): FileContent {\n return {\n type: \"file\",\n name,\n data: toFileDataUri(data, mimeType),\n };\n}\n\n/**\n * Builds the gateway turn input content from a composer message, forwarding\n * attachments as SDK `FileContent` parts. Mirrors how assistant-ui surfaces\n * attachment content on `message.attachments[].content`.\n */\nexport function buildUserMessageContent(message: AppendMessage): UserMessageContent {\n const contentParts = message.content as readonly ThreadUserMessagePart[];\n const inputParts: (ThreadUserMessagePart & { filename?: string })[] = [\n ...contentParts,\n ...(message.attachments?.flatMap((attachment) =>\n attachment.content.map((part) => ({\n ...part,\n filename: attachment.name,\n })),\n ) ?? []),\n ];\n\n const items: UserMessageContentItem[] = [];\n for (const part of inputParts) {\n switch (part.type) {\n case \"text\":\n if (part.text.trim().length > 0) {\n const textPart: TextContent = { type: \"text\", text: part.text };\n items.push(textPart);\n }\n break;\n case \"image\":\n items.push(\n toFileContent(part.filename ?? \"image\", part.image, \"image/png\"),\n );\n break;\n case \"file\":\n items.push(\n toFileContent(\n part.filename ?? \"file\",\n part.data,\n part.mimeType,\n ),\n );\n break;\n default:\n break;\n }\n }\n\n const hasFile = items.some((item): item is FileContent => item.type === \"file\");\n if (!hasFile) {\n // Text-only: keep the string form and the non-empty invariant.\n return getTurnMessageContent(message);\n }\n return items;\n}\n\n/** Derives display text from gateway user-message content (drops file parts). */\nexport function userMessageContentToText(content: UserMessageContent): string {\n if (typeof content === \"string\") {\n return content;\n }\n return content\n .filter(\n (item): item is TextContent => item.type === \"text\",\n )\n .map((item) => item.text)\n .join(\"\\n\")\n .trim();\n}\n\n/** Strips the `-user` suffix from a projected user message id to recover the turn id. */\nexport function parseTurnIdFromMessageId(messageId: string): string {\n return messageId.replace(/-user$/, \"\");\n}\n\n/** Parent turn id for branching before `turnId`; `null` when editing the first turn. */\nexport function resolveBranchPreviousTurnId(\n turns: readonly SessionTurnRecord[],\n turnId: string,\n): string | null {\n const turnIndex = turns.findIndex((turn) => turn.id === turnId);\n if (turnIndex <= 0) {\n return null;\n }\n return turns[turnIndex - 1]!.id;\n}\n\n/** Extracts edited text from an assistant-ui append message (text parts only). */\nexport function extractEditedText(message: AppendMessage): string {\n return getTurnMessageContent(message);\n}\n\n/** Original gateway user-message content from a turn record (for reset). */\nexport function extractTurnUserMessageContent(\n input: TurnInputItem[] | undefined,\n): UserMessageContent {\n for (const item of input ?? []) {\n if (item.type === \"user.message\") {\n return item.content;\n }\n }\n return \"\";\n}\n\n/**\n * Builds resubmit content for a text-only edit: replaces text with `editedText`\n * while preserving original file parts from the turn record.\n */\nexport function buildEditedUserMessageContent(\n editedText: string,\n originalInput: TurnInputItem[] | undefined,\n): UserMessageContent {\n const fileParts: FileContent[] = [];\n for (const item of originalInput ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const content = item.content;\n if (typeof content === \"string\") {\n continue;\n }\n for (const part of content) {\n if (part.type === \"file\") {\n fileParts.push(part);\n }\n }\n }\n\n if (fileParts.length === 0) {\n return editedText;\n }\n\n const items: UserMessageContentItem[] = [];\n if (editedText.trim().length > 0) {\n items.push({ type: \"text\", text: editedText });\n }\n items.push(...fileParts);\n return items;\n}\n\nfunction buildMcpAuthUpdate(\n pendingMcpAuth: McpAuthRequiredEvent,\n foldState: PeerThreadFoldState,\n groupRootBaseline?: readonly string[],\n): TurnStreamUpdate {\n const base =\n groupRootBaseline != null\n ? buildRootAssistantContentForIds(\n foldState,\n rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline),\n )\n : buildRootAssistantContent(foldState);\n return {\n content: [...base, ...buildMcpAuthTextParts(pendingMcpAuth.mcpServers)],\n status: mcpAuthAssistantStatus(),\n metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) },\n };\n}\n\nexport async function* streamTurnEvents(\n stream: AsyncIterable<TurnStreamData>,\n foldState: PeerThreadFoldState,\n groupRootBaseline?: readonly string[],\n onTurnIdAvailable?: (turnId: string) => void,\n): AsyncGenerator<TurnStreamUpdate> {\n let pendingMcpAuth: McpAuthRequiredEvent | undefined;\n let sandboxId: string | undefined;\n let sandboxIdYielded = false;\n\n const withSandbox = (update: TurnStreamUpdate): TurnStreamUpdate => {\n if (sandboxId == null) {\n return update;\n }\n sandboxIdYielded = true;\n return {\n ...update,\n metadata: { ...update.metadata, custom: { ...update.metadata?.custom, sandboxId } },\n };\n };\n\n const yieldContent = (): AssistantContentPart[] | undefined => {\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n const content = buildRootAssistantContentForIds(foldState, ids);\n return content.length > 0 ? content : undefined;\n };\n\n for await (const data of stream) {\n const event = data.event;\n\n if (event.type === \"turn.created\") {\n onTurnIdAvailable?.(event.turnId);\n continue;\n }\n\n if (event.type === \"sandbox.created\") {\n sandboxId = event.sandboxId;\n continue;\n }\n\n if (event.type === \"mcp.auth_required\") {\n pendingMcpAuth = event;\n continue;\n }\n\n if (event.type === \"turn.done\") {\n if (event.state.status === \"error\") {\n throw new Error(event.state.message);\n }\n // The turn is logically complete once `turn.done` is observed. The\n // resumed-turn transport (`subscribeToTurn`) is a reconnectable live\n // tail and is not guaranteed to close its SSE body right after this\n // event, so we must stop consuming explicitly rather than waiting\n // for the underlying stream to end — otherwise `isRunning` never\n // clears and the composer's cancel/spinner button gets stuck.\n break;\n }\n\n if (!ingestStreamEvent(foldState, event)) {\n continue;\n }\n\n const content = yieldContent();\n if (content != null) {\n yield withSandbox({ content });\n }\n }\n\n if (pendingMcpAuth != null) {\n yield withSandbox(buildMcpAuthUpdate(pendingMcpAuth, foldState, groupRootBaseline));\n return;\n }\n\n const approvalThreadId = findFirstPendingApprovalThreadId(foldState);\n const responseThreadId = findFirstPendingResponseThreadId(foldState);\n if (approvalThreadId != null || responseThreadId != null) {\n const custom: Record<string, unknown> = {};\n if (approvalThreadId != null) {\n Object.assign(\n custom,\n toolApprovalMessageCustom(\n approvalThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : approvalThreadId,\n ),\n );\n }\n if (responseThreadId != null) {\n Object.assign(\n custom,\n toolResponseMessageCustom(\n responseThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : responseThreadId,\n ),\n );\n }\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n yield withSandbox({\n content: buildRootAssistantContentForIds(foldState, ids),\n status:\n approvalThreadId != null ? toolApprovalStatus() : toolResponseStatus(),\n metadata: { custom },\n });\n return;\n }\n\n if (sandboxId != null && !sandboxIdYielded) {\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n yield withSandbox({ content: buildRootAssistantContentForIds(foldState, ids) });\n }\n}\n\nexport function turnStreamUpdateToAssistantMessage(\n turnId: string,\n update: TurnStreamUpdate,\n existing?: ThreadMessage,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const id =\n existing?.role === \"assistant\"\n ? existing.id\n : `${turnId}-assistant`;\n const fallbackCreatedAt = existing?.createdAt ?? new Date();\n return {\n id,\n role: \"assistant\",\n content: update.content,\n status: update.status ?? { type: \"running\" },\n createdAt: resolveCreatedAt(id, fallbackCreatedAt, options),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {\n ...(existing?.role === \"assistant\" ? existing.metadata.custom : {}),\n ...update.metadata?.custom,\n turnId,\n },\n },\n };\n}\n\nexport function repositoryItemsFromMessages(\n messages: readonly ThreadMessage[],\n): ExportedMessageRepositoryItem[] {\n const items: ExportedMessageRepositoryItem[] = [];\n let parentId: string | null = null;\n for (const message of messages) {\n items.push({ parentId, message });\n parentId = message.id;\n }\n return items;\n}\n\nexport type { SessionSnapshot, ProjectSessionMessagesOptions } from \"./sessionSnapshot.js\";\n","import type { AgentChatServer, AgentSpec } from \"../server/types.js\";\n\nexport const DRAFT_SESSION_LAST_UPDATED_AT_HEADER = \"x-tfy-session-last-updated-at\";\n\nexport type DraftSessionBridge = {\n syncAgentSpec: (draftSessionId: string, agentSpec: AgentSpec) => Promise<string>;\n getDraftAgentSpec: (draftSessionId: string) => Promise<AgentSpec>;\n};\n\nexport function createDraftSessionBridge(\n server: AgentChatServer,\n): DraftSessionBridge {\n return {\n async getDraftAgentSpec(draftSessionId) {\n const session = await server.getSession({ sessionId: draftSessionId });\n if (session.agentSpec == null) {\n throw new Error(\n `Session ${draftSessionId} has no agentSpec (isMutable=${session.isMutable}).`,\n );\n }\n return session.agentSpec;\n },\n\n async syncAgentSpec(draftSessionId, agentSpec) {\n const updated = await server.updateSession({\n sessionId: draftSessionId,\n agentSpec,\n });\n return updated.updatedAt;\n },\n };\n}\n","/** ISO timestamp one year before now — used as `listSessions` `startTimestamp`. */\nexport function sessionListStartTimestamp(): string {\n const start = new Date();\n start.setFullYear(start.getFullYear() - 1);\n return start.toISOString();\n}\n","import type { AgentSpec } from \"../server/types.js\";\n\n/** @deprecated Use Session with isMutable: true instead. Kept for title helper. */\nexport type DraftSession = {\n title?: string | null;\n agentSpec: AgentSpec;\n};\n\n/** Partial update — host fields flow through when `TSpec` is widened. */\nexport type AgentSpecUpdate<TSpec extends AgentSpec = AgentSpec> = {\n [K in keyof TSpec]?: K extends \"model\"\n ? Omit<Partial<TSpec[\"model\"]>, \"params\"> & {\n params?: Partial<NonNullable<TSpec[\"model\"][\"params\"]>>;\n }\n : TSpec[K];\n};\n\nexport function mergeAgentSpec<TSpec extends AgentSpec>(\n base: TSpec,\n update: AgentSpecUpdate<TSpec>,\n): TSpec {\n const { model: modelUpdate, ...rest } = update;\n\n const next = {\n ...base,\n ...rest,\n } as TSpec;\n\n if (modelUpdate != null) {\n next.model = {\n ...base.model,\n ...modelUpdate,\n name: modelUpdate.name ?? base.model.name,\n params:\n modelUpdate.params != null\n ? { ...base.model.params, ...modelUpdate.params }\n : base.model.params,\n } as TSpec[\"model\"];\n }\n\n return next;\n}\n\nexport function draftSessionTitle(draft: DraftSession): string {\n return draft.title ?? draft.agentSpec.model.name;\n}\n","import type { RemoteThreadMetadata } from \"@assistant-ui/core\";\n\nimport { draftSessionTitle } from \"./draft/agentSpec.js\";\nimport type { AgentSpec, Session } from \"./server/types.js\";\n\n/**\n * Title for a session row in a mixed (draft + named) thread list.\n * Mutable sessions use draftSessionTitle (optionally falling back to\n * `defaultAgentSpec`); named sessions use title → agentName → id.\n */\nexport function sessionDisplayTitle(\n session: Session,\n defaultAgentSpec?: AgentSpec,\n): string {\n if (session.isMutable) {\n const agentSpec = session.agentSpec ?? defaultAgentSpec;\n if (agentSpec != null) {\n return draftSessionTitle({\n title: session.title,\n agentSpec,\n });\n }\n }\n return session.title ?? session.agentName ?? session.id;\n}\n\n/** Map a Session DTO onto RemoteThreadMetadata (mutability + display name in custom). */\nexport function sessionToThreadMetadata(\n session: Session,\n title: string | undefined,\n): RemoteThreadMetadata {\n return {\n status: \"regular\",\n remoteId: session.id,\n title,\n lastMessageAt: new Date(session.updatedAt),\n custom: {\n isMutable: session.isMutable,\n ...(session.agentName != null ? { agentName: session.agentName } : {}),\n },\n };\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"../server/types.js\";\nimport type { AgentSpec } from \"../server/types.js\";\nimport { sessionListStartTimestamp } from \"../sessionListStartTimestamp.js\";\nimport {\n sessionDisplayTitle,\n sessionToThreadMetadata,\n} from \"../sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\nexport function createTrueFoundryDraftThreadListAdapter(options: {\n server: AgentChatServer;\n defaultAgentSpec: AgentSpec;\n getAgentSpec?: () => AgentSpec;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, defaultAgentSpec, getAgentSpec, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(\n session,\n sessionDisplayTitle(session, defaultAgentSpec),\n ),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize(_threadId: string) {\n const draft = await server.createSession({\n agentSpec: getAgentSpec?.() ?? defaultAgentSpec,\n });\n return { remoteId: draft.id, externalId: undefined };\n },\n\n async fetch(remoteId) {\n const draft = await server.getSession({ sessionId: remoteId });\n return sessionToThreadMetadata(\n draft,\n sessionDisplayTitle(draft, defaultAgentSpec),\n );\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","import { createRuntimeExtras } from \"@assistant-ui/core/internal\";\nimport type { McpAuthRequiredEvent } from \"./server/index.js\";\n\nimport type { AgentSpec } from \"./server/types.js\";\nimport type { AgentSpecUpdate } from \"./draft/agentSpec.js\";\nimport type { PendingApproval, PendingToolResponse } from \"./collectPending.js\";\nimport type { RespondToToolApprovalOptions } from \"./toolApproval.js\";\nimport type { RespondToToolResponseOptions } from \"./toolResponse.js\";\n\nexport type { PendingApproval, PendingToolResponse };\n\nexport type TrueFoundryDraftRuntimeExtras = {\n agentSpec: AgentSpec | null;\n draftSessionId: string | undefined;\n isSpecLoading: boolean;\n isSpecSyncing: boolean;\n specError: unknown | null;\n updateAgentSpec: (update: AgentSpecUpdate) => void;\n};\n\nexport type TrueFoundryRuntimeExtras = {\n pendingApprovals: PendingApproval[];\n pendingToolResponses: PendingToolResponse[];\n pendingMcpAuth: { mcpServers: McpAuthRequiredEvent[\"mcpServers\"] } | null;\n sandboxId: string | undefined;\n respondToToolApproval: (response: RespondToToolApprovalOptions) => void;\n respondToToolResponse: (response: RespondToToolResponseOptions) => void;\n resumeMcpAuth: () => Promise<void>;\n downloadSandboxFile: (req: { turnId: string; path: string }) => Promise<Blob>;\n cancel: () => Promise<void>;\n resetFromTurn: (turnId: string) => Promise<void>;\n reload: () => void;\n hasOlderHistory: boolean;\n isLoadingOlderHistory: boolean;\n loadOlderHistory: () => Promise<void>;\n draft: TrueFoundryDraftRuntimeExtras | null;\n};\n\nexport const trueFoundryExtras = createRuntimeExtras<TrueFoundryRuntimeExtras>(\n \"useTrueFoundryAgentRuntime\",\n);\n\nexport const EMPTY_DRAFT_EXTRAS: TrueFoundryDraftRuntimeExtras = {\n agentSpec: null,\n draftSessionId: undefined,\n isSpecLoading: false,\n isSpecSyncing: false,\n specError: null,\n updateAgentSpec: () => {\n throw new Error(\"Draft agent extras are only available in draft mode.\");\n },\n};\n","import type { AgentChatServer, Session } from \"./server/types.js\";\n\nconst inflightBySessionId = new Map<string, Promise<Session>>();\n\n/** `sessionId` is the assistant-ui thread `remoteId` from `RemoteThreadListAdapter.initialize`. */\nexport function getSession(\n server: AgentChatServer,\n sessionId: string,\n): Promise<Session> {\n let inflight = inflightBySessionId.get(sessionId);\n if (inflight == null) {\n inflight = server.getSession({ sessionId }).finally(() => {\n if (inflightBySessionId.get(sessionId) === inflight) {\n inflightBySessionId.delete(sessionId);\n }\n });\n inflightBySessionId.set(sessionId, inflight);\n }\n return inflight;\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"./server/types.js\";\nimport { getSession } from \"./sessions.js\";\nimport { sessionListStartTimestamp } from \"./sessionListStartTimestamp.js\";\nimport { sessionToThreadMetadata } from \"./sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\nexport function createTrueFoundryThreadListAdapter(options: {\n server: AgentChatServer;\n agentName: string;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, agentName, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(session, session.title ?? undefined),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize(_threadId: string) {\n const session = await server.createSession({ agentName });\n return { remoteId: session.id, externalId: undefined };\n },\n\n async fetch(remoteId) {\n const session = await getSession(server, remoteId);\n return sessionToThreadMetadata(session, session.title ?? undefined);\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","import type {\n AttachmentAdapter,\n DictationAdapter,\n ExternalStoreSharedOptions,\n FeedbackAdapter,\n RealtimeVoiceAdapter,\n SpeechSynthesisAdapter,\n} from \"@assistant-ui/core\";\n\nimport type { AgentChatServer, AgentSpec } from \"./server/types.js\";\n\nexport type NamedAgentConfig = {\n mode: \"named\";\n agentName: string;\n};\n\nexport type DraftAgentConfig = {\n mode: \"draft\";\n defaultAgentSpec: AgentSpec;\n onAgentSpecChange?: ((spec: AgentSpec) => void) | undefined;\n};\n\nexport type TrueFoundryAgentConfig = NamedAgentConfig | DraftAgentConfig;\n\ntype TrueFoundryAgentRuntimeBaseOptions = ExternalStoreSharedOptions & {\n server: AgentChatServer;\n initialSessionId?: string | undefined;\n threadId?: string | undefined;\n onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;\n onError?: ((error: unknown) => void) | undefined;\n listEventsConcurrency?: number | undefined;\n /**\n * Optional filter forwarded to `listSessions({ agentId })`.\n * Omit for all chats; hosts that key agents by name pass that name as the id.\n */\n listSessionsAgentId?: string | undefined;\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n speech?: SpeechSynthesisAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n }\n | undefined;\n};\n\nexport type UseTrueFoundryAgentRuntimeOptions = TrueFoundryAgentRuntimeBaseOptions & {\n /** Discriminated agent source. Omit when using legacy `agentName`. */\n agent?: TrueFoundryAgentConfig | undefined;\n /** Legacy named-agent shorthand. Prefer `agent: { mode: \"named\", agentName }`. */\n agentName?: string | undefined;\n};\n\nexport type ResolvedTrueFoundryAgentRuntimeOptions = TrueFoundryAgentRuntimeBaseOptions & {\n agent: TrueFoundryAgentConfig;\n};\n\nexport function resolveTrueFoundryAgentConfig(\n options: Pick<UseTrueFoundryAgentRuntimeOptions, \"agent\" | \"agentName\">,\n): TrueFoundryAgentConfig {\n if (options.agent != null) {\n if (options.agent.mode === \"named\" && options.agentName != null) {\n return { mode: \"named\", agentName: options.agentName };\n }\n return options.agent;\n }\n if (options.agentName != null) {\n return { mode: \"named\", agentName: options.agentName };\n }\n throw new Error(\n \"useTrueFoundryAgentRuntime requires `agent` or legacy `agentName`.\",\n );\n}\n\nexport function resolveTrueFoundryAgentRuntimeOptions(\n options: UseTrueFoundryAgentRuntimeOptions,\n): ResolvedTrueFoundryAgentRuntimeOptions {\n const agent = resolveTrueFoundryAgentConfig(options);\n\n return {\n ...options,\n agent,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { AgentSpec } from \"../server/types.js\";\nimport { mergeAgentSpec, type AgentSpecUpdate } from \"./agentSpec.js\";\nimport type { DraftSessionBridge } from \"./draftSessionBridge.js\";\n\nconst SPEC_SYNC_DEBOUNCE_MS = 400;\n\nexport type UseDraftAgentSpecOptions = {\n draftSessionId: string | undefined;\n draftBridge: DraftSessionBridge | null;\n defaultAgentSpec: AgentSpec;\n onAgentSpecChange?: ((spec: AgentSpec) => void) | undefined;\n onError?: ((error: unknown) => void) | undefined;\n};\n\nexport type UseDraftAgentSpecResult = {\n agentSpec: AgentSpec | null;\n draftSessionId: string | undefined;\n isSpecLoading: boolean;\n isSpecSyncing: boolean;\n specError: unknown | null;\n updateAgentSpec: (update: AgentSpecUpdate) => void;\n takeTurnHeaderTimestamp: () => Promise<string | undefined>;\n};\n\nexport function useDraftAgentSpec({\n draftSessionId,\n draftBridge,\n defaultAgentSpec,\n onAgentSpecChange,\n onError,\n}: UseDraftAgentSpecOptions): UseDraftAgentSpecResult {\n const enabled = draftBridge != null;\n const [agentSpec, setAgentSpec] = useState<AgentSpec>(defaultAgentSpec);\n const [isSpecLoading, setIsSpecLoading] = useState(false);\n const [isSpecSyncing, setIsSpecSyncing] = useState(false);\n const [specError, setSpecError] = useState<unknown | null>(null);\n\n const agentSpecRef = useRef(agentSpec);\n agentSpecRef.current = agentSpec;\n\n const syncTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const syncGenerationRef = useRef(0);\n const loadedDraftIdRef = useRef<string | undefined>(undefined);\n const localDirtyRef = useRef(false);\n const lastUpdatedAtRef = useRef<string | undefined>(undefined);\n const pendingFlushRef = useRef<(() => Promise<void>) | undefined>(undefined);\n const inFlightFlushRef = useRef<Promise<void> | undefined>(undefined);\n const activeDraftIdRef = useRef(draftSessionId);\n\n // Invalidate sync state from the previous draft so a stale pending flush or\n // stored updatedAt can't update the wrong draft or leak into the next\n // turn's header. Bumping the generation makes any in-flight sync a no-op.\n useEffect(() => {\n const previousDraftId = activeDraftIdRef.current;\n if (previousDraftId === draftSessionId) {\n return;\n }\n activeDraftIdRef.current = draftSessionId;\n syncGenerationRef.current++;\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n syncTimeoutRef.current = undefined;\n }\n pendingFlushRef.current = undefined;\n inFlightFlushRef.current = undefined;\n lastUpdatedAtRef.current = undefined;\n setIsSpecSyncing(false);\n // Dirty edits made against a previous draft must not be replayed onto\n // the new one. Keep them only for lazy creation (undefined -> id).\n if (previousDraftId != null) {\n localDirtyRef.current = false;\n }\n }, [draftSessionId]);\n\n useEffect(() => {\n if (!enabled || draftBridge == null) {\n return;\n }\n if (draftSessionId == null) {\n loadedDraftIdRef.current = undefined;\n setAgentSpec(defaultAgentSpec);\n localDirtyRef.current = false;\n setSpecError(null);\n setIsSpecLoading(false);\n return;\n }\n\n if (loadedDraftIdRef.current === draftSessionId) {\n return;\n }\n\n let cancelled = false;\n setIsSpecLoading(true);\n void (async () => {\n try {\n const loaded = await draftBridge.getDraftAgentSpec(draftSessionId);\n if (cancelled) {\n return;\n }\n loadedDraftIdRef.current = draftSessionId;\n\n if (localDirtyRef.current) {\n scheduleSpecSyncRef.current?.(draftSessionId, agentSpecRef.current);\n localDirtyRef.current = false;\n setSpecError(null);\n setIsSpecLoading(false);\n return;\n }\n\n setAgentSpec(loaded);\n setSpecError(null);\n setIsSpecLoading(false);\n } catch (error) {\n if (!cancelled) {\n onError?.(error);\n setSpecError(error);\n setIsSpecLoading(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n // The cancelled load can no longer clear the flag itself. Releasing it\n // here keeps it from sticking when the next run early-returns on an\n // already-loaded draft; a run that starts a fresh load re-raises it in\n // the same commit.\n setIsSpecLoading(false);\n };\n }, [defaultAgentSpec, draftBridge, draftSessionId, enabled, onError]);\n\n const flushSpecSync = useCallback(\n async (draftId: string, spec: AgentSpec, generation: number) => {\n if (draftBridge == null) {\n return;\n }\n setIsSpecSyncing(true);\n try {\n const updatedAt = await draftBridge.syncAgentSpec(draftId, spec);\n if (generation !== syncGenerationRef.current) {\n return;\n }\n lastUpdatedAtRef.current =\n updatedAt || new Date().toISOString();\n setSpecError(null);\n onAgentSpecChange?.(spec);\n } catch (error) {\n if (generation === syncGenerationRef.current) {\n setSpecError(error);\n onError?.(error);\n }\n } finally {\n if (generation === syncGenerationRef.current) {\n setIsSpecSyncing(false);\n }\n }\n },\n [draftBridge, onAgentSpecChange, onError],\n );\n\n const scheduleSpecSync = useCallback(\n (draftId: string, spec: AgentSpec) => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n }\n const generation = ++syncGenerationRef.current;\n const flush = () => {\n pendingFlushRef.current = undefined;\n syncTimeoutRef.current = undefined;\n const promise = flushSpecSync(draftId, spec, generation).finally(() => {\n if (inFlightFlushRef.current === promise) {\n inFlightFlushRef.current = undefined;\n }\n });\n inFlightFlushRef.current = promise;\n return promise;\n };\n pendingFlushRef.current = flush;\n syncTimeoutRef.current = setTimeout(() => {\n void flush();\n }, SPEC_SYNC_DEBOUNCE_MS);\n },\n [flushSpecSync],\n );\n\n const scheduleSpecSyncRef = useRef(scheduleSpecSync);\n scheduleSpecSyncRef.current = scheduleSpecSync;\n\n const flushPendingSpecSyncNow = useCallback(async () => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n syncTimeoutRef.current = undefined;\n }\n const pending = pendingFlushRef.current;\n if (pending != null) {\n pendingFlushRef.current = undefined;\n await pending();\n return;\n }\n if (inFlightFlushRef.current != null) {\n await inFlightFlushRef.current;\n }\n }, []);\n\n const takeTurnHeaderTimestamp = useCallback(async () => {\n await flushPendingSpecSyncNow();\n const updatedAt = lastUpdatedAtRef.current;\n lastUpdatedAtRef.current = undefined;\n return updatedAt;\n }, [flushPendingSpecSyncNow]);\n\n useEffect(\n () => () => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n }\n },\n [],\n );\n\n const updateAgentSpec = useCallback(\n (update: AgentSpecUpdate) => {\n if (!enabled || draftBridge == null) {\n return;\n }\n const next = mergeAgentSpec(agentSpecRef.current, update);\n setAgentSpec(next);\n localDirtyRef.current = true;\n if (draftSessionId != null) {\n scheduleSpecSync(draftSessionId, next);\n }\n },\n [draftBridge, draftSessionId, enabled, scheduleSpecSync],\n );\n\n return useMemo(\n () => ({\n agentSpec: enabled ? agentSpec : null,\n draftSessionId: enabled ? draftSessionId : undefined,\n isSpecLoading: enabled ? isSpecLoading : false,\n isSpecSyncing: enabled ? isSpecSyncing : false,\n specError: enabled ? specError : null,\n updateAgentSpec,\n takeTurnHeaderTimestamp,\n }),\n [\n agentSpec,\n draftSessionId,\n enabled,\n isSpecLoading,\n isSpecSyncing,\n specError,\n takeTurnHeaderTimestamp,\n updateAgentSpec,\n ],\n );\n}\n","\"use client\";\n\nimport { generateId } from \"@assistant-ui/core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n McpAuthRequiredEvent,\n ToolApprovalRequiredEvent,\n ToolResponseRequiredEvent,\n Turn,\n TurnInputItem,\n TurnStateDone,\n} from \"./server/index.js\";\nimport type { AgentChatServer } from \"./server/types.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n buildEditedUserMessageContent,\n buildSnapshotBeforeTurn,\n computeGroupRootBaseline,\n extractTurnUserMessageContent,\n prependOlderSessionHistory,\n projectSessionMessages,\n resolveGatewayBranchPreviousTurnIdForTurn,\n rootModelMessageIdsSinceBaseline,\n userMessageContentToText,\n type UserMessageContent,\n} from \"./convertTurnMessages.js\";\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport { loadSessionSnapshot } from \"./loadSessionSnapshot.js\";\nimport { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from \"./mcpAuth.js\";\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n collectRequiredActionInputs,\n findPausedAssistantMessage,\n messageHasPendingRequiredActions,\n type RequiredActionInput,\n} from \"./requiredActionInputs.js\";\nimport {\n createEmptySessionSnapshot,\n replaceSessionSnapshot,\n type SessionSnapshot,\n type SessionTurnRecord,\n} from \"./sessionSnapshot.js\";\nimport { resumeTurnStream, streamTurnContent } from \"./streamTurn.js\";\nimport {\n TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY,\n type RespondToToolApprovalOptions,\n} from \"./toolApproval.js\";\nimport {\n applyUserToolResponsesToFold,\n TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,\n type RespondToToolResponseOptions,\n} from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport type UseTrueFoundryAgentMessagesOptions = {\n server: AgentChatServer;\n sessionId: string | undefined;\n /** When true the thread is the currently selected (main) thread. */\n isMain?: boolean | undefined;\n /** URL-selected session may load before the thread list marks it as main. */\n isInitialSession?: boolean | undefined;\n listEventsConcurrency?: number | undefined;\n onError?: ((error: unknown) => void) | undefined;\n initializeSession?: () => Promise<{\n remoteId: string;\n externalId: string | undefined;\n }>;\n /** Maps a thread `remoteId` to the gateway session id used for turns. */\n resolveConversationSessionId?: (remoteId: string) => Promise<string>;\n /**\n * Optional per-turn headers for createTurn. Invoked once per `sendTurn` after\n * the session is resolved; return value is forwarded to `turn.execute`.\n */\n getTurnHeaders?: () => Promise<Record<string, string> | undefined>;\n};\n\nexport type SendTurnOptions =\n | {\n userMessage: UserMessageContent;\n previousTurnId?: string | null;\n /** Invoked only when the user turn fails before the gateway registers it. */\n onPreTurnFailure?: () => void;\n /**\n * When branching (edit/reset), the already-rewound history to send from.\n * Applied atomically with `pendingUser` so a stale React snapshot cannot\n * keep pre-branch turns while the new user message is appended.\n */\n branchFromSnapshot?: SessionSnapshot;\n /** Original history restored when a branch fails before turn.created. */\n branchRollbackSnapshot?: SessionSnapshot;\n }\n | { inputs: RequiredActionInput[] }\n | { resumeMcpAuth: true };\n\nfunction buildCompletedTurnState(\n completedAt: string,\n requiredActions: TurnStateDone[\"requiredActions\"] = [],\n): TurnStateDone {\n return {\n status: \"done\",\n requiredActions,\n completedAt,\n };\n}\n\n/**\n * Reconstructs the pending required actions a paused in-flight update carried,\n * so the pause survives `commitActiveStream`'s synthetic \"done\" state.\n *\n * `commitActiveStream` fabricates a `TurnStateDone` for the just-finished\n * stream, and the projection derives an assistant message's `requires-action`\n * status from `turn.state.requiredActions` (see `findApprovalRequiredInTurn` /\n * `findResponseRequiredInTurn` / `findMcpAuthRequired`). If we returned an empty\n * list here, the committed turn would look \"complete\", the projected message\n * would lose its `requires-action` status, and `findPausedAssistantMessage`\n * (used by `trySendCollectedRequiredActions`) would never see it — so answering\n * a tool approval or an `ask_user_question` would never send the resume turn.\n *\n * The paused update already carries the pause state: `status` is\n * `requires-action` and `metadata.custom` holds the pending thread id(s) (and,\n * for MCP, the server list). Only the thread id is read downstream, so an empty\n * `toolCalls` list is sufficient here — the resume inputs are collected from the\n * message content, not from these reconstructed actions.\n */\nexport function requiredActionsFromActiveUpdate(\n update: TurnStreamUpdate,\n): TurnStateDone[\"requiredActions\"] {\n const custom = update.metadata?.custom as TrueFoundryMessageCustomMetadata | undefined;\n const requiredActions: TurnStateDone[\"requiredActions\"] = [];\n const createdAt = new Date().toISOString();\n\n if (custom?.pendingMcpAuth === true && Array.isArray(custom.mcpServers)) {\n const mcpAuthRequired: McpAuthRequiredEvent = {\n type: \"mcp.auth_required\",\n id: generateId(),\n createdAt,\n mcpServers: custom.mcpServers,\n };\n requiredActions.push(mcpAuthRequired);\n }\n\n if (update.status?.type === \"requires-action\") {\n const approvalThreadId = custom?.[TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY];\n if (typeof approvalThreadId === \"string\") {\n const approvalRequired: ToolApprovalRequiredEvent = {\n type: \"tool.approval_required\",\n id: generateId(),\n createdAt,\n threadId: approvalThreadId,\n toolCalls: [],\n };\n requiredActions.push(approvalRequired);\n }\n\n const responseThreadId = custom?.[TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY];\n if (typeof responseThreadId === \"string\") {\n const responseRequired: ToolResponseRequiredEvent = {\n type: \"tool.response_required\",\n id: generateId(),\n createdAt,\n threadId: responseThreadId,\n toolCalls: [],\n };\n requiredActions.push(responseRequired);\n }\n }\n\n return requiredActions;\n}\n\nfunction buildUserTurnInput(content: UserMessageContent): TurnInputItem {\n return { type: \"user.message\", content };\n}\n\nfunction appendTurnInputs(\n base: TurnInputItem[],\n continuationInputs?: RequiredActionInput[],\n): TurnInputItem[] {\n if (continuationInputs == null || continuationInputs.length === 0) {\n return base;\n }\n return [...base, ...continuationInputs];\n}\n\nfunction commitActiveStream(\n snapshot: SessionSnapshot,\n continuationInputs?: RequiredActionInput[],\n): SessionSnapshot {\n const active = snapshot.activeStream;\n if (active == null || active.streamComplete !== true) {\n return snapshot;\n }\n\n const activeSandboxId = (\n active.update.metadata?.custom as { sandboxId?: string } | undefined\n )?.sandboxId;\n\n const completedState = buildCompletedTurnState(\n new Date().toISOString(),\n requiredActionsFromActiveUpdate(active.update),\n );\n const baseline =\n snapshot.groupRootBaseline ?? computeGroupRootBaseline(snapshot.turns);\n const rootModelMessageIds = rootModelMessageIdsSinceBaseline(\n snapshot.fold,\n baseline,\n );\n\n const lastTurn = snapshot.turns.at(-1);\n if (lastTurn?.id === active.turnId) {\n return replaceSessionSnapshot(snapshot, {\n turns: snapshot.turns.map((turn) =>\n turn.id === active.turnId\n ? {\n ...turn,\n state: completedState,\n input: appendTurnInputs(turn.input ?? [], continuationInputs),\n ...(rootModelMessageIds != null\n ? { rootModelMessageIds }\n : {}),\n ...(activeSandboxId != null ? { sandboxId: activeSandboxId } : {}),\n }\n : turn,\n ),\n pendingUser: undefined,\n activeStream: undefined,\n });\n }\n\n const record: SessionTurnRecord = {\n id: active.turnId,\n createdAt:\n snapshot.pendingUser?.createdAt.toISOString() ?? new Date().toISOString(),\n state: completedState,\n input: appendTurnInputs(\n snapshot.pendingUser\n ? [buildUserTurnInput(snapshot.pendingUser.content)]\n : [],\n continuationInputs,\n ),\n ...(snapshot.pendingUser != null\n ? { userText: userMessageContentToText(snapshot.pendingUser.content) }\n : {}),\n ...(rootModelMessageIds != null ? { rootModelMessageIds } : {}),\n ...(activeSandboxId != null ? { sandboxId: activeSandboxId } : {}),\n };\n\n return replaceSessionSnapshot(snapshot, {\n turns: [...snapshot.turns, record],\n pendingUser: undefined,\n activeStream: undefined,\n });\n}\n\nasync function resolveActiveSessionId(\n remoteId: string,\n resolveConversationSessionId?: (remoteId: string) => Promise<string>,\n): Promise<string> {\n if (resolveConversationSessionId != null) {\n return resolveConversationSessionId(remoteId);\n }\n return remoteId;\n}\n\nfunction findTurnIndex(snapshot: SessionSnapshot, turnId: string): number {\n const committedIndex = snapshot.turns.findIndex((turn) => turn.id === turnId);\n if (committedIndex !== -1) {\n return committedIndex;\n }\n if (snapshot.pendingUser?.turnId === turnId) {\n return snapshot.turns.length;\n }\n throw new Error(`Turn ${turnId} not found in session snapshot`);\n}\n\nfunction resolveTurnInput(\n snapshot: SessionSnapshot,\n turnId: string,\n): TurnInputItem[] | undefined {\n const turnRecord = snapshot.turns.find((turn) => turn.id === turnId);\n if (turnRecord?.input != null) {\n return turnRecord.input;\n }\n if (snapshot.pendingUser?.turnId === turnId) {\n return [{ type: \"user.message\", content: snapshot.pendingUser.content }];\n }\n return undefined;\n}\n\nexport function useTrueFoundryAgentMessages({\n server,\n sessionId,\n isMain,\n isInitialSession,\n listEventsConcurrency,\n onError,\n initializeSession,\n resolveConversationSessionId,\n getTurnHeaders,\n}: UseTrueFoundryAgentMessagesOptions) {\n const [snapshot, setSnapshot] = useState<SessionSnapshot>(createEmptySessionSnapshot);\n const [isRunning, setIsRunning] = useState(false);\n // Existing sessions have history pending from the first render. Starting at\n // false causes consumers to briefly render an empty thread before the load\n // effect runs and flips this flag to true.\n const [isLoading, setIsLoading] = useState(\n sessionId != null && (isMain !== false || isInitialSession === true),\n );\n const [isLoadingOlderHistory, setIsLoadingOlderHistory] = useState(false);\n const [loadRetryTrigger, setLoadRetryTrigger] = useState(0);\n\n const snapshotRef = useRef(snapshot);\n snapshotRef.current = snapshot;\n const loadOlderInflightRef = useRef<Promise<void> | null>(null);\n\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const resolveConversationSessionIdRef = useRef(resolveConversationSessionId);\n resolveConversationSessionIdRef.current = resolveConversationSessionId;\n const initializeSessionRef = useRef(initializeSession);\n initializeSessionRef.current = initializeSession;\n const getTurnHeadersRef = useRef(getTurnHeaders);\n getTurnHeadersRef.current = getTurnHeaders;\n\n const createdAtByMessageIdRef = useRef(new Map<string, Date>());\n const abortControllerRef = useRef<AbortController | null>(null);\n const activeRunRef = useRef<Promise<void> | null>(null);\n const runningTurnRef = useRef<Turn | undefined>(undefined);\n const loadGenerationRef = useRef(0);\n const streamGenerationRef = useRef(0);\n const lazilyCreatedSessionIdRef = useRef<string | undefined>(undefined);\n const initialLoadStartedForRef = useRef<string | undefined>(undefined);\n const skipInitialPromotionLoadForRef = useRef<string | undefined>(undefined);\n\n const projectOptions = useMemo(\n () => ({\n getCreatedAt: (messageId: string, fallback: Date) => {\n const cache = createdAtByMessageIdRef.current;\n const existing = cache.get(messageId);\n if (existing != null) {\n return existing;\n }\n cache.set(messageId, fallback);\n return fallback;\n },\n }),\n [],\n );\n\n const messages = useMemo(\n () => projectSessionMessages(snapshot, projectOptions),\n [snapshot, projectOptions],\n );\n\n const runStream = useCallback(\n (\n createStream: (signal: AbortSignal) => AsyncGenerator<TurnStreamUpdate>,\n /**\n * A mutable ref whose `.current` is the turn ID to use for\n * `activeStream.turnId`. Callers that capture the gateway turn ID\n * via `onTurnIdAvailable` update this ref in-place so that both the\n * pending-update flush and `commitActiveStream` always see the real\n * gateway ID rather than the locally-generated optimistic one.\n */\n turnIdRef: { current: string },\n isContinuation: boolean,\n ): Promise<void> => {\n const streamGeneration = ++streamGenerationRef.current;\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n setIsRunning(true);\n\n const run = (async () => {\n // Sub-agent turns can emit 100+ stream events per frame. Coalesce to one\n // setSnapshot per animation frame so assistant-ui does not remount the whole\n // message tree (UI hang). The buffer belongs to this stream only.\n let pendingStreamUpdate: {\n update: TurnStreamUpdate;\n isContinuation: boolean;\n } | null = null;\n let streamUpdateRaf: number | null = null;\n\n const flushPendingStreamUpdate = () => {\n streamUpdateRaf = null;\n const pending = pendingStreamUpdate;\n pendingStreamUpdate = null;\n if (\n pending == null ||\n streamGeneration !== streamGenerationRef.current\n ) {\n return;\n }\n const { update, isContinuation: pendingIsContinuation } = pending;\n setSnapshot((prev) =>\n replaceSessionSnapshot(prev, {\n activeStream: {\n // Read from the ref so we always use the latest ID,\n // including any gateway ID that arrived after the RAf\n // was scheduled.\n turnId: turnIdRef.current,\n update,\n isContinuation: pendingIsContinuation,\n },\n }),\n );\n };\n\n const applyStreamUpdate = (update: TurnStreamUpdate) => {\n pendingStreamUpdate = { update, isContinuation };\n if (streamUpdateRaf == null) {\n streamUpdateRaf = requestAnimationFrame(flushPendingStreamUpdate);\n }\n };\n\n try {\n for await (const update of createStream(abortController.signal)) {\n if (abortController.signal.aborted) {\n return;\n }\n applyStreamUpdate(update);\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n onErrorRef.current?.(error);\n throw error;\n } finally {\n if (streamUpdateRaf != null) {\n cancelAnimationFrame(streamUpdateRaf);\n streamUpdateRaf = null;\n }\n if (streamGeneration !== streamGenerationRef.current) {\n return;\n }\n flushPendingStreamUpdate();\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsRunning(false);\n setSnapshot((prev) => {\n if (prev.activeStream == null) {\n return prev;\n }\n const marked = replaceSessionSnapshot(prev, {\n activeStream: {\n ...prev.activeStream,\n streamComplete: true,\n },\n requiredActions: {\n approvals: new Map(),\n toolResponses: new Map(),\n },\n });\n return commitActiveStream(marked);\n });\n }\n })();\n\n activeRunRef.current = run;\n void run\n .catch(() => undefined)\n .finally(() => {\n if (activeRunRef.current === run) {\n activeRunRef.current = null;\n }\n });\n return run;\n },\n [onError],\n );\n\n const load = useCallback(async () => {\n // Reading the retry counter intentionally makes retryLoad recreate this callback.\n void loadRetryTrigger;\n if (sessionId == null) {\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(createEmptySessionSnapshot());\n return;\n }\n\n // Allow the URL-selected session one early load before assistant-ui marks\n // it main. Suppress only that first promotion; later selections still reload.\n const isEarlyInitialLoad =\n isMain === false &&\n isInitialSession === true &&\n initialLoadStartedForRef.current !== sessionId;\n if (isMain === false) {\n if (!isEarlyInitialLoad) return;\n initialLoadStartedForRef.current = sessionId;\n skipInitialPromotionLoadForRef.current = sessionId;\n } else if (\n isMain === true &&\n skipInitialPromotionLoadForRef.current === sessionId\n ) {\n skipInitialPromotionLoadForRef.current = undefined;\n return;\n }\n if (isInitialSession === true) {\n initialLoadStartedForRef.current = sessionId;\n }\n\n // When we are loading a *different* session the user has navigated away\n // from the lazily-created one — clear the guard so navigating back to it\n // later triggers a proper reload instead of silently skipping.\n if (lazilyCreatedSessionIdRef.current != null && sessionId !== lazilyCreatedSessionIdRef.current) {\n lazilyCreatedSessionIdRef.current = undefined;\n }\n\n if (sessionId === lazilyCreatedSessionIdRef.current) {\n return;\n }\n\n const generation = ++loadGenerationRef.current;\n ++streamGenerationRef.current;\n setIsRunning(false);\n abortControllerRef.current?.abort();\n loadOlderInflightRef.current = null;\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(createEmptySessionSnapshot());\n setIsLoading(true);\n setIsLoadingOlderHistory(false);\n\n try {\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n const loadedSnapshot = await loadSessionSnapshot(\n server,\n conversationSessionId,\n (snap) => {\n if (generation === loadGenerationRef.current) {\n setSnapshot(snap);\n }\n },\n );\n if (generation !== loadGenerationRef.current) {\n return;\n }\n\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(loadedSnapshot);\n runningTurnRef.current = loadedSnapshot.runningTurn;\n\n // History (and any seeded pendingUser for the in-flight turn) is\n // ready — clear loading before resuming. Awaiting the subscribe\n // stream here previously kept isLoading true for the entire\n // backend run, so reconnect UIs stayed on shimmers even though\n // subscribe was already live.\n setIsLoading(false);\n\n if (loadedSnapshot.runningTurn != null) {\n const turn = loadedSnapshot.runningTurn;\n const isContinuation = !extractTurnUserText(turn.input);\n // TODO: pass afterSequenceNumber once stream ingestion tracks sequence numbers.\n // Use loadedSnapshot directly — snapshotRef.current still points at\n // the empty snapshot cleared above until the setSnapshot(loadedSnapshot)\n // call re-renders.\n void runStream(\n (signal) =>\n resumeTurnStream(\n server,\n conversationSessionId,\n turn.id,\n loadedSnapshot.fold,\n signal,\n undefined,\n loadedSnapshot.groupRootBaseline,\n ),\n { current: turn.id },\n isContinuation,\n ).catch(() => undefined);\n }\n } catch (error) {\n if (generation === loadGenerationRef.current) {\n if (isEarlyInitialLoad) {\n // Allow retryLoad while still backgrounded (before isMain promotion).\n initialLoadStartedForRef.current = undefined;\n skipInitialPromotionLoadForRef.current = undefined;\n }\n onErrorRef.current?.(error);\n }\n throw error;\n } finally {\n if (generation === loadGenerationRef.current) {\n setIsLoading(false);\n }\n }\n }, [\n server,\n runStream,\n sessionId,\n loadRetryTrigger,\n isMain,\n isInitialSession,\n ]);\n\n useEffect(() => {\n void load().catch(() => undefined);\n }, [load]);\n\n const sendTurn = useCallback(\n async (options: SendTurnOptions) => {\n // A turn.created event means the gateway registered the user message.\n // Errors after that point must keep the message in chat.\n let gatewayTurnAccepted = false;\n let pendingUserWasSet = false;\n let runStreamStarted = false;\n let pendingUserTurnId: string | undefined;\n\n try {\n let activeSessionId = sessionId;\n if (activeSessionId == null) {\n if (initializeSessionRef.current == null) {\n throw new Error(\"Cannot send a turn without an active session.\");\n }\n const { remoteId } = await initializeSessionRef.current();\n activeSessionId = remoteId;\n lazilyCreatedSessionIdRef.current = remoteId;\n }\n\n const conversationSessionId = await resolveActiveSessionId(\n activeSessionId,\n resolveConversationSessionIdRef.current,\n );\n const turnHeaders = await getTurnHeadersRef.current?.();\n const streamHeaders =\n turnHeaders != null ? { headers: turnHeaders } : {};\n const isContinuation =\n \"inputs\" in options ||\n (\"resumeMcpAuth\" in options && options.resumeMcpAuth === true);\n const continuationTurnId = snapshotRef.current.activeStream?.turnId;\n const turnId =\n isContinuation && continuationTurnId != null\n ? continuationTurnId\n : generateId();\n // First turns must send previousTurnId: \"none\".\n const isFirstTurnInSession =\n \"userMessage\" in options &&\n options.previousTurnId === undefined &&\n snapshotRef.current.turns.length === 0 &&\n snapshotRef.current.pendingUser == null &&\n snapshotRef.current.activeStream == null;\n\n // Mutable ref so runStream always reads the latest ID. For new\n // user-message turns the local `generateId()` value is replaced\n // with the gateway-assigned ID once the first SSE event arrives.\n const turnIdRef = { current: turnId };\n\n if (\"inputs\" in options) {\n applyUserToolResponsesToFold(\n snapshotRef.current.fold,\n options.inputs,\n );\n }\n\n const branchBase =\n \"userMessage\" in options ? options.branchFromSnapshot : undefined;\n\n let groupRootBaseline: readonly string[] | undefined;\n\n if (branchBase != null && \"userMessage\" in options) {\n // Atomic apply: never merge pendingUser onto a stale React `prev`\n // that still holds pre-branch turns (edit would show old + new).\n const rootBucket = branchBase.fold.threads.get(ROOT_THREAD_ID);\n groupRootBaseline = [...(rootBucket?.modelMessageIds ?? [])];\n const nextSnapshot = replaceSessionSnapshot(branchBase, {\n pendingUser: {\n turnId,\n content: options.userMessage,\n createdAt: new Date(),\n },\n activeStream: undefined,\n groupRootBaseline,\n });\n snapshotRef.current = nextSnapshot;\n setSnapshot(nextSnapshot);\n pendingUserWasSet = true;\n pendingUserTurnId = turnId;\n } else {\n setSnapshot((prev) =>\n commitActiveStream(\n prev,\n \"inputs\" in options ? options.inputs : undefined,\n ),\n );\n\n if (\"userMessage\" in options) {\n const rootBucket =\n snapshotRef.current.fold.threads.get(ROOT_THREAD_ID);\n groupRootBaseline = [...(rootBucket?.modelMessageIds ?? [])];\n setSnapshot((prev) => {\n const next = replaceSessionSnapshot(prev, {\n pendingUser: {\n turnId,\n content: options.userMessage,\n createdAt: new Date(),\n },\n activeStream: undefined,\n groupRootBaseline,\n });\n snapshotRef.current = next;\n return next;\n });\n pendingUserWasSet = true;\n pendingUserTurnId = turnId;\n } else {\n groupRootBaseline =\n snapshotRef.current.groupRootBaseline ??\n computeGroupRootBaseline(snapshotRef.current.turns);\n }\n }\n\n runStreamStarted = true;\n await runStream(\n (signal) => {\n if (\"inputs\" in options) {\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n { inputs: options.inputs, ...streamHeaders },\n signal,\n groupRootBaseline,\n );\n }\n if (\"resumeMcpAuth\" in options) {\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n { resumeMcpAuth: true, ...streamHeaders },\n signal,\n groupRootBaseline,\n );\n }\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n {\n userMessage: options.userMessage,\n ...(options.previousTurnId !== undefined\n ? { previousTurnId: options.previousTurnId ?? \"none\" }\n : isFirstTurnInSession\n ? { previousTurnId: \"none\" }\n : {}),\n ...streamHeaders,\n },\n signal,\n groupRootBaseline,\n // Rename the optimistic local ID to the gateway turn ID\n // so that edit/retry can resolve the turn via the gateway.\n (gatewayTurnId) => {\n const oldId = turnIdRef.current;\n // turn.created proves the gateway registered the message.\n gatewayTurnAccepted = true;\n if (gatewayTurnId === oldId) return;\n turnIdRef.current = gatewayTurnId;\n // Rename in the ref immediately so any synchronous read\n // (e.g. commitActiveStream) sees the correct ID.\n const renamePendingUser = (prev: SessionSnapshot): SessionSnapshot => {\n if (prev.pendingUser?.turnId !== oldId) return prev;\n return replaceSessionSnapshot(prev, {\n pendingUser: { ...prev.pendingUser, turnId: gatewayTurnId },\n });\n };\n snapshotRef.current = renamePendingUser(snapshotRef.current);\n setSnapshot(renamePendingUser);\n },\n );\n },\n turnIdRef,\n isContinuation,\n );\n } catch (error) {\n if (\"userMessage\" in options && !gatewayTurnAccepted) {\n const branchRollbackSnapshot =\n options.branchRollbackSnapshot;\n const canRestoreBranch =\n branchRollbackSnapshot != null &&\n (snapshotRef.current === options.branchFromSnapshot ||\n snapshotRef.current.pendingUser?.turnId ===\n pendingUserTurnId);\n if (canRestoreBranch) {\n snapshotRef.current = branchRollbackSnapshot;\n setSnapshot(branchRollbackSnapshot);\n } else if (pendingUserWasSet) {\n const clearPendingUser = (\n previous: SessionSnapshot,\n ): SessionSnapshot => {\n if (previous.pendingUser?.turnId !== pendingUserTurnId) {\n return previous;\n }\n return replaceSessionSnapshot(previous, {\n pendingUser: undefined,\n });\n };\n snapshotRef.current = clearPendingUser(snapshotRef.current);\n setSnapshot(clearPendingUser);\n }\n options.onPreTurnFailure?.();\n }\n if (!runStreamStarted) {\n onErrorRef.current?.(error);\n }\n throw error;\n }\n },\n [server, runStream, sessionId],\n );\n\n const cancel = useCallback(async () => {\n if (sessionId == null) {\n abortControllerRef.current?.abort();\n return;\n }\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n // Request cancellation but keep consuming the stream. After cancel(),\n // the backend gracefully closes the SSE stream: it emits a terminal\n // turn.done event and then ends the stream, which lets the active run\n // drain to completion on its own instead of being torn down mid-flight.\n await server.cancelSession({ sessionId: conversationSessionId }).catch(() => undefined);\n // Wait for the in-flight stream to finish draining. No explicit\n // reconcile is needed here — the cancelled turn is terminal and local\n // state reconciles against the event log on the next session load.\n await activeRunRef.current?.catch(() => undefined);\n }, [server, sessionId]);\n\n const isRunningRef = useRef(isRunning);\n isRunningRef.current = isRunning;\n\n const trySendCollectedRequiredActions = useCallback(\n (nextSnapshot: SessionSnapshot) => {\n if (isRunningRef.current) {\n return;\n }\n const projected = projectSessionMessages(nextSnapshot, projectOptions);\n const paused = findPausedAssistantMessage(projected);\n if (paused == null || messageHasPendingRequiredActions(paused)) {\n return;\n }\n const inputs = collectRequiredActionInputs(paused);\n if (inputs.length > 0) {\n // sendTurn/runStream already report via onError; swallow to avoid duplicates.\n void sendTurn({ inputs }).catch(() => undefined);\n }\n },\n [projectOptions, sendTurn],\n );\n\n const respondToToolApproval = useCallback(\n (response: RespondToToolApprovalOptions) => {\n const prev = snapshotRef.current;\n const approvals = new Map(prev.requiredActions.approvals);\n approvals.set(response.approvalId, {\n approved: response.approved,\n ...(response.reason != null ? { reason: response.reason } : {}),\n });\n const nextSnapshot = replaceSessionSnapshot(prev, {\n requiredActions: {\n ...prev.requiredActions,\n approvals,\n },\n });\n setSnapshot(nextSnapshot);\n trySendCollectedRequiredActions(nextSnapshot);\n },\n [trySendCollectedRequiredActions],\n );\n\n const respondToToolResponse = useCallback(\n (response: RespondToToolResponseOptions) => {\n const prev = snapshotRef.current;\n const toolResponses = new Map(prev.requiredActions.toolResponses);\n toolResponses.set(response.toolCallId, { content: response.content });\n const nextSnapshot = replaceSessionSnapshot(prev, {\n requiredActions: {\n ...prev.requiredActions,\n toolResponses,\n },\n });\n setSnapshot(nextSnapshot);\n trySendCollectedRequiredActions(nextSnapshot);\n },\n [trySendCollectedRequiredActions],\n );\n\n const resumeRun = useCallback(async () => {\n const turn = runningTurnRef.current;\n if (turn == null) {\n return;\n }\n // TODO: pass afterSequenceNumber once stream ingestion tracks sequence numbers.\n await runStream(\n (signal) =>\n resumeTurnStream(\n server,\n turn.sessionId,\n turn.id,\n snapshotRef.current.fold,\n signal,\n undefined,\n snapshotRef.current.groupRootBaseline,\n ),\n { current: turn.id },\n true,\n );\n }, [runStream, server]);\n\n const branchFromTurn = useCallback(\n async (turnId: string, userMessage: UserMessageContent) => {\n let committed: SessionSnapshot;\n let previousTurnId: string;\n let rewound: SessionSnapshot;\n try {\n let activeSessionId = sessionId;\n if (activeSessionId == null) {\n throw new Error(\"Cannot branch from a turn without an active session.\");\n }\n\n committed = commitActiveStream(snapshotRef.current);\n setSnapshot(committed);\n\n await cancel();\n\n const conversationSessionId = await resolveActiveSessionId(\n activeSessionId,\n resolveConversationSessionIdRef.current,\n );\n previousTurnId = await resolveGatewayBranchPreviousTurnIdForTurn(\n server,\n conversationSessionId,\n turnId,\n );\n rewound = await buildSnapshotBeforeTurn(\n server,\n conversationSessionId,\n turnId,\n listEventsConcurrency,\n );\n createdAtByMessageIdRef.current = new Map();\n // Keep the ref aligned before awaiting sendTurn so any intermediate\n // reads (and the atomic pendingUser apply) see the rewound history.\n snapshotRef.current = rewound;\n setSnapshot(rewound);\n } catch (error) {\n // Setup failures never reach sendTurn/runStream reporting.\n onErrorRef.current?.(error);\n throw error;\n }\n\n // sendTurn/runStream own error reporting for the turn itself.\n await sendTurn({\n userMessage,\n previousTurnId,\n branchFromSnapshot: rewound,\n branchRollbackSnapshot: committed,\n });\n },\n [\n cancel,\n server,\n listEventsConcurrency,\n sendTurn,\n sessionId,\n ],\n );\n\n const resetFromTurn = useCallback(\n async (turnId: string) => {\n const committed = commitActiveStream(snapshotRef.current);\n const originalInput = resolveTurnInput(committed, turnId);\n if (originalInput == null) {\n const error = new Error(`Turn ${turnId} not found in session snapshot`);\n onErrorRef.current?.(error);\n throw error;\n }\n const userMessage = extractTurnUserMessageContent(originalInput);\n await branchFromTurn(turnId, userMessage);\n },\n [branchFromTurn],\n );\n\n const editFromTurn = useCallback(\n async (turnId: string, editedText: string) => {\n const committed = commitActiveStream(snapshotRef.current);\n const originalInput = resolveTurnInput(committed, turnId);\n if (originalInput == null) {\n const error = new Error(`Turn ${turnId} not found in session snapshot`);\n onErrorRef.current?.(error);\n throw error;\n }\n const userMessage = buildEditedUserMessageContent(\n editedText,\n originalInput,\n );\n await branchFromTurn(turnId, userMessage);\n },\n [branchFromTurn],\n );\n\n const retryLoad = useCallback(() => {\n setLoadRetryTrigger((n) => n + 1);\n }, []);\n\n const hasOlderHistory = snapshot.historyPagination?.hasOlder === true;\n\n const loadOlderHistory = useCallback(async () => {\n if (sessionId == null || isMain === false) {\n return;\n }\n if (loadOlderInflightRef.current != null) {\n return loadOlderInflightRef.current;\n }\n\n const current = snapshotRef.current;\n if (current.historyPagination?.hasOlder !== true) {\n return;\n }\n if (current.historyPagination.olderPageToken == null) {\n return;\n }\n\n const generation = loadGenerationRef.current;\n setIsLoadingOlderHistory(true);\n\n const run = (async () => {\n try {\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n const next = await prependOlderSessionHistory(\n server,\n conversationSessionId,\n snapshotRef.current,\n );\n if (generation !== loadGenerationRef.current) {\n return;\n }\n setSnapshot(next);\n } catch (error) {\n if (generation === loadGenerationRef.current) {\n onErrorRef.current?.(error);\n }\n throw error;\n } finally {\n if (generation === loadGenerationRef.current) {\n setIsLoadingOlderHistory(false);\n }\n loadOlderInflightRef.current = null;\n }\n })();\n\n loadOlderInflightRef.current = run;\n return run;\n }, [server, isMain, sessionId]);\n\n return {\n messages,\n isRunning,\n isLoading,\n isLoadingOlderHistory,\n hasOlderHistory,\n loadOlderHistory,\n retryLoad,\n sendTurn,\n cancel,\n respondToToolApproval,\n respondToToolResponse,\n resumeRun,\n branchFromTurn,\n resetFromTurn,\n editFromTurn,\n };\n}\n\nexport { findPausedAssistantMessage, MCP_AUTH_RESUME_RUN_CUSTOM_KEY };\n","import type { AgentChatServer } from \"./server/types.js\";\n\nimport { buildSnapshotFromSessionEvents } from \"./convertTurnMessages.js\";\nimport { getSession } from \"./sessions.js\";\nimport type { SessionSnapshot } from \"./sessionSnapshot.js\";\n\nconst inflightBySessionId = new Map<string, Promise<SessionSnapshot>>();\n\n/**\n * Loads a session snapshot once per concurrent burst for a given session id.\n * React Strict Mode and overlapping fetch/load paths share the same in-flight\n * request instead of duplicating getSession + listEvents calls.\n *\n * `onProgress` is called after each complete turn is ingested so the caller\n * can update the UI progressively while history is being processed.\n */\nexport function loadSessionSnapshot(\n server: AgentChatServer,\n sessionId: string,\n onProgress?: (snap: SessionSnapshot) => void,\n): Promise<SessionSnapshot> {\n let inflight = inflightBySessionId.get(sessionId);\n if (inflight == null) {\n inflight = getSession(server, sessionId)\n .then(() => buildSnapshotFromSessionEvents(server, sessionId, onProgress))\n .finally(() => {\n if (inflightBySessionId.get(sessionId) === inflight) {\n inflightBySessionId.delete(sessionId);\n }\n });\n inflightBySessionId.set(sessionId, inflight);\n }\n return inflight;\n}\n","import type { ThreadMessage } from \"@assistant-ui/core\";\nimport type {\n TurnInputItem,\n UserToolApprovalEvent,\n UserToolResponseEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n collectApprovalInputs,\n messageHasPendingApprovals,\n} from \"./toolApproval.js\";\nimport {\n collectResponseInputs,\n messageHasPendingResponses,\n} from \"./toolResponse.js\";\n\nexport type RequiredActionInput = Extract<\n TurnInputItem,\n UserToolApprovalEvent | UserToolResponseEvent\n>;\n\nexport function messageHasPendingRequiredActions(\n message: ThreadMessage | undefined,\n): boolean {\n return (\n messageHasPendingApprovals(message) || messageHasPendingResponses(message)\n );\n}\n\nexport function collectRequiredActionInputs(\n message: ThreadMessage,\n defaultThreadId: string = ROOT_THREAD_ID,\n): RequiredActionInput[] {\n if (messageHasPendingRequiredActions(message)) {\n return [];\n }\n return [\n ...collectApprovalInputs(message, defaultThreadId),\n ...collectResponseInputs(message, defaultThreadId),\n ];\n}\n\nexport function isRequiredActionInput(\n item: TurnInputItem,\n): item is RequiredActionInput {\n return (\n item.type === \"user.tool_approval\" || item.type === \"user.tool_response\"\n );\n}\n\nexport function findPausedAssistantMessage(\n messages: readonly ThreadMessage[],\n): Extract<ThreadMessage, { role: \"assistant\" }> | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const candidate = messages[i];\n if (\n candidate?.role === \"assistant\" &&\n candidate.status?.type === \"requires-action\"\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n","import type {\n AgentChatServer,\n PreviousTurnIdInput,\n TurnInputItem,\n} from \"./server/types.js\";\nimport type { TurnStreamData } from \"./server/events.js\";\n\nimport {\n streamTurnEvents,\n type UserMessageContent,\n} from \"./convertTurnMessages.js\";\nimport { PeerThreadFoldState } from \"./foldPeerThreads.js\";\nimport type { RequiredActionInput } from \"./requiredActionInputs.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport type StreamTurnOptions = {\n userMessage?: UserMessageContent;\n resumeMcpAuth?: boolean;\n inputs?: RequiredActionInput[];\n /**\n * Branch anchor for createTurn. Omit for `\"auto\"`. Pass `\"none\"` for a fresh\n * root turn.\n */\n previousTurnId?: PreviousTurnIdInput;\n /** Extra headers for the turn request. */\n headers?: Record<string, string>;\n};\n\nfunction buildTurnInput(options: StreamTurnOptions): TurnInputItem[] {\n if (options.inputs != null) {\n return options.inputs;\n }\n if (options.resumeMcpAuth === true) {\n return [];\n }\n return [{ type: \"user.message\", content: options.userMessage ?? \"\" }];\n}\n\nfunction bindAbort(\n server: AgentChatServer,\n sessionId: string,\n abortSignal: AbortSignal,\n): () => void {\n const onAbort = () => {\n void server.cancelSession({ sessionId }).catch(() => undefined);\n };\n if (abortSignal.aborted) {\n onAbort();\n return onAbort;\n }\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n return onAbort;\n}\n\nexport async function* streamTurnContent(\n server: AgentChatServer,\n sessionId: string,\n foldState: PeerThreadFoldState,\n options: StreamTurnOptions,\n abortSignal: AbortSignal,\n groupRootBaseline?: readonly string[],\n /**\n * Called once with the turn ID as soon as it becomes available (first\n * `turn.created` SSE event). Use this to reconcile the locally-generated\n * optimistic ID with the real turn ID.\n */\n onTurnIdAvailable?: (turnId: string) => void,\n): AsyncGenerator<TurnStreamUpdate> {\n const onAbort = bindAbort(server, sessionId, abortSignal);\n if (abortSignal.aborted) {\n return;\n }\n\n let turnIdNotified = false;\n const notifyTurnId = (turnId: string) => {\n if (!turnIdNotified) {\n onTurnIdAvailable?.(turnId);\n turnIdNotified = true;\n }\n };\n\n const stream: AsyncIterable<TurnStreamData> = server.createTurn({\n sessionId,\n input: buildTurnInput(options),\n previousTurnId: options.previousTurnId ?? \"auto\",\n abortSignal,\n ...(options.headers != null ? { headers: options.headers } : {}),\n });\n\n try {\n for await (const update of streamTurnEvents(\n stream,\n foldState,\n groupRootBaseline,\n notifyTurnId,\n )) {\n yield update;\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n throw error;\n } finally {\n abortSignal.removeEventListener(\"abort\", onAbort);\n }\n}\n\n/** TODO: wire `afterSequenceNumber` from the last ingested stream event to skip replay on reconnect. */\nexport async function* resumeTurnStream(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n foldState: PeerThreadFoldState,\n abortSignal: AbortSignal,\n afterSequenceNumber?: number,\n groupRootBaseline?: readonly string[],\n): AsyncGenerator<TurnStreamUpdate> {\n if (server.subscribeToTurn == null) {\n throw new Error(\n \"resumeTurnStream requires AgentChatServer.subscribeToTurn\",\n );\n }\n\n const onAbort = () => {\n void server.cancelSession({ sessionId }).catch(() => undefined);\n };\n if (abortSignal.aborted) {\n onAbort();\n return;\n }\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n yield* streamTurnEvents(\n server.subscribeToTurn({\n sessionId,\n turnId,\n ...(afterSequenceNumber != null\n ? { afterSequenceNumber }\n : {}),\n abortSignal,\n }),\n foldState,\n groupRootBaseline,\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n throw error;\n } finally {\n abortSignal.removeEventListener(\"abort\", onAbort);\n }\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"./server/types.js\";\nimport { sessionListStartTimestamp } from \"./sessionListStartTimestamp.js\";\nimport {\n sessionDisplayTitle,\n sessionToThreadMetadata,\n} from \"./sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\n/**\n * Read-only thread-list adapter backed by `AgentChatServer.listSessions`.\n * Hosts that previously used listOwnedSessions should filter in their server impl.\n */\nexport function createTrueFoundryOwnedSessionsThreadListAdapter(options: {\n server: AgentChatServer;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(session, sessionDisplayTitle(session)),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize() {\n throw new Error(\n \"Owned sessions history adapter is read-only; create sessions via a named or draft runtime.\",\n );\n },\n\n async fetch(remoteId) {\n const session = await server.getSession({ sessionId: remoteId });\n return sessionToThreadMetadata(session, sessionDisplayTitle(session));\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n EMPTY_DRAFT_EXTRAS,\n trueFoundryExtras,\n type TrueFoundryDraftRuntimeExtras,\n} from \"./truefoundryExtras.js\";\nimport type { RespondToToolApprovalOptions } from \"./toolApproval.js\";\nimport type { RespondToToolResponseOptions } from \"./toolResponse.js\";\n\n/** Pending tool approvals plus a respond action. */\nexport const useTrueFoundryApprovals = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingApprovals ?? [],\n respond:\n extras?.respondToToolApproval ??\n (() => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Pending ask-user tool responses plus a respond action. */\nexport const useTrueFoundryToolResponses = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingToolResponses ?? [],\n respond:\n extras?.respondToToolResponse ??\n ((_response: RespondToToolResponseOptions) => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Pending MCP OAuth plus a resume action. */\nexport const useTrueFoundryMcpAuth = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingMcpAuth ?? null,\n resume:\n extras?.resumeMcpAuth ??\n (async () => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Returns a function to respond to a tool approval from any render context. */\nexport const useTrueFoundryRespondToToolApproval = () => {\n const aui = useAui();\n return (response: RespondToToolApprovalOptions) =>\n trueFoundryExtras.get(aui).respondToToolApproval(response);\n};\n\n/** Returns a function to respond to a pending tool response from any render context. */\nexport const useTrueFoundryRespondToToolResponse = () => {\n const aui = useAui();\n return (response: RespondToToolResponseOptions) =>\n trueFoundryExtras.get(aui).respondToToolResponse(response);\n};\n\n/** Returns a function to resume after MCP OAuth from any render context. */\nexport const useTrueFoundryResumeMcpAuth = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).resumeMcpAuth();\n};\n\n/** Current sandboxId for this session, if a sandbox has been created. */\nexport const useTrueFoundrySandboxId = (): string | undefined =>\n trueFoundryExtras.use((e) => e.sandboxId, undefined);\n\n/** Turn that produced the message being rendered. Only defined inside a message scope. */\nexport const useTrueFoundryTurnId = (): string | undefined =>\n useAuiState(\n (state) =>\n (state.message.metadata?.custom as TrueFoundryMessageCustomMetadata | undefined)\n ?.turnId,\n );\n\n/**\n * Returns a function to download a file the current turn wrote to its sandbox. Must be called\n * from a message scope, since the artifact belongs to the turn that rendered it.\n */\nexport const useTrueFoundryDownloadSandboxFile = () => {\n const aui = useAui();\n const turnId = useTrueFoundryTurnId();\n return (path: string) => {\n if (turnId == null) {\n throw new Error(\n \"Downloading a sandbox file requires a message scope to resolve its turn.\",\n );\n }\n return trueFoundryExtras.get(aui).downloadSandboxFile({ turnId, path });\n };\n};\n\n/** Returns a function to cancel the current run from any render context. */\nexport const useTrueFoundryCancel = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).cancel();\n};\n\n/** Returns a function to reload (retry) the current session from any render context. */\nexport const useTrueFoundryReload = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).reload();\n};\n\n/** Older history pagination state plus a load-more action for scroll-up. */\nexport const useTrueFoundryHistoryPagination = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n hasOlderHistory: extras?.hasOlderHistory ?? false,\n isLoadingOlderHistory: extras?.isLoadingOlderHistory ?? false,\n loadOlderHistory:\n extras?.loadOlderHistory ??\n (async () => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Returns a function to reset (re-submit) a user turn from any render context. */\nexport const useTrueFoundryResetFromTurn = () => {\n const aui = useAui();\n return (turnId: string) => trueFoundryExtras.get(aui).resetFromTurn(turnId);\n};\n\n/** Current draft agent spec and sync state (draft mode only). */\nexport const useTrueFoundryAgentSpec = () => {\n const extras = trueFoundryExtras.use((e) => e.draft, null);\n\n return useMemo(\n () => ({ ...EMPTY_DRAFT_EXTRAS, ...extras }),\n [extras],\n );\n};\n\n/** Returns a draft spec updater from any render context. */\nexport const useTrueFoundryUpdateAgentSpec = () => {\n const aui = useAui();\n return (update: Parameters<TrueFoundryDraftRuntimeExtras[\"updateAgentSpec\"]>[0]) =>\n trueFoundryExtras.get(aui).draft?.updateAgentSpec(update);\n};\n\n","import {\n generateId,\n type AttachmentAdapter,\n type PendingAttachment,\n} from \"@assistant-ui/core\";\n\nconst bytesToBase64 = (bytes: Uint8Array): string =>\n globalThis.Buffer.from(bytes).toString(\"base64\");\n\nconst getFileDataURL = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n const buffer = await file.arrayBuffer();\n return `data:${file.type};base64,${bytesToBase64(new Uint8Array(buffer))}`;\n }\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n};\n\n/**\n * Reads composer files into `CompleteAttachment` `file` parts for send.\n * Wire via `adapters: { attachments: trueFoundryAttachmentAdapter }`.\n */\nexport const trueFoundryAttachmentAdapter: AttachmentAdapter = {\n accept: \"*\",\n async add({ file }) {\n return {\n id: generateId(),\n type: \"file\",\n name: file.name,\n file,\n contentType: file.type,\n content: [],\n status: {\n type: \"requires-action\",\n reason: \"composer-send\",\n },\n };\n },\n async send(attachment: PendingAttachment) {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n mimeType: attachment.contentType ?? \"\",\n filename: attachment.name,\n data: await getFileDataURL(attachment.file),\n },\n ],\n };\n },\n async remove() {},\n};\n"],"mappings":"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","names":["useCallback","useMemo","useRef","useState","existing","bucket","itemsAsc","parseDataUriMime","THREAD_LIST_PAGE_SIZE","useCallback","useEffect","useMemo","useRef","useState","inflightBySessionId","useState","useRef","useMemo","useCallback","useEffect","useRef","useCallback","useState","useMemo","THREAD_LIST_PAGE_SIZE","useMemo","useAui","useAuiState","useMemo","useAui","useAuiState","generateId"]}
1
+ {"version":3,"sources":["../src/useTrueFoundryAgentRuntime.ts","../src/constants.ts","../src/toolApproval.ts","../src/askUserQuestion.ts","../src/createSubAgent.ts","../src/modelMessageImageContent.ts","../src/modelMessageContent.ts","../src/foldPeerThreads.ts","../src/toolResponse.ts","../src/collectPending.ts","../src/listPages.ts","../src/extractTurnUserText.ts","../src/mcpAuth.ts","../src/turnEventHelpers.ts","../src/sessionSnapshot.ts","../src/convertTurnMessages.ts","../src/draft/draftSessionBridge.ts","../src/sessionListStartTimestamp.ts","../src/draft/agentSpec.ts","../src/sessionThreadMetadata.ts","../src/draft/truefoundryDraftThreadListAdapter.ts","../src/truefoundryExtras.ts","../src/sessions.ts","../src/truefoundryThreadListAdapter.ts","../src/types.ts","../src/draft/useDraftAgentSpec.ts","../src/useTrueFoundryAgentMessages.ts","../src/loadSessionSnapshot.ts","../src/requiredActionInputs.ts","../src/streamTurn.ts","../src/truefoundryOwnedSessionsThreadListAdapter.ts","../src/hooks.ts","../src/attachmentAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport {\n pickExternalStoreSharedOptions,\n type AppendMessage,\n type ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport {\n useExternalStoreRuntime,\n useRemoteThreadListRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { MutableRefObject } from \"react\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport type { AgentSpec } from \"./server/types.js\";\nimport {\n collectPendingApprovals,\n collectPendingToolResponses,\n derivePendingMcpAuth,\n deriveSandboxId,\n} from \"./collectPending.js\";\nimport {\n buildUserMessageContent,\n extractEditedText,\n parseTurnIdFromMessageId,\n userMessageContentToText,\n} from \"./convertTurnMessages.js\";\nimport {\n createDraftSessionBridge,\n DRAFT_SESSION_LAST_UPDATED_AT_HEADER,\n} from \"./draft/draftSessionBridge.js\";\nimport { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from \"./mcpAuth.js\";\nimport { createTrueFoundryDraftThreadListAdapter } from \"./draft/truefoundryDraftThreadListAdapter.js\";\nimport { trueFoundryExtras } from \"./truefoundryExtras.js\";\nimport { createTrueFoundryThreadListAdapter } from \"./truefoundryThreadListAdapter.js\";\nimport type { UseTrueFoundryAgentRuntimeOptions } from \"./types.js\";\nimport { resolveTrueFoundryAgentRuntimeOptions } from \"./types.js\";\nimport { useDraftAgentSpec } from \"./draft/useDraftAgentSpec.js\";\nimport { useTrueFoundryAgentMessages } from \"./useTrueFoundryAgentMessages.js\";\n\nfunction useTrueFoundryAgentRuntimeImpl(\n options: ReturnType<typeof resolveTrueFoundryAgentRuntimeOptions>,\n pendingAgentSpecRef: MutableRefObject<AgentSpec | undefined>,\n) {\n const {\n server,\n agent,\n adapters,\n onError,\n listEventsConcurrency,\n ...sharedOptions\n } = options;\n\n const draftBridgeRef = useRef(\n agent.mode === \"draft\" ? createDraftSessionBridge(server) : null,\n );\n\n const draftSessionId = useAuiState(\n (state) =>\n agent.mode === \"draft\"\n ? (state.threadListItem.remoteId ?? undefined)\n : undefined,\n );\n const sessionId = useAuiState((state) => state.threadListItem.remoteId ?? undefined);\n const isMain = useAuiState(\n (state) => state.threads.mainThreadId === state.threadListItem.id,\n );\n // On a hard refresh, the URL session runtime mounts before assistant-ui\n // promotes it to the main thread. Allow that one session to hydrate early.\n const isInitialSession =\n sessionId != null && sessionId === options.initialSessionId;\n\n const draftSpec = useDraftAgentSpec({\n draftSessionId,\n draftBridge: draftBridgeRef.current,\n defaultAgentSpec:\n agent.mode === \"draft\" ? agent.defaultAgentSpec : { model: { name: \"\" } },\n onAgentSpecChange: agent.mode === \"draft\" ? agent.onAgentSpecChange : undefined,\n onError,\n });\n\n const takeTurnHeaderTimestampRef = useRef(draftSpec.takeTurnHeaderTimestamp);\n takeTurnHeaderTimestampRef.current = draftSpec.takeTurnHeaderTimestamp;\n\n const getTurnHeaders = useCallback(async () => {\n if (agent.mode !== \"draft\") {\n return undefined;\n }\n const updatedAt = await takeTurnHeaderTimestampRef.current();\n if (updatedAt == null) {\n return undefined;\n }\n return { [DRAFT_SESSION_LAST_UPDATED_AT_HEADER]: updatedAt };\n }, [agent.mode]);\n\n const aui = useAui();\n const initializeSession = useCallback(\n () => aui.threadListItem().initialize(),\n [aui],\n );\n const runtimeAdapters = useRuntimeAdapters();\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const {\n messages,\n isRunning,\n resumeUnavailable,\n isLoading,\n isLoadingOlderHistory,\n hasOlderHistory,\n loadOlderHistory,\n sendTurn,\n cancel,\n respondToToolApproval,\n respondToToolResponse,\n resumeRun,\n editFromTurn,\n resetFromTurn,\n retryLoad,\n } = useTrueFoundryAgentMessages({\n server,\n sessionId,\n isMain,\n isInitialSession,\n listEventsConcurrency,\n onError,\n initializeSession,\n getTurnHeaders: agent.mode === \"draft\" ? getTurnHeaders : undefined,\n });\n\n if (agent.mode === \"draft\" && draftSpec.agentSpec != null) {\n pendingAgentSpecRef.current = draftSpec.agentSpec;\n }\n\n const pendingApprovals = useMemo(\n () => collectPendingApprovals(messages),\n [messages],\n );\n const pendingToolResponses = useMemo(\n () => collectPendingToolResponses(messages),\n [messages],\n );\n const pendingMcpAuth = useMemo(() => derivePendingMcpAuth(messages), [messages]);\n const sandboxId = useMemo(() => deriveSandboxId(messages), [messages]);\n\n const resumeMcpAuth = useMemo(\n () => () => sendTurn({ resumeMcpAuth: true }),\n [sendTurn],\n );\n\n const downloadSandboxFile = useCallback(\n async ({ turnId, path }: { turnId: string; path: string }) => {\n if (server.downloadSandboxFile == null) {\n throw new Error(\n \"Downloading a sandbox file requires AgentChatServer.downloadSandboxFile.\",\n );\n }\n if (sessionId == null) {\n throw new Error(\n \"This session has not been saved yet, so its files cannot be downloaded.\",\n );\n }\n if (sandboxId == null) {\n throw new Error(\"No sandbox is available yet for this session.\");\n }\n return await server.downloadSandboxFile({\n sessionId,\n turnId,\n sandboxId,\n path,\n });\n },\n [server, sessionId, sandboxId],\n );\n\n const draftExtras = useMemo(() => {\n if (agent.mode !== \"draft\") {\n return null;\n }\n return {\n agentSpec: draftSpec.agentSpec,\n draftSessionId: draftSpec.draftSessionId,\n isSpecLoading: draftSpec.isSpecLoading,\n isSpecSyncing: draftSpec.isSpecSyncing,\n specError: draftSpec.specError,\n updateAgentSpec: draftSpec.updateAgentSpec,\n flushAgentSpec: draftSpec.flushAgentSpec,\n adoptAgentSpec: draftSpec.adoptAgentSpec,\n };\n }, [agent.mode, draftSpec]);\n\n return useExternalStoreRuntime({\n ...pickExternalStoreSharedOptions(sharedOptions),\n messages,\n isRunning,\n isLoading,\n extras: trueFoundryExtras.provide({\n pendingApprovals,\n pendingToolResponses,\n pendingMcpAuth,\n resumeUnavailable,\n sandboxId,\n respondToToolApproval,\n respondToToolResponse,\n resumeMcpAuth,\n downloadSandboxFile,\n cancel,\n // resetFromTurn/branchFromTurn/sendTurn already report via onError.\n resetFromTurn: (turnId: string) =>\n resetFromTurn(turnId).catch(() => undefined),\n reload: retryLoad,\n hasOlderHistory,\n isLoadingOlderHistory,\n loadOlderHistory,\n draft: draftExtras,\n }),\n unstable_enableToolInvocations: true,\n setToolStatuses,\n adapters: {\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n },\n onNew: async (message: AppendMessage) => {\n if (!(message.startRun ?? message.role === \"user\")) {\n return;\n }\n\n const resumeMcpAuthFlag =\n message.runConfig?.custom?.[MCP_AUTH_RESUME_RUN_CUSTOM_KEY] === true;\n\n if (resumeMcpAuthFlag) {\n await sendTurn({ resumeMcpAuth: true });\n return;\n }\n\n const userMessage = buildUserMessageContent(message);\n await sendTurn({\n userMessage,\n // The composer clears before onNew runs. Restore its text only when\n // the turn failed before turn.created registered it in the backend.\n onPreTurnFailure: () => {\n const text = userMessageContentToText(userMessage);\n const composer = aui.thread().composer();\n if (text && !composer.getState().text.trim()) {\n composer.setText(text);\n }\n },\n });\n },\n onCancel: async () => {\n await cancel();\n },\n onRespondToToolApproval: async (response) => {\n respondToToolApproval(response);\n },\n onResume: async () => {\n await resumeRun();\n },\n onEdit: async (message: AppendMessage) => {\n const sourceId = message.sourceId;\n if (sourceId == null) {\n throw new Error(\"Could not resolve edited user message.\");\n }\n const turnId = parseTurnIdFromMessageId(sourceId);\n const editedText = extractEditedText(message);\n // editFromTurn/branchFromTurn/sendTurn already report via onError.\n await editFromTurn(turnId, editedText);\n },\n });\n}\n\nexport function useTrueFoundryAgentRuntime(options: UseTrueFoundryAgentRuntimeOptions) {\n const resolved = resolveTrueFoundryAgentRuntimeOptions(options);\n const { server, agent } = resolved;\n\n const pendingAgentSpecRef = useRef<AgentSpec | undefined>(\n agent.mode === \"draft\" ? agent.defaultAgentSpec : undefined,\n );\n\n const agentMode = agent.mode;\n const namedAgentName = agent.mode === \"named\" ? agent.agentName : undefined;\n const listSessionsAgentId = resolved.listSessionsAgentId;\n const threadListAdapter = useMemo(() => {\n if (agentMode === \"draft\") {\n const draftAgent = agent as Extract<typeof agent, { mode: \"draft\" }>;\n return createTrueFoundryDraftThreadListAdapter({\n server,\n defaultAgentSpec: draftAgent.defaultAgentSpec,\n getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec,\n listSessionsAgentId,\n });\n }\n return createTrueFoundryThreadListAdapter({\n server,\n agentName: namedAgentName!,\n listSessionsAgentId,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentMode, namedAgentName, listSessionsAgentId, server]);\n\n return useRemoteThreadListRuntime({\n allowNesting: true,\n adapter: threadListAdapter,\n initialThreadId: resolved.initialSessionId,\n threadId: resolved.threadId,\n onThreadIdChange: resolved.onThreadIdChange,\n runtimeHook: () => useTrueFoundryAgentRuntimeImpl(resolved, pendingAgentSpecRef),\n });\n}\n","/** Gateway root thread id — always the literal `\"main\"`. */\nexport const ROOT_THREAD_ID = \"main\";\n","import type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadAssistantMessagePart,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type {\n ToolApprovalRequiredEvent,\n Turn,\n UserToolApprovalEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { ToolApprovalMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\nexport type StoredApprovalDecision = {\n approved: boolean;\n reason?: string;\n};\n\nexport const TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY = \"toolApprovalThreadId\";\n\nexport type RespondToToolApprovalOptions = {\n approvalId: string;\n approved: boolean;\n optionId?: string;\n reason?: string;\n};\n\ntype ApprovalDecision = UserToolApprovalEvent[\"approval\"];\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\ntype AssistantToolCallPart = Extract<\n ThreadAssistantMessagePart,\n { type: \"tool-call\" }\n>;\n\nexport function hasPendingToolApproval(\n approval: ToolCallPart[\"approval\"] | undefined,\n): boolean {\n return (\n approval != null &&\n approval.approved === undefined &&\n approval.resolution === undefined\n );\n}\n\nfunction applyApprovalDecisionToToolCall(\n part: AssistantToolCallPart,\n options: RespondToToolApprovalOptions,\n): AssistantToolCallPart {\n const { approved, optionId, reason } = options;\n const targetApproval = part.approval!;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null ? { optionId } : {}),\n ...(reason != null ? { reason } : {}),\n };\n if (approved) {\n return { ...part, approval };\n }\n return {\n ...part,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n}\n\nfunction updateToolApprovalInContent(\n content: readonly ThreadAssistantMessagePart[],\n options: RespondToToolApprovalOptions,\n): { content: readonly ThreadAssistantMessagePart[]; found: boolean } {\n let found = false;\n const newContent = content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n if (part.approval?.id === options.approvalId) {\n found = true;\n return applyApprovalDecisionToToolCall(part, options);\n }\n\n if (part.messages == null) {\n return part;\n }\n\n const messages = part.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n const nested = updateToolApprovalInContent(message.content, options);\n if (!nested.found) {\n return message;\n }\n found = true;\n return { ...message, content: nested.content };\n });\n return { ...part, messages };\n });\n\n return { content: newContent, found };\n}\n\nexport function applyApprovalDecisionsToMessage(\n message: ThreadAssistantMessage,\n options: RespondToToolApprovalOptions,\n): ThreadAssistantMessage {\n const { content } = updateToolApprovalInContent(message.content, options);\n return { ...message, content: [...content] };\n}\n\nexport function toolApprovalStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"tool-calls\" };\n}\n\nexport function toolApprovalMessageCustom(\n threadId: string,\n): ToolApprovalMessageCustomMetadata {\n return {\n [TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY]:\n threadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : threadId,\n };\n}\n\nexport function getToolApprovalThreadId(\n message: ThreadMessage | undefined,\n): string | undefined {\n if (message?.role !== \"assistant\") {\n return undefined;\n }\n const threadId = message.metadata.custom[TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY];\n return typeof threadId === \"string\" ? threadId : undefined;\n}\n\nexport function findApprovalRequiredInTurn(\n turn: Pick<Turn, \"state\">,\n): ToolApprovalRequiredEvent | undefined {\n if (turn.state.status !== \"done\") {\n return undefined;\n }\n const found = turn.state.requiredActions?.find(\n (action) => action.type === \"tool.approval_required\",\n );\n return found?.type === \"tool.approval_required\" ? found : undefined;\n}\n\nfunction toolCallPartHasPendingApproval(part: ToolCallPart): boolean {\n return hasPendingToolApproval(part.approval);\n}\n\nfunction nestedMessagesHavePendingApprovals(\n messages: readonly ThreadMessage[],\n): boolean {\n for (const message of messages) {\n if (messageHasPendingApprovals(message)) {\n return true;\n }\n }\n return false;\n}\n\nexport function messageHasPendingApprovals(message: ThreadMessage | undefined): boolean {\n if (message?.role !== \"assistant\") {\n return false;\n }\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (toolCallPartHasPendingApproval(part)) {\n return true;\n }\n if (part.messages != null && nestedMessagesHavePendingApprovals(part.messages)) {\n return true;\n }\n }\n return false;\n}\n\nfunction walkAssistantToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: AssistantToolCallPart) => void,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role === \"assistant\") {\n walkAssistantToolCallParts(message.content, visit);\n }\n }\n }\n}\n\nexport function collectDecidedApprovalsFromContent(\n content: readonly ThreadAssistantMessagePart[],\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n walkAssistantToolCallParts(content, (part) => {\n const { approval } = part;\n if (approval?.id == null || approval.approved === undefined) {\n return;\n }\n decisions.set(approval.id, {\n approved: approval.approved,\n ...(approval.reason != null ? { reason: approval.reason } : {}),\n });\n });\n return decisions;\n}\n\nfunction applyApprovalDecisionsToMessages(\n messages: readonly ThreadMessage[],\n decisions: ReadonlyMap<string, StoredApprovalDecision>,\n): ThreadMessage[] {\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyApprovalDecisionsToContent(message.content, decisions),\n };\n });\n}\n\nexport function applyApprovalDecisionsToContent(\n content: readonly ThreadAssistantMessagePart[],\n decisions: ReadonlyMap<string, StoredApprovalDecision>,\n): ThreadAssistantMessagePart[] {\n return content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n const decision =\n part.approval?.id != null ? decisions.get(part.approval.id) : undefined;\n let nextPart: AssistantToolCallPart = part;\n\n if (\n decision != null &&\n part.approval != null &&\n part.approval.approved === undefined\n ) {\n nextPart = applyApprovalDecisionToToolCall(part, {\n approvalId: part.approval.id,\n approved: decision.approved,\n reason: decision.reason,\n });\n }\n\n if (nextPart.messages == null) {\n return nextPart;\n }\n\n return {\n ...nextPart,\n messages: applyApprovalDecisionsToMessages(nextPart.messages, decisions),\n };\n });\n}\n\nexport function mergeDecidedApprovalsIntoContent(\n incoming: readonly ThreadAssistantMessagePart[],\n existing: readonly ThreadAssistantMessagePart[],\n): ThreadAssistantMessagePart[] {\n const decided = collectDecidedApprovalsFromContent(existing);\n if (decided.size === 0) {\n return [...incoming];\n }\n return applyApprovalDecisionsToContent(incoming, decided);\n}\n\nexport function extractToolApprovalsFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): UserToolApprovalEvent[] {\n const events: UserToolApprovalEvent[] = [];\n for (const item of input ?? []) {\n if (item.type === \"user.tool_approval\") {\n events.push(item);\n }\n }\n return events;\n}\n\nexport function collectSubsequentApprovalDecisions(\n turns: readonly Pick<Turn, \"input\">[],\n fromIndex: number,\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n\n for (let index = fromIndex + 1; index < turns.length; index++) {\n const input = turns[index]?.input ?? [];\n if (input.some((item) => item.type === \"user.message\")) {\n break;\n }\n\n for (const event of extractToolApprovalsFromTurnInput(input)) {\n decisions.set(event.toolCallId, {\n approved: event.approval.status === \"allow\",\n ...(event.approval.status === \"deny\" && event.approval.reason != null\n ? { reason: event.approval.reason }\n : {}),\n });\n }\n }\n\n return decisions;\n}\n\nexport function collectApprovalDecisionsFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): Map<string, StoredApprovalDecision> {\n const decisions = new Map<string, StoredApprovalDecision>();\n for (const event of extractToolApprovalsFromTurnInput(input)) {\n decisions.set(event.toolCallId, {\n approved: event.approval.status === \"allow\",\n ...(event.approval.status === \"deny\" && event.approval.reason != null\n ? { reason: event.approval.reason }\n : {}),\n });\n }\n return decisions;\n}\n\nfunction contentHasPendingApprovals(\n content: readonly ThreadAssistantMessagePart[],\n): boolean {\n return messageHasPendingApprovals({\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n });\n}\n\nexport function resolveToolApprovalUpdate(\n update: TurnStreamUpdate,\n priorDecisions?: ReadonlyMap<string, StoredApprovalDecision>,\n): TurnStreamUpdate {\n let { content } = update;\n if (priorDecisions != null && priorDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, priorDecisions);\n }\n\n if (\n contentHasPendingApprovals(content) ||\n update.status?.type !== \"requires-action\" ||\n update.status.reason !== \"tool-calls\"\n ) {\n return { ...update, content };\n }\n\n const { status: _status, metadata: _metadata, ...rest } = update;\n return { ...rest, content };\n}\n\nexport function mapApprovalDecision(\n approved: boolean,\n reason?: string,\n): ApprovalDecision {\n if (approved) {\n return { status: \"allow\" };\n }\n return { status: \"deny\", ...(reason != null ? { reason } : {}) };\n}\n\nfunction isDecidedApprovalAwaitingSdk(part: ToolCallPart): boolean {\n const { approval, result, isError } = part;\n if (approval?.id == null || approval.approved === undefined) {\n return false;\n }\n if (approval.approved === true) {\n return result === undefined;\n }\n return isError === true;\n}\n\nfunction collectApprovalInputsFromMessages(\n messages: readonly ThreadMessage[],\n defaultThreadId: string,\n): UserToolApprovalEvent[] {\n const events: UserToolApprovalEvent[] = [];\n for (const message of messages) {\n events.push(...collectApprovalInputs(message, defaultThreadId));\n }\n return events;\n}\n\nexport function collectApprovalInputs(\n message: ThreadMessage,\n threadId: string,\n): UserToolApprovalEvent[] {\n if (message.role !== \"assistant\" || !threadId) {\n return [];\n }\n if (messageHasPendingApprovals(message)) {\n return [];\n }\n\n const scopedThreadId = getToolApprovalThreadId(message) ?? threadId;\n const events: UserToolApprovalEvent[] = [];\n\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (isDecidedApprovalAwaitingSdk(part)) {\n const { approval } = part;\n if (approval == null) {\n continue;\n }\n events.push({\n type: \"user.tool_approval\",\n threadId: scopedThreadId,\n toolCallId: approval.id,\n approval: mapApprovalDecision(approval.approved!, approval.reason),\n });\n }\n if (part.messages != null) {\n events.push(\n ...collectApprovalInputsFromMessages(part.messages, scopedThreadId),\n );\n }\n }\n return events;\n}\n\nexport function toTrueFoundryApprovalInputs(\n message: Extract<ThreadMessage, { role: \"assistant\" }>,\n response: RespondToToolApprovalOptions,\n defaultThreadId: string = ROOT_THREAD_ID,\n): UserToolApprovalEvent[] {\n const updated = applyApprovalDecisionsToMessage(message, response);\n return collectApprovalInputs(updated, defaultThreadId);\n}\n","import type { ToolCall } from \"./server/index.js\";\n\nexport function isAskUserQuestionToolCall(\n toolCall: Pick<ToolCall, \"toolInfo\">,\n): boolean {\n return (\n toolCall.toolInfo?.type === \"truefoundry-system\" &&\n toolCall.toolInfo?.name === \"ask_user_question\"\n );\n}\n\nexport type AskUserQuestionArgs = {\n question?: string;\n options?: string[];\n};\n\nexport function parseAskUserQuestionArgs(\n argsText: string | undefined,\n): AskUserQuestionArgs {\n if (!argsText) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(argsText);\n if (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n const record = parsed as Record<string, unknown>;\n const question = typeof record.question === \"string\" ? record.question : undefined;\n const options = Array.isArray(record.options)\n ? record.options.filter((item): item is string => typeof item === \"string\")\n : undefined;\n return { question, options };\n } catch {\n return {};\n }\n}\n","import type { ToolCall } from \"./server/index.js\";\n\nexport function isCreateSubAgentToolCall(\n toolCall: Pick<ToolCall, \"toolInfo\" | \"function\">,\n): boolean {\n // Gateway may attach truefoundry-system toolInfo on persisted turns, but streamed\n // model.message tool calls often only carry function.name. Without the fallback,\n // foldPeerThreads never nests child threads under the spawning tool call.\n if (\n toolCall.toolInfo?.type === \"truefoundry-system\" &&\n toolCall.toolInfo?.name === \"create_sub_agent\"\n ) {\n return true;\n }\n return toolCall.function?.name === \"create_sub_agent\";\n}\n","import type { CompleteAttachment } from \"@assistant-ui/core\";\nimport {\n isEventDelta,\n mergeEventDelta,\n type ModelMessageEvent,\n type TurnEvent,\n type TurnStreamingEvent,\n} from \"./server/index.js\";\n\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\n\nexport type ImageUrlContentPart = {\n type: \"image_url\";\n image_url: { url: string };\n};\n\ntype ModelMessageContentPart =\n | { type: \"text\"; text: string }\n | { type: \"refusal\"; refusal: string }\n | ImageUrlContentPart;\n\ntype ContentBlockDelta = {\n index: number;\n delta:\n | { type: \"text\"; text?: string }\n | { type: \"image_url\"; image_url?: { url?: string } };\n};\n\ntype ModelMessageDeltaWithContentBlocks = {\n type: \"model.message.delta\";\n id: string;\n contentBlocks?: ContentBlockDelta[];\n content_blocks?: ContentBlockDelta[];\n};\n\nfunction parseDataUriMime(data: string): string {\n if (!data.startsWith(\"data:\")) {\n return \"image/png\";\n }\n const match = /^data:([^;,]+)/.exec(data);\n return match?.[1] ?? \"image/png\";\n}\n\nfunction imageFilenameFromUrl(url: string, index: number): string {\n const mimeType = parseDataUriMime(url);\n const ext = mimeType.split(\"/\")[1] ?? \"png\";\n return `image-${index + 1}.${ext}`;\n}\n\nexport function isImageUrlContentPart(\n part: unknown,\n): part is ImageUrlContentPart {\n return (\n part != null &&\n typeof part === \"object\" &&\n (part as ImageUrlContentPart).type === \"image_url\" &&\n typeof (part as ImageUrlContentPart).image_url?.url === \"string\"\n );\n}\n\nfunction normalizeModelMessageContent(\n message: ModelMessageEvent,\n): ModelMessageContentPart[] {\n const { content } = message;\n if (content == null) {\n return [];\n }\n if (typeof content === \"string\") {\n return content.length > 0 ? [{ type: \"text\", text: content }] : [];\n }\n return content as ModelMessageContentPart[];\n}\n\nfunction ensureModelMessageContentArray(message: ModelMessageEvent): void {\n if (Array.isArray(message.content)) {\n return;\n }\n // Gateway may stream `image_url` content blocks that aren't in the SDK content union yet.\n (message as { content?: ModelMessageContentPart[] }).content =\n normalizeModelMessageContent(message);\n}\n\nfunction mergeContentBlockDeltas(\n message: ModelMessageEvent,\n blocks: readonly ContentBlockDelta[],\n): void {\n ensureModelMessageContentArray(message);\n const content = message.content as ModelMessageContentPart[];\n\n for (const block of blocks) {\n const index = block.index;\n while (content.length <= index) {\n content.push({ type: \"text\", text: \"\" });\n }\n\n const delta = block.delta;\n if (delta.type === \"text\") {\n const existing = content[index];\n if (existing?.type === \"text\") {\n existing.text += delta.text ?? \"\";\n } else {\n content[index] = { type: \"text\", text: delta.text ?? \"\" };\n }\n continue;\n }\n\n if (delta.type !== \"image_url\") {\n continue;\n }\n\n const chunk = delta.image_url?.url ?? \"\";\n const existing = content[index];\n if (isImageUrlContentPart(existing)) {\n existing.image_url.url += chunk;\n } else {\n content[index] = { type: \"image_url\", image_url: { url: chunk } };\n }\n }\n}\n\nexport function mergeStreamEventDelta(\n base: TurnEvent,\n delta: TurnStreamingEvent,\n): void {\n if (!isEventDelta(delta)) {\n return;\n }\n\n mergeEventDelta(base, delta);\n\n if (base.type !== \"model.message\" || delta.type !== \"model.message.delta\") {\n return;\n }\n\n const extended = delta as ModelMessageDeltaWithContentBlocks;\n const blocks = extended.contentBlocks ?? extended.content_blocks;\n if (blocks == null || blocks.length === 0) {\n return;\n }\n\n mergeContentBlockDeltas(base, blocks);\n}\n\nexport function imageUrlToAttachment(\n url: string,\n attachmentId: string,\n): CompleteAttachment {\n const mimeType = parseDataUriMime(url);\n return {\n id: attachmentId,\n type: \"image\",\n name: imageFilenameFromUrl(url, 0),\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: url, filename: imageFilenameFromUrl(url, 0) }],\n };\n}\n\nexport function imagePartToAssistantImage(url: string, index: number): AssistantContentPart {\n return {\n type: \"image\",\n image: url,\n filename: imageFilenameFromUrl(url, index),\n };\n}\n\nexport function extractImagePartsFromModelMessage(\n message: ModelMessageEvent,\n): AssistantContentPart[] {\n const parts: AssistantContentPart[] = [];\n let imageIndex = 0;\n\n for (const part of normalizeModelMessageContent(message)) {\n if (!isImageUrlContentPart(part)) {\n continue;\n }\n const url = part.image_url.url.trim();\n if (url.length === 0) {\n continue;\n }\n parts.push(imagePartToAssistantImage(url, imageIndex));\n imageIndex += 1;\n }\n\n return parts;\n}\n\nexport function extractImageUrlFromUserContentItem(\n part: unknown,\n): string | undefined {\n if (isImageUrlContentPart(part)) {\n const url = part.image_url.url.trim();\n return url.length > 0 ? url : undefined;\n }\n return undefined;\n}","import type { ThreadAssistantMessagePart } from \"@assistant-ui/core\";\nimport type { ModelMessageEvent } from \"./server/index.js\";\nimport type { PendingResponseRef } from \"./foldPeerThreads.js\";\nimport { extractImagePartsFromModelMessage } from \"./modelMessageImageContent.js\";\n\nexport type AssistantContentPart = ThreadAssistantMessagePart;\n\nexport type ToolCallContext = {\n toolResults?: ReadonlyMap<string, string>;\n pendingApprovals?: ReadonlyMap<string, { id: string }>;\n approvalDecisions?: ReadonlyMap<\n string,\n { id: string; approved: boolean; reason?: string }\n >;\n pendingResponses?: ReadonlyMap<string, PendingResponseRef>;\n};\n\nexport type SdkToolCall = NonNullable<ModelMessageEvent[\"toolCalls\"]>[number];\n\nfunction parseToolArgs(argsText: string): Record<string, string | number | boolean | null> {\n if (!argsText) {\n return {};\n }\n try {\n const parsed: unknown = JSON.parse(argsText);\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, string | number | boolean | null>;\n }\n return {};\n } catch {\n return {};\n }\n}\n\ntype ToolCallPart = Extract<AssistantContentPart, { type: \"tool-call\" }>;\n\nfunction toolCallToPart(\n toolCall: SdkToolCall,\n context?: ToolCallContext,\n): ToolCallPart {\n const argsText = toolCall.function.arguments ?? \"\";\n const toolResult = context?.toolResults?.get(toolCall.id);\n const pendingResponse = context?.pendingResponses?.get(toolCall.id);\n const pendingApproval = context?.pendingApprovals?.get(toolCall.id);\n const approvalDecision = context?.approvalDecisions?.get(toolCall.id);\n\n let interrupt: ToolCallPart[\"interrupt\"];\n if (pendingResponse != null && toolResult === undefined) {\n interrupt = {\n type: \"human\",\n payload: {\n ...(pendingResponse.question != null\n ? { question: pendingResponse.question }\n : {}),\n ...(pendingResponse.options != null\n ? { options: pendingResponse.options }\n : {}),\n },\n };\n }\n\n let approval: ToolCallPart[\"approval\"];\n if (approvalDecision != null) {\n approval = {\n id: approvalDecision.id,\n approved: approvalDecision.approved,\n ...(approvalDecision.reason != null\n ? { reason: approvalDecision.reason }\n : {}),\n };\n } else if (pendingApproval != null) {\n approval = { id: pendingApproval.id };\n }\n\n let result: ToolCallPart[\"result\"];\n let isError = false;\n if (toolResult !== undefined) {\n result = toolResult;\n } else if (approvalDecision?.approved === false) {\n result = { error: approvalDecision.reason || \"Tool approval denied\" };\n isError = true;\n }\n\n return {\n type: \"tool-call\",\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n argsText,\n args: parseToolArgs(argsText),\n ...(result !== undefined ? { result } : {}),\n ...(isError ? { isError: true } : {}),\n ...(approval != null ? { approval } : {}),\n ...(interrupt != null ? { interrupt } : {}),\n };\n}\n\nfunction extractText(message: ModelMessageEvent): string {\n const { content, refusal } = message;\n if (content == null) {\n return refusal ?? \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n return content\n .map((part) => {\n if (part.type === \"text\") {\n return part.text;\n }\n if (part.type === \"refusal\") {\n return part.refusal;\n }\n return \"\";\n })\n .join(\"\");\n}\n\nexport function buildAssistantContent(\n message: ModelMessageEvent,\n context?: ToolCallContext,\n): AssistantContentPart[] {\n const parts: AssistantContentPart[] = [];\n if (message.reasoningContent) {\n parts.push({ type: \"reasoning\", text: message.reasoningContent });\n }\n const text = extractText(message);\n if (text) {\n parts.push({ type: \"text\", text });\n }\n parts.push(...extractImagePartsFromModelMessage(message));\n for (const toolCall of message.toolCalls ?? []) {\n parts.push(toolCallToPart(toolCall, context));\n }\n return parts;\n}\n","import type { MessageStatus, ThreadMessage } from \"@assistant-ui/core\";\nimport {\n isEventDelta,\n type ThreadCreatedEvent,\n type ToolResponseRequiredEvent,\n type TurnEvent,\n type TurnStreamingEvent,\n} from \"./server/index.js\";\n\nimport { parseAskUserQuestionArgs } from \"./askUserQuestion.js\";\nimport { isCreateSubAgentToolCall } from \"./createSubAgent.js\";\nimport {\n buildAssistantContent,\n type AssistantContentPart,\n type SdkToolCall,\n} from \"./modelMessageContent.js\";\nimport { mergeStreamEventDelta } from \"./modelMessageImageContent.js\";\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { SubAgentMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport { toolApprovalMessageCustom, toolApprovalStatus } from \"./toolApproval.js\";\nimport { toolResponseMessageCustom, toolResponseStatus } from \"./toolResponse.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\ntype AgentInfo = ThreadCreatedEvent[\"agentInfo\"];\n\nexport type SubAgentCustomMetadata = {\n threadId: string;\n title?: string;\n name?: string;\n model?: string;\n input?: string;\n};\n\nexport type SubAgentArtifact = {\n subAgents: Array<{\n threadId: string;\n title?: string;\n agentInfo?: AgentInfo;\n }>;\n};\n\ntype ToolCallRef = ToolResponseRequiredEvent[\"toolCalls\"][number];\n\nexport type PendingResponseRef = {\n id: string;\n sourceEventId: string;\n question?: string;\n options?: string[];\n};\n\nexport type ApprovalDecisionRef = {\n id: string;\n approved: boolean;\n reason?: string;\n};\n\nexport type ThreadBucket = {\n events: Map<string, TurnEvent>;\n modelMessageIds: string[];\n toolResults: Map<string, string>;\n pendingApprovals: Map<string, { id: string }>;\n approvalDecisions: Map<string, ApprovalDecisionRef>;\n pendingResponses: Map<string, PendingResponseRef>;\n done: boolean;\n title?: string;\n agentInfo?: AgentInfo;\n};\n\nexport type ThreadParentLink = {\n parentThreadId: string;\n toolCallId: string;\n};\n\nconst isDev =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction warnUnexpectedRootThread(threadId: string, eventType: string): void {\n if (!isDev) {\n return;\n }\n console.warn(\n `[@truefoundry/assistant-ui-runtime] Expected root thread \"${ROOT_THREAD_ID}\" but received \"${threadId}\" on ${eventType}.`,\n );\n}\n\nfunction assertRootThreadEvent(threadId: string, eventType: string): void {\n if (threadId === ROOT_THREAD_ID) {\n return;\n }\n if (isDev) {\n throw new Error(\n `[@truefoundry/assistant-ui-runtime] Root-looking event ${eventType} arrived on thread \"${threadId}\" instead of \"${ROOT_THREAD_ID}\".`,\n );\n }\n warnUnexpectedRootThread(threadId, eventType);\n}\n\nexport class PeerThreadFoldState {\n readonly threads = new Map<string, ThreadBucket>();\n readonly threadParents = new Map<string, ThreadParentLink>();\n\n getOrCreateBucket(threadId: string): ThreadBucket {\n let bucket = this.threads.get(threadId);\n if (bucket == null) {\n bucket = {\n events: new Map(),\n modelMessageIds: [],\n toolResults: new Map(),\n pendingApprovals: new Map(),\n approvalDecisions: new Map(),\n pendingResponses: new Map(),\n done: false,\n };\n this.threads.set(threadId, bucket);\n }\n return bucket;\n }\n}\n\nfunction isTurnScopedEvent(message: TurnStreamingEvent): boolean {\n return message.type === \"turn.created\" || message.type === \"turn.done\";\n}\n\nfunction ingestEventIntoBucket(\n bucket: ThreadBucket,\n message: TurnStreamingEvent,\n): void {\n if (isTurnScopedEvent(message)) {\n return;\n }\n\n if (isEventDelta(message)) {\n const base = bucket.events.get(message.id);\n if (base != null) {\n mergeStreamEventDelta(base, message);\n }\n return;\n }\n\n bucket.events.set(message.id, message as TurnEvent);\n\n if (message.type === \"model.message\") {\n if (!bucket.modelMessageIds.includes(message.id)) {\n bucket.modelMessageIds.push(message.id);\n }\n return;\n }\n\n if (message.type === \"tool.response\") {\n bucket.toolResults.set(message.toolCallId, message.content);\n bucket.pendingResponses.delete(message.toolCallId);\n return;\n }\n\n if (message.type === \"tool.approval_required\") {\n for (const ref of message.toolCalls) {\n bucket.pendingApprovals.set(ref.id, { id: ref.id });\n }\n return;\n }\n\n if (message.type === \"tool.response_required\") {\n for (const ref of message.toolCalls) {\n const resolved = resolveAskUserQuestionFromBucket(bucket, ref);\n bucket.pendingResponses.set(ref.id, {\n id: ref.id,\n sourceEventId: ref.sourceEventId,\n ...(resolved?.question != null ? { question: resolved.question } : {}),\n ...(resolved?.options != null ? { options: resolved.options } : {}),\n });\n }\n return;\n }\n\n if (message.type === \"thread.done\") {\n bucket.done = true;\n if (message.title) {\n bucket.title = message.title;\n }\n }\n}\n\nfunction isContentAffectingEvent(message: TurnStreamingEvent): boolean {\n return (\n message.type === \"thread.created\" ||\n message.type === \"thread.done\" ||\n message.type === \"model.message\" ||\n message.type === \"model.message.delta\" ||\n message.type === \"tool.response\" ||\n message.type === \"tool.approval_required\" ||\n message.type === \"tool.response_required\"\n );\n}\n\nexport function ingestStreamEvent(\n state: PeerThreadFoldState,\n message: TurnStreamingEvent,\n): boolean {\n if (message.type === \"mcp.auth_required\" || isTurnScopedEvent(message)) {\n return false;\n }\n\n if (message.threadId == null) {\n return false;\n }\n\n if (message.type === \"thread.created\") {\n state.threadParents.set(message.threadId, {\n parentThreadId: message.parent.threadId,\n toolCallId: message.parent.toolCallId,\n });\n const bucket = state.getOrCreateBucket(message.threadId);\n bucket.title = message.title;\n bucket.agentInfo = message.agentInfo;\n return true;\n }\n\n if (message.type === \"model.message\" && message.threadId === ROOT_THREAD_ID) {\n assertRootThreadEvent(message.threadId, message.type);\n }\n\n const bucket = state.getOrCreateBucket(message.threadId);\n ingestEventIntoBucket(bucket, message);\n\n return isContentAffectingEvent(message);\n}\n\nexport function ingestTurnEvent(state: PeerThreadFoldState, event: TurnEvent): void {\n if (event.threadId == null) {\n return;\n }\n\n if (event.type === \"thread.created\") {\n state.threadParents.set(event.threadId, {\n parentThreadId: event.parent.threadId,\n toolCallId: event.parent.toolCallId,\n });\n const bucket = state.getOrCreateBucket(event.threadId);\n bucket.title = event.title;\n bucket.agentInfo = event.agentInfo;\n } else if (event.type === \"model.message\" && event.threadId === ROOT_THREAD_ID) {\n assertRootThreadEvent(event.threadId, event.type);\n }\n\n ingestEventIntoBucket(state.getOrCreateBucket(event.threadId), event);\n}\n\nfunction resolveAskUserQuestionFromBucket(\n bucket: ThreadBucket,\n ref: Pick<ToolCallRef, \"id\" | \"sourceEventId\">,\n): { question?: string; options?: string[] } | undefined {\n const modelMessage = bucket.events.get(ref.sourceEventId);\n if (modelMessage?.type !== \"model.message\") {\n return undefined;\n }\n const toolCall = modelMessage.toolCalls?.find((call) => call.id === ref.id);\n if (toolCall == null) {\n return undefined;\n }\n return parseAskUserQuestionArgs(toolCall.function.arguments);\n}\n\nfunction findToolCallInBucket(\n bucket: ThreadBucket,\n toolCallId: string,\n): SdkToolCall | undefined {\n for (const id of bucket.modelMessageIds) {\n const event = bucket.events.get(id);\n if (event?.type !== \"model.message\") {\n continue;\n }\n const match = event.toolCalls?.find((toolCall) => toolCall.id === toolCallId);\n if (match != null) {\n return match;\n }\n }\n return undefined;\n}\n\nfunction isLinkedCreateSubAgentThread(\n state: PeerThreadFoldState,\n subThreadId: string,\n): boolean {\n const link = state.threadParents.get(subThreadId);\n if (link == null) {\n return false;\n }\n const parentBucket = state.threads.get(link.parentThreadId);\n if (parentBucket == null) {\n return false;\n }\n const toolCall = findToolCallInBucket(parentBucket, link.toolCallId);\n return toolCall != null && isCreateSubAgentToolCall(toolCall);\n}\n\nfunction childSubThreadIds(\n state: PeerThreadFoldState,\n parentThreadId: string,\n toolCallId: string,\n): string[] {\n const ids: string[] = [];\n for (const [subThreadId, link] of state.threadParents) {\n if (\n link.parentThreadId === parentThreadId &&\n link.toolCallId === toolCallId &&\n isLinkedCreateSubAgentThread(state, subThreadId)\n ) {\n ids.push(subThreadId);\n }\n }\n return ids;\n}\n\nfunction bucketHasUnresolvedPendingResponses(bucket: ThreadBucket): boolean {\n for (const id of bucket.pendingResponses.keys()) {\n if (!bucket.toolResults.has(id)) {\n return true;\n }\n }\n return false;\n}\n\nfunction bucketAssistantStatus(bucket: ThreadBucket): MessageStatus {\n if (bucket.pendingApprovals.size > 0) {\n return toolApprovalStatus();\n }\n if (bucketHasUnresolvedPendingResponses(bucket)) {\n return toolResponseStatus();\n }\n if (!bucket.done && bucket.modelMessageIds.length > 0) {\n return { type: \"running\" };\n }\n return { type: \"complete\", reason: \"stop\" };\n}\n\nfunction buildSubAgentCustomMetadata(\n threadId: string,\n bucket: ThreadBucket,\n): SubAgentMessageCustomMetadata {\n const metadata: SubAgentCustomMetadata = {\n threadId,\n ...(bucket.title != null ? { title: bucket.title } : {}),\n ...(bucket.agentInfo?.name != null ? { name: bucket.agentInfo.name } : {}),\n ...(bucket.agentInfo?.model != null ? { model: bucket.agentInfo.model } : {}),\n ...(bucket.agentInfo?.input != null ? { input: bucket.agentInfo.input } : {}),\n };\n return { subAgent: metadata };\n}\n\nfunction attachSubAgentMessages(\n state: PeerThreadFoldState,\n parentThreadId: string,\n parts: AssistantContentPart[],\n): AssistantContentPart[] {\n const parentBucket = state.threads.get(parentThreadId);\n\n return parts.map((part) => {\n if (part.type !== \"tool-call\" || parentBucket == null) {\n return part;\n }\n\n const sdkToolCall = findToolCallInBucket(parentBucket, part.toolCallId);\n if (sdkToolCall == null || !isCreateSubAgentToolCall(sdkToolCall)) {\n return part;\n }\n\n const childIds = childSubThreadIds(state, parentThreadId, part.toolCallId);\n if (childIds.length === 0) {\n return part;\n }\n\n const messages: ThreadMessage[] = [];\n const subAgents: SubAgentArtifact[\"subAgents\"] = [];\n for (const childId of childIds) {\n const childMessages = buildSubThreadMessages(state, childId);\n if (childMessages.length > 0) {\n messages.push(...childMessages);\n }\n const childBucket = state.threads.get(childId);\n if (childBucket != null) {\n subAgents.push({\n threadId: childId,\n ...(childBucket.title != null ? { title: childBucket.title } : {}),\n ...(childBucket.agentInfo != null\n ? { agentInfo: childBucket.agentInfo }\n : {}),\n });\n }\n }\n if (messages.length === 0 && subAgents.length === 0) {\n return part;\n }\n\n const artifact: SubAgentArtifact = { subAgents };\n // thread.created (title, agentInfo) arrives before the child's first model.message.\n // Attach artifact-only so UI can render the sub-agent header immediately; see README\n // SubAgentArtifact / MessagePartPrimitive.Messages in agent-ui ToolCallContainer.\n if (messages.length === 0) {\n return { ...part, artifact };\n }\n return { ...part, messages, artifact };\n });\n}\n\nfunction buildThreadAssistantParts(\n state: PeerThreadFoldState,\n threadId: string,\n modelMessageIds?: readonly string[],\n): AssistantContentPart[] {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return [];\n }\n\n const ids =\n threadId === ROOT_THREAD_ID && modelMessageIds != null\n ? modelMessageIds\n : bucket.modelMessageIds;\n\n const parts: AssistantContentPart[] = [];\n // A single tool call can appear in more than one `model.message` event (e.g.\n // once in the paused turn and again in the resumed turn after a tool\n // approval). assistant-ui keys tool parts by `toolCallId` within a message,\n // so emitting the same id twice crashes the render. Collapse duplicates,\n // letting the latest occurrence win while preserving the original position.\n const toolCallIndexById = new Map<string, number>();\n for (const id of ids) {\n const event = bucket.events.get(id);\n if (event?.type !== \"model.message\") {\n continue;\n }\n for (const part of buildAssistantContent(event, {\n toolResults: bucket.toolResults,\n pendingApprovals: bucket.pendingApprovals,\n approvalDecisions: bucket.approvalDecisions,\n pendingResponses: bucket.pendingResponses,\n })) {\n if (part.type === \"tool-call\") {\n const existingIndex = toolCallIndexById.get(part.toolCallId);\n if (existingIndex != null) {\n parts[existingIndex] = part;\n continue;\n }\n toolCallIndexById.set(part.toolCallId, parts.length);\n }\n parts.push(part);\n }\n }\n\n return attachSubAgentMessages(state, threadId, parts);\n}\n\nfunction buildSubThreadMessages(\n state: PeerThreadFoldState,\n threadId: string,\n): ThreadMessage[] {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return [];\n }\n\n const content = buildThreadAssistantParts(state, threadId);\n if (content.length === 0) {\n return [];\n }\n\n const custom = {\n ...buildSubAgentCustomMetadata(threadId, bucket),\n ...(bucket.pendingApprovals.size > 0\n ? toolApprovalMessageCustom(threadId)\n : {}),\n ...(bucketHasUnresolvedPendingResponses(bucket)\n ? toolResponseMessageCustom(threadId)\n : {}),\n };\n\n return [\n {\n id: `${threadId}-assistant`,\n role: \"assistant\",\n content,\n status: bucketAssistantStatus(bucket),\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom,\n },\n },\n ];\n}\n\nexport function buildRootAssistantContent(\n state: PeerThreadFoldState,\n): AssistantContentPart[] {\n return buildThreadAssistantParts(state, ROOT_THREAD_ID);\n}\n\nexport function buildRootAssistantContentForIds(\n state: PeerThreadFoldState,\n modelMessageIds: readonly string[],\n): AssistantContentPart[] {\n return buildThreadAssistantParts(state, ROOT_THREAD_ID, modelMessageIds);\n}\n\nexport function findFirstPendingApprovalThreadId(\n state: PeerThreadFoldState,\n): string | undefined {\n for (const [threadId, bucket] of state.threads) {\n if (bucket.pendingApprovals.size > 0) {\n return threadId;\n }\n }\n return undefined;\n}\n\nexport function findFirstPendingResponseThreadId(\n state: PeerThreadFoldState,\n): string | undefined {\n for (const [threadId, bucket] of state.threads) {\n if (bucketHasUnresolvedPendingResponses(bucket)) {\n return threadId;\n }\n }\n return undefined;\n}\n\nexport function resolveAskUserQuestion(\n state: PeerThreadFoldState,\n threadId: string,\n ref: Pick<ToolCallRef, \"id\" | \"sourceEventId\">,\n): { question?: string; options?: string[] } | undefined {\n const bucket = state.threads.get(threadId);\n if (bucket == null) {\n return undefined;\n }\n return resolveAskUserQuestionFromBucket(bucket, ref);\n}\n\nexport function isRootThreadId(threadId: string | undefined): boolean {\n return threadId === ROOT_THREAD_ID;\n}\n\nexport function recordToolApprovalInFold(\n fold: PeerThreadFoldState,\n decision: { toolCallId: string; approved: boolean; reason?: string },\n): void {\n const record: ApprovalDecisionRef = {\n id: decision.toolCallId,\n approved: decision.approved,\n ...(decision.reason != null ? { reason: decision.reason } : {}),\n };\n let applied = false;\n for (const bucket of fold.threads.values()) {\n if (!bucket.pendingApprovals.has(decision.toolCallId)) {\n continue;\n }\n bucket.pendingApprovals.delete(decision.toolCallId);\n bucket.approvalDecisions.set(decision.toolCallId, record);\n applied = true;\n }\n if (applied) {\n return;\n }\n const rootBucket = fold.getOrCreateBucket(ROOT_THREAD_ID);\n rootBucket.approvalDecisions.set(decision.toolCallId, record);\n}\n\n/** Persist a user.tool_response answer into fold state (clears pending ask-user). */\nexport function recordToolResponseInFold(\n fold: PeerThreadFoldState,\n response: { toolCallId: string; content: string },\n): void {\n let applied = false;\n for (const bucket of fold.threads.values()) {\n if (!bucket.pendingResponses.has(response.toolCallId)) {\n continue;\n }\n bucket.toolResults.set(response.toolCallId, response.content);\n bucket.pendingResponses.delete(response.toolCallId);\n applied = true;\n }\n if (applied) {\n return;\n }\n const rootBucket = fold.getOrCreateBucket(ROOT_THREAD_ID);\n rootBucket.toolResults.set(response.toolCallId, response.content);\n rootBucket.pendingResponses.delete(response.toolCallId);\n}\n","import type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadAssistantMessagePart,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type {\n ToolResponseRequiredEvent,\n Turn,\n TurnInputItem,\n UserToolResponseEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n recordToolApprovalInFold,\n recordToolResponseInFold,\n type PeerThreadFoldState,\n} from \"./foldPeerThreads.js\";\nimport type { ToolResponseMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport { ROOT_THREAD_ID } from \"./constants.js\";\n\nexport const TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY = \"toolResponseThreadId\";\n\nexport type AskUserQuestionInterruptPayload = {\n question?: string;\n options?: string[];\n};\n\nexport type StoredToolResponse = Pick<UserToolResponseEvent, \"content\">;\n\nexport type RespondToToolResponseOptions = Pick<\n UserToolResponseEvent,\n \"toolCallId\" | \"content\"\n>;\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\ntype AssistantToolCallPart = Extract<\n ThreadAssistantMessagePart,\n { type: \"tool-call\" }\n>;\n\nexport function hasPendingToolResponse(\n part: Pick<ToolCallPart, \"interrupt\" | \"result\">,\n): boolean {\n return part.interrupt != null && part.result === undefined;\n}\n\nfunction isStagedResponseAwaitingSdk(part: ToolCallPart): boolean {\n return part.interrupt != null && part.result !== undefined;\n}\n\nexport function toolResponseStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"tool-calls\" };\n}\n\nexport function toolResponseMessageCustom(\n threadId: string,\n): ToolResponseMessageCustomMetadata {\n return {\n [TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY]:\n threadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : threadId,\n };\n}\n\nexport function getToolResponseThreadId(\n message: ThreadMessage | undefined,\n): string | undefined {\n if (message?.role !== \"assistant\") {\n return undefined;\n }\n const threadId = message.metadata.custom[TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY];\n return typeof threadId === \"string\" ? threadId : undefined;\n}\n\nexport function findResponseRequiredInTurn(\n turn: Pick<Turn, \"state\">,\n): ToolResponseRequiredEvent | undefined {\n if (turn.state.status !== \"done\") {\n return undefined;\n }\n const found = turn.state.requiredActions?.find(\n (action) => action.type === \"tool.response_required\",\n );\n return found?.type === \"tool.response_required\" ? found : undefined;\n}\n\nfunction applyToolResponseToToolCall(\n part: AssistantToolCallPart,\n content: string,\n): AssistantToolCallPart {\n return { ...part, result: content };\n}\n\nfunction updateToolResponseInContent(\n content: readonly ThreadAssistantMessagePart[],\n options: RespondToToolResponseOptions,\n): { content: readonly ThreadAssistantMessagePart[]; found: boolean } {\n let found = false;\n const newContent = content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n if (part.toolCallId === options.toolCallId && hasPendingToolResponse(part)) {\n found = true;\n return applyToolResponseToToolCall(part, options.content);\n }\n\n if (part.messages == null) {\n return part;\n }\n\n const messages = part.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n const nested = updateToolResponseInContent(message.content, options);\n if (!nested.found) {\n return message;\n }\n found = true;\n return { ...message, content: nested.content };\n });\n return { ...part, messages };\n });\n\n return { content: newContent, found };\n}\n\nexport function applyToolResponseToMessage(\n message: ThreadAssistantMessage,\n options: RespondToToolResponseOptions,\n): ThreadAssistantMessage {\n const { content } = updateToolResponseInContent(message.content, options);\n return { ...message, content: [...content] };\n}\n\nfunction nestedMessagesHavePendingResponses(\n messages: readonly ThreadMessage[],\n): boolean {\n for (const message of messages) {\n if (messageHasPendingResponses(message)) {\n return true;\n }\n }\n return false;\n}\n\nexport function messageHasPendingResponses(message: ThreadMessage | undefined): boolean {\n if (message?.role !== \"assistant\") {\n return false;\n }\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (hasPendingToolResponse(part)) {\n return true;\n }\n if (part.messages != null && nestedMessagesHavePendingResponses(part.messages)) {\n return true;\n }\n }\n return false;\n}\n\nfunction collectResponseInputsFromMessages(\n messages: readonly ThreadMessage[],\n defaultThreadId: string,\n): UserToolResponseEvent[] {\n const events: UserToolResponseEvent[] = [];\n for (const message of messages) {\n events.push(...collectResponseInputs(message, defaultThreadId));\n }\n return events;\n}\n\nexport function collectResponseInputs(\n message: ThreadMessage,\n threadId: string,\n): UserToolResponseEvent[] {\n if (message.role !== \"assistant\" || !threadId) {\n return [];\n }\n if (messageHasPendingResponses(message)) {\n return [];\n }\n\n const scopedThreadId = getToolResponseThreadId(message) ?? threadId;\n const events: UserToolResponseEvent[] = [];\n\n for (const part of message.content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n if (isStagedResponseAwaitingSdk(part)) {\n events.push({\n type: \"user.tool_response\",\n threadId: scopedThreadId,\n toolCallId: part.toolCallId,\n content: String(part.result),\n });\n }\n if (part.messages != null) {\n events.push(\n ...collectResponseInputsFromMessages(part.messages, scopedThreadId),\n );\n }\n }\n return events;\n}\n\nfunction contentHasPendingResponses(\n content: readonly ThreadAssistantMessagePart[],\n): boolean {\n return messageHasPendingResponses({\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n });\n}\n\nexport function resolveToolResponseUpdate(update: TurnStreamUpdate): TurnStreamUpdate {\n if (\n contentHasPendingResponses(update.content) ||\n update.status?.type !== \"requires-action\" ||\n update.status.reason !== \"tool-calls\"\n ) {\n return update;\n }\n\n const { status: _status, metadata: _metadata, ...rest } = update;\n return rest;\n}\n\nfunction walkAssistantToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: AssistantToolCallPart) => void,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role === \"assistant\") {\n walkAssistantToolCallParts(message.content, visit);\n }\n }\n }\n}\n\nfunction collectStagedResponsesFromContent(\n content: readonly ThreadAssistantMessagePart[],\n): Map<string, string> {\n const staged = new Map<string, string>();\n walkAssistantToolCallParts(content, (part) => {\n if (isStagedResponseAwaitingSdk(part)) {\n staged.set(part.toolCallId, String(part.result));\n }\n });\n return staged;\n}\n\nfunction applyStagedResponsesToContentMap(\n content: readonly ThreadAssistantMessagePart[],\n staged: ReadonlyMap<string, string>,\n): ThreadAssistantMessagePart[] {\n return content.map((part) => {\n if (part.type !== \"tool-call\") {\n return part;\n }\n\n const contentValue = staged.get(part.toolCallId);\n let nextPart: AssistantToolCallPart = part;\n if (contentValue != null && hasPendingToolResponse(part)) {\n nextPart = applyToolResponseToToolCall(part, contentValue);\n }\n\n if (nextPart.messages == null) {\n return nextPart;\n }\n\n return {\n ...nextPart,\n messages: nextPart.messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyStagedResponsesToContentMap(message.content, staged),\n };\n }),\n };\n });\n}\n\nexport function mergeStagedResponsesIntoContent(\n incoming: readonly ThreadAssistantMessagePart[],\n existing: readonly ThreadAssistantMessagePart[],\n): ThreadAssistantMessagePart[] {\n const staged = collectStagedResponsesFromContent(existing);\n if (staged.size === 0) {\n return [...incoming];\n }\n return applyStagedResponsesToContentMap(incoming, staged);\n}\n\nexport function extractToolResponsesFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): UserToolResponseEvent[] {\n const events: UserToolResponseEvent[] = [];\n for (const item of input ?? []) {\n if (item.type === \"user.tool_response\") {\n events.push(item);\n }\n }\n return events;\n}\n\nexport function applyUserToolResponsesToFold(\n fold: PeerThreadFoldState,\n inputs: readonly TurnInputItem[],\n): void {\n for (const item of inputs) {\n if (item.type === \"user.tool_response\") {\n recordToolResponseInFold(fold, {\n toolCallId: item.toolCallId,\n content: item.content,\n });\n } else if (item.type === \"user.tool_approval\") {\n recordToolApprovalInFold(fold, {\n toolCallId: item.toolCallId,\n approved: item.approval.status === \"allow\",\n ...(item.approval.status === \"deny\" && item.approval.reason != null\n ? { reason: item.approval.reason }\n : {}),\n });\n }\n }\n}\n\nexport function collectSubsequentToolResponses(\n turns: readonly Pick<Turn, \"input\">[],\n fromIndex: number,\n): Map<string, StoredToolResponse> {\n const responses = new Map<string, StoredToolResponse>();\n\n for (let index = fromIndex + 1; index < turns.length; index++) {\n const input = turns[index]?.input ?? [];\n if (input.some((item) => item.type === \"user.message\")) {\n break;\n }\n\n for (const event of extractToolResponsesFromTurnInput(input)) {\n responses.set(event.toolCallId, { content: event.content });\n }\n }\n\n return responses;\n}\n\nexport function collectToolResponsesFromTurnInput(\n input: Turn[\"input\"] | undefined,\n): Map<string, StoredToolResponse> {\n const responses = new Map<string, StoredToolResponse>();\n for (const event of extractToolResponsesFromTurnInput(input)) {\n responses.set(event.toolCallId, { content: event.content });\n }\n return responses;\n}\n\nfunction applyStagedResponsesToMessages(\n messages: readonly ThreadMessage[],\n responses: ReadonlyMap<string, StoredToolResponse>,\n): ThreadMessage[] {\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n return {\n ...message,\n content: applyStagedResponsesToContentMap(\n message.content,\n new Map(\n [...responses.entries()].map(([toolCallId, value]) => [\n toolCallId,\n value.content,\n ]),\n ),\n ),\n };\n });\n}\n\nexport function applyStagedResponsesToContent(\n content: readonly ThreadAssistantMessagePart[],\n responses: ReadonlyMap<string, StoredToolResponse>,\n): ThreadAssistantMessagePart[] {\n const staged = new Map(\n [...responses.entries()].map(([toolCallId, value]) => [\n toolCallId,\n value.content,\n ]),\n );\n return applyStagedResponsesToContentMap(content, staged);\n}\n","import type { ThreadAssistantMessagePart, ThreadMessage } from \"@assistant-ui/core\";\nimport type { McpAuthRequiredEvent } from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n getToolApprovalThreadId,\n hasPendingToolApproval,\n} from \"./toolApproval.js\";\nimport {\n getToolResponseThreadId,\n hasPendingToolResponse,\n type AskUserQuestionInterruptPayload,\n} from \"./toolResponse.js\";\n\nexport type PendingApproval = {\n approvalId: string;\n threadId: string;\n toolName: string;\n args: Record<string, unknown>;\n argsText: string;\n};\n\nexport type PendingToolResponse = {\n toolCallId: string;\n threadId: string;\n toolName: string;\n args: Record<string, unknown>;\n argsText: string;\n question?: string;\n options?: string[];\n};\n\ntype ToolCallPart = Extract<\n ThreadMessage[\"content\"][number],\n { type: \"tool-call\" }\n>;\n\nfunction walkToolCallParts(\n content: readonly ThreadAssistantMessagePart[],\n visit: (part: ToolCallPart, threadId: string) => void,\n threadId: string,\n): void {\n for (const part of content) {\n if (part.type !== \"tool-call\") {\n continue;\n }\n visit(part, threadId);\n if (part.messages == null) {\n continue;\n }\n for (const message of part.messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const nestedThreadId =\n getToolApprovalThreadId(message) ??\n getToolResponseThreadId(message) ??\n threadId;\n walkToolCallParts(message.content, visit, nestedThreadId);\n }\n }\n}\n\nexport function collectPendingApprovals(\n messages: readonly ThreadMessage[],\n): PendingApproval[] {\n const pending: PendingApproval[] = [];\n\n for (const message of messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const rootThreadId = getToolApprovalThreadId(message) ?? ROOT_THREAD_ID;\n walkToolCallParts(message.content, (part, threadId) => {\n if (!hasPendingToolApproval(part.approval)) {\n return;\n }\n pending.push({\n approvalId: part.approval!.id,\n threadId,\n toolName: part.toolName,\n args: { ...part.args },\n argsText: part.argsText,\n });\n }, rootThreadId);\n }\n\n return pending;\n}\n\nexport function collectPendingToolResponses(\n messages: readonly ThreadMessage[],\n): PendingToolResponse[] {\n const pending: PendingToolResponse[] = [];\n\n for (const message of messages) {\n if (message.role !== \"assistant\") {\n continue;\n }\n const rootThreadId = getToolResponseThreadId(message) ?? ROOT_THREAD_ID;\n walkToolCallParts(message.content, (part, threadId) => {\n if (!hasPendingToolResponse(part)) {\n return;\n }\n const payload = part.interrupt?.payload as\n | AskUserQuestionInterruptPayload\n | undefined;\n pending.push({\n toolCallId: part.toolCallId,\n threadId,\n toolName: part.toolName,\n args: { ...part.args },\n argsText: part.argsText,\n ...(payload?.question != null ? { question: payload.question } : {}),\n ...(payload?.options != null ? { options: payload.options } : {}),\n });\n }, rootThreadId);\n }\n\n return pending;\n}\n\nexport function derivePendingMcpAuth(\n messages: readonly ThreadMessage[],\n): { mcpServers: McpAuthRequiredEvent[\"mcpServers\"] } | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message?.role !== \"assistant\") {\n continue;\n }\n if (message.status?.type !== \"requires-action\") {\n continue;\n }\n const custom = message.metadata.custom as TrueFoundryMessageCustomMetadata;\n if (custom.pendingMcpAuth !== true) {\n continue;\n }\n const servers = custom.mcpServers;\n if (!Array.isArray(servers)) {\n return { mcpServers: [] };\n }\n return { mcpServers: servers };\n }\n return null;\n}\n\n/**\n * Most recent `sandboxId` observed anywhere in the conversation, scanning backward.\n * Unlike `derivePendingMcpAuth`, this isn't gated on message status: once a sandbox\n * is created it stays valid for the rest of the session, not just the paused message.\n */\nexport function deriveSandboxId(messages: readonly ThreadMessage[]): string | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message?.role !== \"assistant\") {\n continue;\n }\n const custom = message.metadata.custom as TrueFoundryMessageCustomMetadata;\n if (typeof custom.sandboxId === \"string\") {\n return custom.sandboxId;\n }\n }\n return undefined;\n}\n","import type { ListResult } from \"./server/types.js\";\n\n/**\n * Drains all pages of a token-paginated list into a single array.\n * Newest-first APIs should reverse after calling this.\n */\nexport async function drainListPages<T>(\n fetchPage: (pageToken?: string) => Promise<ListResult<T>>,\n): Promise<T[]> {\n const items: T[] = [];\n let pageToken: string | undefined;\n for (;;) {\n const page = await fetchPage(pageToken);\n items.push(...page.data);\n if (page.nextPageToken == null || page.nextPageToken === \"\") {\n break;\n }\n pageToken = page.nextPageToken;\n }\n return items;\n}\n","import type { Turn } from \"./server/index.js\";\n\nexport function extractTurnUserText(input: Turn[\"input\"]): string {\n const parts: string[] = [];\n for (const item of input ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const { content } = item;\n if (typeof content === \"string\") {\n parts.push(content);\n continue;\n }\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n }\n }\n }\n return parts.join(\"\\n\").trim();\n}\n","import type { MessageStatus } from \"@assistant-ui/core\";\nimport type { McpAuthRequiredEvent, TurnStateDone } from \"./server/index.js\";\n\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport type { McpAuthMessageCustomMetadata } from \"./messageCustomMetadata.js\";\n\n/** `runConfig.custom` flag: resume after MCP OAuth with an empty SDK turn input. */\nexport const MCP_AUTH_RESUME_RUN_CUSTOM_KEY = \"resumeMcpAuth\";\n\ntype McpServerAuthInfo = McpAuthRequiredEvent[\"mcpServers\"][number];\n\nexport function buildMcpAuthTextParts(\n servers: readonly McpServerAuthInfo[],\n): AssistantContentPart[] {\n const linkLines = servers.map(\n (server) => `- [Authorize ${server.name}](${server.authUrl})`,\n );\n const text = [\n \"This agent needs access to external services before it can continue.\",\n \"\",\n ...linkLines,\n \"\",\n \"Open each link to sign in, then press **Continue** below.\",\n ].join(\"\\n\");\n return [{ type: \"text\", text }];\n}\n\nexport function findMcpAuthRequired(\n requiredActions: TurnStateDone[\"requiredActions\"] | undefined,\n): McpAuthRequiredEvent | undefined {\n const found = requiredActions?.find(\n (action) => action.type === \"mcp.auth_required\",\n );\n return found?.type === \"mcp.auth_required\"\n ? (found as McpAuthRequiredEvent)\n : undefined;\n}\n\nexport function mcpAuthAssistantStatus(): MessageStatus {\n return { type: \"requires-action\", reason: \"interrupt\" };\n}\n\nexport function mcpAuthMessageCustom(\n servers: readonly McpServerAuthInfo[],\n): McpAuthMessageCustomMetadata {\n return { pendingMcpAuth: true, mcpServers: [...servers] };\n}\n","import type { Turn } from \"./server/index.js\";\n\nimport {\n buildMcpAuthTextParts,\n findMcpAuthRequired,\n mcpAuthAssistantStatus,\n mcpAuthMessageCustom,\n} from \"./mcpAuth.js\";\nimport {\n findApprovalRequiredInTurn,\n toolApprovalMessageCustom,\n toolApprovalStatus,\n} from \"./toolApproval.js\";\nimport {\n findResponseRequiredInTurn,\n toolResponseMessageCustom,\n toolResponseStatus,\n} from \"./toolResponse.js\";\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nfunction buildToolApprovalUpdate(\n content: AssistantContentPart[],\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingApproval = findApprovalRequiredInTurn(turn);\n if (pendingApproval == null) {\n return { content };\n }\n return {\n content,\n status: toolApprovalStatus(),\n metadata: { custom: toolApprovalMessageCustom(pendingApproval.threadId) },\n };\n}\n\nfunction buildToolResponseUpdate(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingResponse = findResponseRequiredInTurn(turn);\n if (pendingResponse == null) {\n return update;\n }\n return {\n ...update,\n content: update.content,\n status: toolResponseStatus(),\n metadata: {\n custom: {\n ...update.metadata?.custom,\n ...toolResponseMessageCustom(pendingResponse.threadId),\n },\n },\n };\n}\n\nexport function appendToolResponseToTurnContent(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n if (update.status?.type === \"requires-action\") {\n return update;\n }\n return buildToolResponseUpdate(update, turn);\n}\n\nexport function appendToolApprovalToTurnContent(\n update: TurnStreamUpdate,\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n if (update.status?.type === \"requires-action\") {\n return update;\n }\n const approvalUpdate = buildToolApprovalUpdate(update.content, turn);\n return appendToolResponseToTurnContent(approvalUpdate, turn);\n}\n\nexport function appendMcpAuthToTurnContent(\n content: AssistantContentPart[],\n turn: Pick<Turn, \"state\">,\n): TurnStreamUpdate {\n const pendingMcpAuth = findMcpAuthRequired(\n turn.state.status === \"done\" ? turn.state.requiredActions : undefined,\n );\n if (pendingMcpAuth == null) {\n return appendToolApprovalToTurnContent({ content }, turn);\n }\n\n return appendToolApprovalToTurnContent(\n {\n content: [...content, ...buildMcpAuthTextParts(pendingMcpAuth.mcpServers)],\n status: mcpAuthAssistantStatus(),\n metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) },\n },\n turn,\n );\n}\n","import type {\n McpAuthRequiredEvent,\n Turn,\n TurnCreatedEvent,\n TurnDoneEvent,\n TurnEvent,\n TurnInputItem,\n} from \"./server/index.js\";\n\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport { PeerThreadFoldState } from \"./foldPeerThreads.js\";\nimport type { StoredApprovalDecision } from \"./toolApproval.js\";\nimport type { StoredToolResponse } from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\n/** Session-level event item from `AgentSession.listEvents`. */\nexport type GatewaySessionEventItem = {\n turnId: string;\n event: TurnCreatedEvent | TurnDoneEvent | TurnEvent;\n};\n\n/** Cursor for fetching older `listEvents` pages (scroll-up history). */\nexport type SessionHistoryPagination = {\n /** Token for the next older page; omit when exhausted. */\n olderPageToken?: string;\n hasOlder: boolean;\n};\n\n/** Turn metadata retained for cross-turn projection and subsequent required-action replay. */\nexport type SessionTurnRecord = Pick<\n Turn,\n \"id\" | \"createdAt\" | \"state\" | \"input\"\n> & {\n /** Denormalized from `input` for user/assistant interleaving during projection. */\n userText?: string;\n /** Root-thread `model.message` ids ingested with this turn (for per-group projection). */\n rootModelMessageIds?: readonly string[];\n /** sandboxId observed via a `sandbox.created` event during this turn (session-scoped, latest wins). */\n sandboxId?: string;\n};\n\nexport type RequiredActionsOverlay = {\n approvals: Map<string, StoredApprovalDecision>;\n toolResponses: Map<string, StoredToolResponse>;\n};\n\nexport type ActiveStreamState = {\n turnId: string;\n update: TurnStreamUpdate;\n isContinuation: boolean;\n streamComplete?: boolean;\n};\n\nexport type PendingUserMessage = {\n turnId: string;\n /** Gateway user.message content (text-only string or text/file parts). */\n content: Extract<TurnInputItem, { type: \"user.message\" }>[\"content\"];\n createdAt: Date;\n};\n\nexport type SessionSnapshot = {\n fold: PeerThreadFoldState;\n turns: SessionTurnRecord[];\n pendingMcpAuth?: McpAuthRequiredEvent;\n pendingUser?: PendingUserMessage;\n activeStream?: ActiveStreamState;\n /** Root `model.message` ids present before the active turn group started (streaming scope). */\n groupRootBaseline?: readonly string[];\n requiredActions: RequiredActionsOverlay;\n runningTurn?: Turn;\n unstable_resume?: boolean;\n /**\n * Chronological `listEvents` items loaded so far (for prepend-on-scroll rebuild).\n * Live stream commits are not appended here — they live in `turns` / `fold`.\n */\n historyEvents?: readonly GatewaySessionEventItem[];\n historyPagination?: SessionHistoryPagination;\n};\n\nexport type ProjectSessionMessagesOptions = {\n getCreatedAt?: (messageId: string, fallback: Date) => Date;\n};\n\nexport function emptyRequiredActionsOverlay(): RequiredActionsOverlay {\n return {\n approvals: new Map(),\n toolResponses: new Map(),\n };\n}\n\nexport function createEmptySessionSnapshot(): SessionSnapshot {\n return {\n fold: new PeerThreadFoldState(),\n turns: [],\n requiredActions: emptyRequiredActionsOverlay(),\n };\n}\n\nexport function turnToSessionRecord(turn: Turn): SessionTurnRecord {\n const userText = extractTurnUserText(turn.input);\n return {\n id: turn.id,\n ...(userText ? { userText } : {}),\n createdAt: turn.createdAt,\n state: turn.state,\n input: turn.input,\n };\n}\n\n/** Builds a SessionTurnRecord from session-level TurnCreatedEvent + TurnDoneEvent data. */\nexport function sessionEventsToSessionRecord(\n turnId: string,\n createdEvent: TurnCreatedEvent,\n doneEvent: TurnDoneEvent,\n rootModelMessageIds: readonly string[],\n sandboxId?: string,\n): SessionTurnRecord {\n const userText = extractTurnUserText(createdEvent.input);\n return {\n id: turnId,\n ...(userText ? { userText } : {}),\n createdAt: createdEvent.createdAt,\n state: doneEvent.state,\n input: createdEvent.input,\n rootModelMessageIds,\n ...(sandboxId != null ? { sandboxId } : {}),\n };\n}\n\n/** Returns a new snapshot wrapper; fold maps may be mutated in place before calling. */\nexport function replaceSessionSnapshot(\n snapshot: SessionSnapshot,\n patch: Partial<Omit<SessionSnapshot, \"requiredActions\">> & {\n requiredActions?: RequiredActionsOverlay;\n },\n): SessionSnapshot {\n return {\n ...snapshot,\n ...patch,\n ...(patch.requiredActions != null\n ? { requiredActions: patch.requiredActions }\n : {}),\n };\n}\n\nexport function cloneRequiredActionsOverlay(\n overlay: RequiredActionsOverlay,\n): RequiredActionsOverlay {\n return {\n approvals: new Map(overlay.approvals),\n toolResponses: new Map(overlay.toolResponses),\n };\n}\n","import type {\n AppendMessage,\n CompleteAttachment,\n ExportedMessageRepositoryItem,\n MessageStatus,\n ThreadMessage,\n ThreadUserMessagePart,\n} from \"@assistant-ui/core\";\nimport type {\n McpAuthRequiredEvent,\n Turn,\n TurnCreatedEvent,\n TurnDoneEvent,\n TurnEvent,\n TurnInputItem,\n TurnStreamData,\n} from \"./server/index.js\";\nimport type { AgentChatServer } from \"./server/types.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport { drainListPages } from \"./listPages.js\";\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport {\n buildRootAssistantContent,\n buildRootAssistantContentForIds,\n findFirstPendingApprovalThreadId,\n findFirstPendingResponseThreadId,\n ingestStreamEvent,\n ingestTurnEvent,\n PeerThreadFoldState,\n type ThreadBucket,\n} from \"./foldPeerThreads.js\";\nimport {\n appendMcpAuthToTurnContent,\n appendToolApprovalToTurnContent,\n} from \"./turnEventHelpers.js\";\nimport type { AssistantContentPart } from \"./modelMessageContent.js\";\nimport {\n extractImageUrlFromUserContentItem,\n imageUrlToAttachment,\n} from \"./modelMessageImageContent.js\";\nimport {\n type SessionSnapshot,\n type ProjectSessionMessagesOptions,\n type SessionTurnRecord,\n type RequiredActionsOverlay,\n type GatewaySessionEventItem,\n type SessionHistoryPagination,\n createEmptySessionSnapshot,\n emptyRequiredActionsOverlay,\n replaceSessionSnapshot,\n sessionEventsToSessionRecord,\n turnToSessionRecord,\n} from \"./sessionSnapshot.js\";\nimport {\n applyApprovalDecisionsToContent,\n collectApprovalDecisionsFromTurnInput,\n collectSubsequentApprovalDecisions,\n messageHasPendingApprovals,\n TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY,\n toolApprovalMessageCustom,\n toolApprovalStatus,\n} from \"./toolApproval.js\";\nimport {\n applyStagedResponsesToContent,\n applyUserToolResponsesToFold,\n collectSubsequentToolResponses,\n collectToolResponsesFromTurnInput,\n messageHasPendingResponses,\n TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,\n toolResponseMessageCustom,\n toolResponseStatus,\n} from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\nimport {\n buildMcpAuthTextParts,\n mcpAuthAssistantStatus,\n mcpAuthMessageCustom,\n} from \"./mcpAuth.js\";\n\n/**\n * Turn / event → assistant-ui normalization\n *\n * This module is the projection layer: it turns gateway session state into\n * `ThreadMessage[]` for `@assistant-ui/core`. The hook in\n * `useTrueFoundryAgentMessages.ts` owns the mutable `SessionSnapshot`; this\n * file defines how that snapshot is built and rendered.\n *\n * ## Data model\n *\n * Gateway side:\n * - A **session** has ordered **turns** (each with `input`, `state`, `listEvents`).\n * - A turn's **input** is either a user message (`user.message`) or a continuation\n * (`user.tool_response`, `user.tool_approval`, …).\n * - **Events** (`model.message`, `tool.*`, `thread.created`, …) arrive on a\n * **thread id**; the root conversation uses `ROOT_THREAD_ID` (`\"main\"`).\n *\n * Local side (`SessionSnapshot` in `sessionSnapshot.ts`):\n * - `fold` — accumulated events across all threads (see `foldPeerThreads.ts`).\n * - `turns` — committed turn records, each optionally storing\n * `rootModelMessageIds` (root-thread `model.message` ids ingested with that turn).\n * - `pendingUser` / `activeStream` — optimistic UI while a turn is in flight.\n * - `groupRootBaseline` — root `model.message` ids that existed before the active\n * turn group started; used to scope live streaming to the current group only.\n * - `requiredActions` — locally staged approval/response decisions before resume.\n *\n * Output:\n * - Alternating **user** / **assistant** `ThreadMessage` pairs.\n * - One assistant message per **turn group** (user turn + its continuation turns).\n *\n * ## Turn groups\n *\n * A **turn group** starts at a turn whose input contains `user.message`. Later\n * turns with only continuation inputs (tool response, tool approval, MCP resume)\n * belong to the same group and are folded into the same assistant message.\n *\n * Root content for a group is the union of `rootModelMessageIds` on every turn\n * in that group. Prior groups must not leak in: scope with\n * `rootModelMessageIdsSinceBaseline(fold, baseline)` where\n * `baseline = groupRootBaseline ?? computeGroupRootBaseline(turns)`.\n *\n * ## Pipeline\n *\n * 1. **Ingest** — `ingestStreamEvent` / `ingestTurnEvent` append events into\n * per-thread buckets in `PeerThreadFoldState`. Deltas merge in place.\n *\n * 2. **Fold to content** — `buildRootAssistantContentForIds` walks scoped\n * `model.message` ids and emits assistant-ui parts (reasoning, text, tool-call).\n * Sub-agent child threads are attached under `create_sub_agent` tool-calls as\n * nested `messages` (see `attachSubAgentMessages` in `foldPeerThreads.ts`).\n *\n * 3. **History projection** — `projectHistoryTurns` walks committed `turns`:\n * - User turn → push user message; push assistant if the group has content.\n * - Continuation turn → merge assistant content into the last assistant message\n * in the group (same `*-assistant` id as the user turn that opened the group).\n * - Apply answers from later continuation turns onto earlier tool-calls via\n * `collectSubsequentApprovalDecisions` / `collectSubsequentToolResponses`.\n * - A paused group's assistant message keeps `requires-action` until a later\n * continuation turn resolves all its approvals/responses, then downgrades\n * to the turn-state status (`complete`, `error`, `cancelled`).\n *\n * 4. **Live projection** — `projectSessionMessages` = history + `pendingUser` +\n * `activeStream`. While streaming, `streamTurnEvents` yields content scoped to\n * `groupRootBaseline`. When `streamComplete`, `projectActiveStreamUpdate`\n * rebuilds from the fold (same baseline scoping as streaming).\n *\n * 5. **Staged overlay** — Before the SDK resume turn is sent, user decisions sit\n * in `requiredActions` and are merged onto messages by\n * `applyRequiredActionsOverlayToMessages` so the UI shows interrupt + result\n * together. Resume is batched: all pending approvals and ask-user answers in\n * a paused message must be resolved before `sendTurn({ inputs })`.\n *\n * ## Required actions (assistant-ui mapping)\n *\n * | Gateway event / input | assistant-ui representation |\n * |-----------------------------|------------------------------------------------------|\n * | `tool.approval_required` | `tool-call` with `approval: { id }`, status |\n * | | `requires-action` / `tool-calls`, custom thread id |\n * | `user.tool_approval` | closes `tool.approval_required`: sets `approval.approved` |\n * | | (+ optional reason) on tool-call |\n * | `tool.response_required` | `tool-call` with `interrupt: { type: \"human\", … }` |\n * | (ask_user_question) | payload parsed from tool args (`askUserQuestion.ts`) |\n * | `user.tool_response` | closes `tool.response_required`: sets `result` on |\n * | | tool-call and clears the pending `interrupt` |\n * | `mcp.auth_required` | Appended auth link text parts; status `interrupt` |\n *\n * Sub-agent threads can have their own pending approval/response; metadata\n * `toolApprovalThreadId` / `toolResponseThreadId` on nested assistant messages\n * scopes resume inputs to the correct thread.\n *\n * A sub-agent stays attached under the `create_sub_agent` tool-call that spawned\n * it, which lives in the root `model.message` of the turn that opened the group.\n * The child thread keeps producing events across several turns (spawn turn, then\n * continuation turns that answer its required actions), and all of them render\n * under that single tool-call in the group's one assistant message.\n *\n * INVARIANT — while a sub-agent is active the parent agent is paused awaiting a\n * required action, so every following turn until it finishes is a continuation\n * (`user.tool_response` / `user.tool_approval` / MCP resume), NOT a `user.message`.\n * If a sub-agent is spawned/active in turn 1, turn 2 cannot carry `user.message`\n * input. A `user.message` there would open a new turn group (`userText` boundary)\n * and split the still-running sub-agent's events away from its tool-call. The\n * gateway enforces this; the projection relies on it for correct nesting.\n *\n * ## Assumptions\n *\n * - Root-thread model messages use `threadId === ROOT_THREAD_ID`.\n * - Turn order in `snapshot.turns` matches gateway chronological order.\n * - `rootModelMessageIds` on committed turns is accurate (set in\n * `commitActiveStream` when a stream completes).\n * - Continuation turns never carry `user.message`; that boundary defines groups.\n * In particular, while a sub-agent (or any tool) is mid-flight awaiting a\n * required action, the next turn is always a continuation, never a new\n * `user.message`.\n * - Tool-call identity is stable via `toolCallId` across events, fold state, and\n * assistant-ui parts.\n * - Reload (`buildSnapshotFromSessionEvents`) and live paths must produce the same\n * per-group scoping; history uses cumulative `groupRootIds` per turn index,\n * live uses `groupRootBaseline`.\n */\n\nconst TURN_EVENTS_PAGE_SIZE = 25;\nconst SESSION_EVENTS_PAGE_SIZE = 100;\n/** Cap how many event pages initial load / load-older may chain for a group boundary. */\nconst MAX_HISTORY_BOUNDARY_PAGES = 10;\n\ntype FetchSessionEventsOptions = {\n /**\n * Newest turn in the listing window (initial load only). Lists that turn and\n * its ancestors. Omit to use the session last turn. Running-turn events are\n * excluded by the API — subscribe to that turn for live events.\n */\n lastTurnId?: string;\n};\n\ntype SessionEventsPageResult = {\n /** Newest-first items from this request. */\n itemsNewestFirst: GatewaySessionEventItem[];\n olderPageToken?: string;\n hasOlder: boolean;\n};\n\n/**\n * Drops a leading incomplete turn (events before the first `turn.created`) that\n * appears when a page boundary splits a turn.\n */\nfunction trimIncompleteLeadingEvents(\n itemsAsc: GatewaySessionEventItem[],\n): GatewaySessionEventItem[] {\n const start = itemsAsc.findIndex((item) => item.event.type === \"turn.created\");\n if (start === -1) {\n return [];\n }\n return itemsAsc.slice(start);\n}\n\n/**\n * Whether the oldest complete turn in a chronological window opens a user group.\n * `incomplete` means we still lack a finished oldest turn (need an older page).\n */\nfunction oldestCompleteTurnGroupState(\n itemsAsc: GatewaySessionEventItem[],\n): \"user-group\" | \"continuation\" | \"incomplete\" {\n const trimmed = trimIncompleteLeadingEvents(itemsAsc);\n if (trimmed.length === 0) {\n return \"incomplete\";\n }\n const created = trimmed[0];\n if (created?.event.type !== \"turn.created\") {\n return \"incomplete\";\n }\n const hasDone = trimmed.some(\n (item) => item.turnId === created.turnId && item.event.type === \"turn.done\",\n );\n if (!hasDone) {\n return \"incomplete\";\n }\n return extractTurnUserText(created.event.input) != null\n ? \"user-group\"\n : \"continuation\";\n}\n\nasync function fetchSessionEventsPage(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions & { pageToken?: string },\n): Promise<SessionEventsPageResult> {\n const page = await server.listEvents({\n sessionId,\n limit: SESSION_EVENTS_PAGE_SIZE,\n ...(options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}),\n ...(options?.pageToken != null ? { pageToken: options.pageToken } : {}),\n });\n const olderPageToken = page.nextPageToken;\n const hasOlder = olderPageToken != null && olderPageToken !== \"\";\n return {\n itemsNewestFirst: page.data as GatewaySessionEventItem[],\n ...(olderPageToken != null && olderPageToken !== \"\"\n ? { olderPageToken }\n : {}),\n hasOlder,\n };\n}\n\n/**\n * Fetches pages until the chronological window starts on a complete user-message\n * turn group (or history is exhausted).\n */\nasync function fetchSessionEventsWindow(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions & { pageToken?: string },\n): Promise<{\n itemsAsc: GatewaySessionEventItem[];\n olderPageToken?: string;\n hasOlder: boolean;\n}> {\n let itemsNewestFirst: GatewaySessionEventItem[] = [];\n let pageToken = options?.pageToken;\n let olderPageToken: string | undefined;\n let hasOlder = false;\n\n for (let pageCount = 0; pageCount < MAX_HISTORY_BOUNDARY_PAGES; pageCount++) {\n const page = await fetchSessionEventsPage(server, sessionId, {\n ...options,\n ...(pageToken != null ? { pageToken } : {}),\n });\n itemsNewestFirst = [...itemsNewestFirst, ...page.itemsNewestFirst];\n olderPageToken = page.olderPageToken;\n hasOlder = page.hasOlder;\n\n const itemsAsc = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());\n const groupState = oldestCompleteTurnGroupState(itemsAsc);\n if (groupState === \"user-group\" || !hasOlder) {\n return {\n itemsAsc,\n ...(olderPageToken != null ? { olderPageToken } : {}),\n hasOlder,\n };\n }\n\n if (olderPageToken == null) {\n return { itemsAsc, hasOlder: false };\n }\n pageToken = olderPageToken;\n }\n\n const itemsAsc = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());\n return {\n itemsAsc,\n ...(olderPageToken != null ? { olderPageToken } : {}),\n hasOlder,\n };\n}\n\n/**\n * Fetches session-level events via `server.listEvents()`. The API returns pages\n * in desc order (newest first); the collected array is reversed before returning\n * so callers receive events in chronological (asc) order.\n *\n * Used by rewind/edit paths that need the full ancestor window.\n */\nasync function fetchAllSessionEvents(\n server: AgentChatServer,\n sessionId: string,\n options?: FetchSessionEventsOptions,\n): Promise<GatewaySessionEventItem[]> {\n const items = await drainListPages((pageToken) =>\n server.listEvents({\n sessionId,\n limit: SESSION_EVENTS_PAGE_SIZE,\n ...(options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}),\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n items.reverse();\n return items as GatewaySessionEventItem[];\n}\n\nfunction cloneThreadBucket(bucket: ThreadBucket): ThreadBucket {\n return {\n events: new Map(bucket.events),\n modelMessageIds: [...bucket.modelMessageIds],\n toolResults: new Map(bucket.toolResults),\n pendingApprovals: new Map(bucket.pendingApprovals),\n approvalDecisions: new Map(bucket.approvalDecisions),\n pendingResponses: new Map(bucket.pendingResponses),\n done: bucket.done,\n ...(bucket.title != null ? { title: bucket.title } : {}),\n ...(bucket.agentInfo != null ? { agentInfo: bucket.agentInfo } : {}),\n };\n}\n\n/** Prepends older fold state ahead of the currently loaded fold (scroll-up). */\nexport function prependFoldState(\n older: PeerThreadFoldState,\n newer: PeerThreadFoldState,\n): PeerThreadFoldState {\n const result = new PeerThreadFoldState();\n const threadIds = new Set([...older.threads.keys(), ...newer.threads.keys()]);\n for (const threadId of threadIds) {\n const olderBucket = older.threads.get(threadId);\n const newerBucket = newer.threads.get(threadId);\n if (olderBucket == null && newerBucket != null) {\n result.threads.set(threadId, cloneThreadBucket(newerBucket));\n continue;\n }\n if (newerBucket == null && olderBucket != null) {\n result.threads.set(threadId, cloneThreadBucket(olderBucket));\n continue;\n }\n if (olderBucket == null || newerBucket == null) {\n continue;\n }\n result.threads.set(threadId, {\n events: new Map([...olderBucket.events, ...newerBucket.events]),\n modelMessageIds: [\n ...olderBucket.modelMessageIds,\n ...newerBucket.modelMessageIds,\n ],\n toolResults: new Map([\n ...olderBucket.toolResults,\n ...newerBucket.toolResults,\n ]),\n pendingApprovals: new Map([\n ...olderBucket.pendingApprovals,\n ...newerBucket.pendingApprovals,\n ]),\n approvalDecisions: new Map([\n ...olderBucket.approvalDecisions,\n ...newerBucket.approvalDecisions,\n ]),\n pendingResponses: new Map([\n ...olderBucket.pendingResponses,\n ...newerBucket.pendingResponses,\n ]),\n done: newerBucket.done || olderBucket.done,\n ...(newerBucket.title != null || olderBucket.title != null\n ? { title: newerBucket.title ?? olderBucket.title }\n : {}),\n ...(newerBucket.agentInfo != null || olderBucket.agentInfo != null\n ? { agentInfo: newerBucket.agentInfo ?? olderBucket.agentInfo }\n : {}),\n });\n }\n for (const [threadId, link] of older.threadParents) {\n result.threadParents.set(threadId, link);\n }\n for (const [threadId, link] of newer.threadParents) {\n result.threadParents.set(threadId, link);\n }\n return result;\n}\n\n/**\n * Ingests a chronologically ordered list of session-level event items into the\n * snapshot. `turn.created` marks the start of a turn (provides user input),\n * content events are folded as usual, and `turn.done` finalises the turn record\n * and pushes it to `snapshot.turns`.\n *\n * `onTurnComplete` is called after each `turn.done` with the partially-built\n * snapshot so callers can update UI progressively. The fold state is correct at\n * that point for every turn up to and including the just-completed one.\n */\nfunction ingestSessionEventsIntoSnapshot(\n snapshot: SessionSnapshot,\n items: GatewaySessionEventItem[],\n onTurnComplete?: (snap: SessionSnapshot) => void,\n): void {\n let currentTurnId: string | null = null;\n let currentCreatedEvent: TurnCreatedEvent | null = null;\n let currentContentEvents: TurnEvent[] = [];\n let beforeCount = 0;\n\n for (const item of items) {\n const { turnId, event } = item;\n\n if (event.type === \"turn.created\") {\n currentTurnId = turnId;\n currentCreatedEvent = event;\n currentContentEvents = [];\n beforeCount =\n snapshot.fold.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;\n } else if (event.type === \"turn.done\") {\n if (currentTurnId == null || currentCreatedEvent == null) {\n continue;\n }\n\n const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(\n beforeCount,\n );\n\n const sandboxEvent = currentContentEvents.find(\n (ev): ev is Extract<TurnEvent, { type: \"sandbox.created\" }> =>\n ev.type === \"sandbox.created\",\n );\n\n applyUserToolResponsesToFold(\n snapshot.fold,\n currentCreatedEvent.input ?? [],\n );\n snapshot.turns.push(\n sessionEventsToSessionRecord(\n currentTurnId,\n currentCreatedEvent,\n event,\n rootModelMessageIds,\n sandboxEvent?.sandboxId,\n ),\n );\n\n // Pass a new object reference so React's Object.is check in\n // useState sees a changed value and schedules a re-render.\n // The snapshot is mutated in place throughout this loop, so\n // passing `snapshot` directly would make every tick look identical\n // to React after the first setSnapshot call.\n onTurnComplete?.(replaceSessionSnapshot(snapshot, {}));\n\n currentTurnId = null;\n currentCreatedEvent = null;\n currentContentEvents = [];\n } else {\n if (currentTurnId != null) {\n ingestTurnEvent(snapshot.fold, event as TurnEvent);\n currentContentEvents.push(event as TurnEvent);\n }\n }\n }\n}\n\nfunction attachRunningTurn(\n snapshot: SessionSnapshot,\n runningTurn: Turn | undefined,\n): SessionSnapshot {\n if (runningTurn == null) {\n return snapshot;\n }\n // Session-level history excludes the running turn. Apply continuation inputs\n // from the turn listing so answered approvals / ask-user prompts are not\n // restored as pending while reconnecting to that turn after a refresh.\n applyUserToolResponsesToFold(snapshot.fold, runningTurn.input ?? []);\n const pendingUserText = extractTurnUserText(runningTurn.input);\n return replaceSessionSnapshot(snapshot, {\n runningTurn,\n unstable_resume: true as const,\n groupRootBaseline: computeGroupRootBaseline(snapshot.turns),\n ...(pendingUserText\n ? {\n pendingUser: {\n turnId: runningTurn.id,\n content: extractTurnUserMessageContent(runningTurn.input),\n createdAt: new Date(runningTurn.createdAt),\n },\n }\n : {}),\n });\n}\n\n/**\n * Builds a session snapshot using the session-level `listEvents` API.\n *\n * Loads the newest event page (extending only when a page boundary splits a\n * turn group), then leaves older pages for `prependOlderSessionHistory`.\n * Only `listTurns({ limit: 1 })` is called first to detect a currently-running\n * turn (the session-level API does not return events for the running turn).\n *\n * `onProgress` is called after each complete turn is ingested so callers can\n * update the UI progressively while the processing loop runs.\n */\nexport async function buildSnapshotFromSessionEvents(\n server: AgentChatServer,\n sessionId: string,\n onProgress?: (snap: SessionSnapshot) => void,\n): Promise<SessionSnapshot> {\n // Detect a running turn with a single listTurns page — do not drain pagination.\n const turnsPage = await server.listTurns({ sessionId, limit: 1 });\n const newestTurn = turnsPage.data[0] as Turn | undefined;\n const runningTurn =\n newestTurn?.state?.status === \"running\" ? newestTurn : undefined;\n\n const window = await fetchSessionEventsWindow(server, sessionId);\n const historyPagination: SessionHistoryPagination = {\n hasOlder: window.hasOlder,\n ...(window.olderPageToken != null\n ? { olderPageToken: window.olderPageToken }\n : {}),\n };\n\n const snapshot = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(snapshot, window.itemsAsc, onProgress);\n\n const withHistory = replaceSessionSnapshot(snapshot, {\n historyEvents: window.itemsAsc,\n historyPagination,\n });\n\n return attachRunningTurn(withHistory, runningTurn);\n}\n\n/**\n * Fetches the next older `listEvents` window and prepends it onto `snapshot`\n * without tearing down live stream / pending UI state.\n */\nexport async function prependOlderSessionHistory(\n server: AgentChatServer,\n sessionId: string,\n snapshot: SessionSnapshot,\n): Promise<SessionSnapshot> {\n const pagination = snapshot.historyPagination;\n if (pagination?.hasOlder !== true || pagination.olderPageToken == null) {\n return snapshot;\n }\n\n const window = await fetchSessionEventsWindow(server, sessionId, {\n pageToken: pagination.olderPageToken,\n });\n if (window.itemsAsc.length === 0) {\n return replaceSessionSnapshot(snapshot, {\n historyPagination: { hasOlder: false },\n });\n }\n\n const olderSnap = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(olderSnap, window.itemsAsc);\n\n const existingIds = new Set(snapshot.turns.map((turn) => turn.id));\n const olderTurns = olderSnap.turns.filter((turn) => !existingIds.has(turn.id));\n const mergedFold = prependFoldState(olderSnap.fold, snapshot.fold);\n const historyEvents = [\n ...window.itemsAsc,\n ...(snapshot.historyEvents ?? []),\n ];\n const olderRootIds = olderTurns.flatMap(\n (turn) => turn.rootModelMessageIds ?? [],\n );\n\n return replaceSessionSnapshot(snapshot, {\n fold: mergedFold,\n turns: [...olderTurns, ...snapshot.turns],\n historyEvents,\n historyPagination: {\n hasOlder: window.hasOlder,\n ...(window.olderPageToken != null\n ? { olderPageToken: window.olderPageToken }\n : {}),\n },\n ...(snapshot.groupRootBaseline != null\n ? {\n groupRootBaseline: [\n ...olderRootIds,\n ...snapshot.groupRootBaseline,\n ],\n }\n : {}),\n });\n}\n\nexport type ConvertTurnsResult = {\n messages: ThreadMessage[];\n foldState: PeerThreadFoldState;\n runningTurn?: Turn;\n unstable_resume?: boolean;\n};\n\nfunction assistantStatusFromTurnState(state: Turn[\"state\"]): MessageStatus {\n switch (state.status) {\n case \"done\":\n return { type: \"complete\", reason: \"stop\" };\n case \"error\":\n return { type: \"incomplete\", reason: \"error\", error: state.message };\n case \"cancelled\":\n return { type: \"incomplete\", reason: \"cancelled\" };\n case \"running\":\n return { type: \"running\" };\n default:\n return { type: \"complete\", reason: \"unknown\" };\n }\n}\n\nfunction resolveCreatedAt(\n messageId: string,\n fallback: Date,\n options?: ProjectSessionMessagesOptions,\n): Date {\n return options?.getCreatedAt?.(messageId, fallback) ?? fallback;\n}\n\nfunction parseDataUriMime(data: string): string {\n if (!data.startsWith(\"data:\")) {\n return \"application/octet-stream\";\n }\n const match = /^data:([^;,]+)/.exec(data);\n return match?.[1] ?? \"application/octet-stream\";\n}\n\nfunction fileContentToAttachment(\n file: FileContent,\n attachmentId: string,\n): CompleteAttachment {\n const mimeType = parseDataUriMime(file.data);\n if (mimeType.startsWith(\"image/\")) {\n return {\n id: attachmentId,\n type: \"image\",\n name: file.name,\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: file.data, filename: file.name }],\n };\n }\n return {\n id: attachmentId,\n type: \"file\",\n name: file.name,\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n mimeType,\n filename: file.name,\n data: file.data,\n },\n ],\n };\n}\n\n/** Projects gateway turn input onto an assistant-ui user message (text + attachments). */\nexport function buildUserMessageFromTurnInput(\n turnId: string,\n input: Turn[\"input\"],\n createdAt: string | Date,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const fallback = createdAt instanceof Date ? createdAt : new Date(createdAt);\n const id = `${turnId}-user`;\n const content: ThreadUserMessagePart[] = [];\n const attachments: CompleteAttachment[] = [];\n\n for (const item of input ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const messageContent = item.content;\n if (typeof messageContent === \"string\") {\n content.push({ type: \"text\", text: messageContent });\n continue;\n }\n for (const part of messageContent) {\n if (part.type === \"text\") {\n content.push({ type: \"text\", text: part.text });\n } else if (part.type === \"file\") {\n attachments.push(\n fileContentToAttachment(\n part,\n `${turnId}-file-${attachments.length}`,\n ),\n );\n } else {\n const imageUrl = extractImageUrlFromUserContentItem(part);\n if (imageUrl != null) {\n attachments.push(\n imageUrlToAttachment(\n imageUrl,\n `${turnId}-file-${attachments.length}`,\n ),\n );\n }\n }\n }\n }\n\n return {\n id,\n role: \"user\",\n content: content.length > 0 ? content : [{ type: \"text\", text: \"\" }],\n attachments,\n createdAt: resolveCreatedAt(id, fallback, options),\n metadata: { custom: {} },\n };\n}\n\nfunction buildAssistantMessage(\n turnId: string,\n content: AssistantContentPart[],\n createdAt: string | Date,\n status: MessageStatus,\n custom: Record<string, unknown> = {},\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const fallback = createdAt instanceof Date ? createdAt : new Date(createdAt);\n const id = `${turnId}-assistant`;\n return {\n id,\n role: \"assistant\",\n content,\n status,\n createdAt: resolveCreatedAt(id, fallback, options),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom,\n },\n };\n}\n\nasync function ingestTurnEventsIntoFold(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n foldState: PeerThreadFoldState,\n): Promise<void> {\n if (server.listTurnEvents == null) {\n return;\n }\n const events = await drainListPages((pageToken) =>\n server.listTurnEvents!({\n sessionId,\n turnId,\n order: \"asc\",\n limit: TURN_EVENTS_PAGE_SIZE,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n for (const event of events) {\n ingestTurnEvent(foldState, event as TurnEvent);\n }\n}\n\nasync function fetchTurnEvents(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n): Promise<TurnEvent[]> {\n if (server.listTurnEvents == null) {\n return [];\n }\n const events = await drainListPages((pageToken) =>\n server.listTurnEvents!({\n sessionId,\n turnId,\n order: \"asc\",\n limit: TURN_EVENTS_PAGE_SIZE,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n return events as TurnEvent[];\n}\n\nfunction ingestCollectedEventsIntoFold(\n foldState: PeerThreadFoldState,\n events: TurnEvent[],\n): void {\n for (const event of events) {\n ingestTurnEvent(foldState, event);\n }\n}\n\nasync function fetchAllTurnEventsWithConcurrency(\n server: AgentChatServer,\n sessionId: string,\n turns: Turn[],\n concurrency: number,\n): Promise<TurnEvent[][]> {\n const results: TurnEvent[][] = new Array(turns.length);\n const pool = new Set<Promise<void>>();\n for (let i = 0; i < turns.length; i++) {\n const idx = i;\n const turn = turns[idx]!;\n const p: Promise<void> = fetchTurnEvents(server, sessionId, turn.id).then(\n (events) => {\n results[idx] = events;\n pool.delete(p);\n },\n );\n pool.add(p);\n if (pool.size >= concurrency) await Promise.race(pool);\n }\n await Promise.all(pool);\n return results;\n}\n\nexport function rootModelMessageIdsSinceBaseline(\n foldState: PeerThreadFoldState,\n baseline: readonly string[],\n): string[] {\n const bucket = foldState.threads.get(ROOT_THREAD_ID);\n if (bucket == null) {\n return [];\n }\n if (baseline.length === 0) {\n return [...bucket.modelMessageIds];\n }\n const baselineSet = new Set(baseline);\n return bucket.modelMessageIds.filter((id) => !baselineSet.has(id));\n}\n\nexport function computeGroupRootBaseline(turns: SessionTurnRecord[]): string[] {\n let groupStartIndex = turns.length - 1;\n while (groupStartIndex >= 0 && turns[groupStartIndex]?.userText == null) {\n groupStartIndex--;\n }\n const baseline: string[] = [];\n for (let i = 0; i < groupStartIndex; i++) {\n baseline.push(...(turns[i]?.rootModelMessageIds ?? []));\n }\n return baseline;\n}\n\nfunction buildTurnUpdateFromFold(\n foldState: PeerThreadFoldState,\n turn: Pick<Turn, \"state\">,\n rootModelMessageIds: readonly string[],\n): TurnStreamUpdate {\n const content = buildRootAssistantContentForIds(foldState, rootModelMessageIds);\n let update: TurnStreamUpdate = { content };\n update = appendMcpAuthToTurnContent(update.content, turn);\n update = appendToolApprovalToTurnContent(update, turn);\n return update;\n}\n\nfunction contentHasPendingRequiredActions(\n content: readonly AssistantContentPart[],\n): boolean {\n const message: ThreadMessage = {\n id: \"pending-check\",\n role: \"assistant\",\n content,\n status: { type: \"complete\", reason: \"stop\" },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n };\n return messageHasPendingApprovals(message) || messageHasPendingResponses(message);\n}\n\nfunction resolveProjectedRequiredActionState(\n turnUpdate: TurnStreamUpdate,\n content: readonly AssistantContentPart[],\n record: Pick<Turn, \"state\">,\n): { status: MessageStatus; custom: Record<string, unknown> } {\n let status = turnUpdate.status ?? assistantStatusFromTurnState(record.state);\n let custom = { ...(turnUpdate.metadata?.custom ?? {}) };\n\n if (\n status.type === \"requires-action\" &&\n status.reason === \"tool-calls\" &&\n !contentHasPendingRequiredActions(content)\n ) {\n status = assistantStatusFromTurnState(record.state);\n const {\n [TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY]: _approvalThreadId,\n [TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY]: _responseThreadId,\n ...restCustom\n } = custom;\n custom = restCustom;\n }\n\n return { status, custom };\n}\n\nfunction projectActiveStreamUpdate(snapshot: SessionSnapshot): TurnStreamUpdate {\n const activeStream = snapshot.activeStream;\n if (activeStream == null) {\n throw new Error(\"projectActiveStreamUpdate requires an active stream\");\n }\n\n const hasStagedOverlay =\n snapshot.requiredActions.approvals.size > 0 ||\n snapshot.requiredActions.toolResponses.size > 0;\n\n // While the user has staged a response locally, keep the paused stream update\n // so required-action collection can pair interrupt + result before resume.\n if (hasStagedOverlay) {\n return activeStream.update;\n }\n\n const baseline =\n snapshot.groupRootBaseline ?? computeGroupRootBaseline(snapshot.turns);\n const rootModelMessageIds = rootModelMessageIdsSinceBaseline(\n snapshot.fold,\n baseline,\n );\n\n const foldContent = buildRootAssistantContentForIds(\n snapshot.fold,\n rootModelMessageIds,\n );\n const content =\n foldContent.length > 0 ? foldContent : activeStream.update.content;\n\n const turnRecord = snapshot.turns.find((turn) => turn.id === activeStream.turnId);\n const turnLike = turnRecord ?? snapshot.runningTurn;\n\n const rebuilt =\n turnLike != null\n ? buildTurnUpdateFromFold(snapshot.fold, turnLike, rootModelMessageIds)\n : { content };\n\n return {\n ...activeStream.update,\n content,\n metadata: rebuilt.metadata ?? activeStream.update.metadata,\n status: rebuilt.status ?? activeStream.update.status,\n };\n}\n\nfunction applyRequiredActionsOverlayToMessages(\n messages: ThreadMessage[],\n overlay: RequiredActionsOverlay,\n): ThreadMessage[] {\n if (overlay.approvals.size === 0 && overlay.toolResponses.size === 0) {\n return messages;\n }\n\n return messages.map((message) => {\n if (message.role !== \"assistant\") {\n return message;\n }\n\n let { content } = message;\n if (overlay.approvals.size > 0) {\n content = applyApprovalDecisionsToContent(content, overlay.approvals);\n }\n if (overlay.toolResponses.size > 0) {\n content = applyStagedResponsesToContent(content, overlay.toolResponses);\n }\n\n if (content === message.content) {\n return message;\n }\n\n return { ...message, content: [...content] };\n });\n}\n\nfunction projectHistoryTurns(\n snapshot: SessionSnapshot,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage[] {\n const messages: ThreadMessage[] = [];\n let lastAssistantIndex: number | undefined;\n let groupRootIds: string[] = [];\n let sandboxId: string | undefined;\n\n for (let turnIndex = 0; turnIndex < snapshot.turns.length; turnIndex++) {\n const record = snapshot.turns[turnIndex]!;\n const turnRootIds = record.rootModelMessageIds ?? [];\n sandboxId = record.sandboxId ?? sandboxId;\n\n if (record.userText) {\n groupRootIds = [...turnRootIds];\n } else {\n groupRootIds = [...groupRootIds, ...turnRootIds];\n }\n\n const turnUpdate = buildTurnUpdateFromFold(snapshot.fold, record, groupRootIds);\n let content = turnUpdate.content;\n\n const subsequentDecisions = collectSubsequentApprovalDecisions(\n snapshot.turns,\n turnIndex,\n );\n if (subsequentDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, subsequentDecisions);\n }\n\n const subsequentResponses = collectSubsequentToolResponses(\n snapshot.turns,\n turnIndex,\n );\n if (subsequentResponses.size > 0) {\n content = applyStagedResponsesToContent(content, subsequentResponses);\n }\n\n const currentResponses = collectToolResponsesFromTurnInput(record.input);\n if (currentResponses.size > 0) {\n content = applyStagedResponsesToContent(content, currentResponses);\n }\n\n const currentDecisions = collectApprovalDecisionsFromTurnInput(record.input);\n if (currentDecisions.size > 0) {\n content = applyApprovalDecisionsToContent(content, currentDecisions);\n }\n\n const { status, custom: baseCustom } = resolveProjectedRequiredActionState(\n turnUpdate,\n content,\n record,\n );\n // Continuation turns fold into the previous assistant message and overwrite this custom,\n // so a folded message reports the latest turn that contributed to it — the one whose\n // sandbox wrote the newest artifacts.\n const custom = {\n ...baseCustom,\n turnId: record.id,\n ...(sandboxId != null ? { sandboxId } : {}),\n };\n\n if (record.userText) {\n messages.push(\n buildUserMessageFromTurnInput(\n record.id,\n record.input,\n record.createdAt,\n options,\n ),\n );\n\n if (record.state.status === \"running\") {\n if (content.length > 0) {\n messages.push(\n buildAssistantMessage(\n record.id,\n content,\n record.createdAt,\n status,\n custom,\n options,\n ),\n );\n lastAssistantIndex = messages.length - 1;\n }\n break;\n }\n\n if (content.length > 0) {\n messages.push(\n buildAssistantMessage(\n record.id,\n content,\n record.createdAt,\n status,\n custom,\n options,\n ),\n );\n lastAssistantIndex = messages.length - 1;\n }\n } else if (content.length > 0 && lastAssistantIndex != null) {\n if (record.state.status === \"running\") {\n break;\n }\n const existing = messages[lastAssistantIndex] as Extract<\n ThreadMessage,\n { role: \"assistant\" }\n >;\n messages[lastAssistantIndex] = {\n ...existing,\n content,\n status,\n metadata: {\n ...existing.metadata,\n custom,\n },\n };\n } else if (record.state.status === \"running\") {\n break;\n }\n }\n\n return messages;\n}\n\nexport function projectSessionMessages(\n snapshot: SessionSnapshot,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage[] {\n let messages = projectHistoryTurns(snapshot, options);\n\n if (snapshot.pendingUser != null) {\n messages.push(\n buildUserMessageFromTurnInput(\n snapshot.pendingUser.turnId,\n [{ type: \"user.message\", content: snapshot.pendingUser.content }],\n snapshot.pendingUser.createdAt,\n options,\n ),\n );\n }\n\n if (snapshot.activeStream != null) {\n const { turnId, update, isContinuation, streamComplete } =\n snapshot.activeStream;\n const resolvedUpdate =\n streamComplete === true ? projectActiveStreamUpdate(snapshot) : update;\n\n const last = messages.at(-1);\n const existingAssistant =\n isContinuation && last?.role === \"assistant\" ? last : undefined;\n let assistantMessage = turnStreamUpdateToAssistantMessage(\n turnId,\n resolvedUpdate,\n existingAssistant,\n options,\n );\n if (streamComplete === true && resolvedUpdate.status == null) {\n assistantMessage = {\n ...assistantMessage,\n status: { type: \"complete\", reason: \"stop\" },\n };\n }\n\n if (isContinuation && last?.role === \"assistant\") {\n messages = [...messages.slice(0, -1), assistantMessage];\n } else {\n messages = [...messages, assistantMessage];\n }\n }\n\n return applyRequiredActionsOverlayToMessages(\n messages,\n snapshot.requiredActions,\n );\n}\n\nconst DEFAULT_LIST_EVENTS_CONCURRENCY = 5;\n\nfunction ingestTurnsIntoSnapshot(\n snapshot: SessionSnapshot,\n turns: Turn[],\n eventArrays: TurnEvent[][],\n): Turn | undefined {\n let runningTurn: Turn | undefined;\n\n for (let i = 0; i < turns.length; i++) {\n const turn = turns[i]!;\n const rootBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const beforeCount = rootBucket?.modelMessageIds.length ?? 0;\n\n ingestCollectedEventsIntoFold(snapshot.fold, eventArrays[i] ?? []);\n applyUserToolResponsesToFold(snapshot.fold, turn.input ?? []);\n\n const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);\n const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(\n beforeCount,\n );\n\n const sandboxEvent = (eventArrays[i] ?? []).find(\n (event): event is Extract<TurnEvent, { type: \"sandbox.created\" }> =>\n event.type === \"sandbox.created\",\n );\n\n snapshot.turns.push({\n ...turnToSessionRecord(turn),\n rootModelMessageIds,\n ...(sandboxEvent != null ? { sandboxId: sandboxEvent.sandboxId } : {}),\n });\n\n if (turn.state.status === \"running\") {\n runningTurn = turn;\n break;\n }\n }\n\n return runningTurn;\n}\n\nexport async function buildSnapshotFromSession(\n server: AgentChatServer,\n sessionId: string,\n concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n): Promise<SessionSnapshot> {\n // Completed history comes from session-level listEvents. The session API\n // excludes the running turn — hydrate that turn via listTurnEvents so\n // convertTurnsToThreadMessages still surfaces in-flight content.\n const snapshot = await buildSnapshotFromSessionEvents(server, sessionId);\n if (snapshot.runningTurn == null) {\n return snapshot;\n }\n\n const turn = snapshot.runningTurn;\n const eventArrays = await fetchAllTurnEventsWithConcurrency(\n server,\n sessionId,\n [turn],\n concurrency,\n );\n ingestTurnsIntoSnapshot(snapshot, [turn], eventArrays);\n\n // Hydrated in-flight content lives in `turns` / `fold` now — drop the\n // reconnect seed so projection does not duplicate the user bubble.\n return replaceSessionSnapshot(snapshot, {\n runningTurn: turn,\n unstable_resume: true as const,\n groupRootBaseline: computeGroupRootBaseline(snapshot.turns),\n pendingUser: undefined,\n });\n}\n\n/** Rebuilds session state from turns strictly before `beforeTurnId` (excludes that turn). */\nexport async function buildSnapshotBeforeTurn(\n server: AgentChatServer,\n sessionId: string,\n beforeTurnId: string,\n concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n): Promise<SessionSnapshot> {\n const turns = await listSessionTurnsOrdered(server, sessionId);\n\n const beforeIndex = turns.findIndex((turn) => turn.id === beforeTurnId);\n if (beforeIndex === -1) {\n throw new Error(`Turn ${beforeTurnId} not found in session`);\n }\n\n return buildSnapshotBeforeTurnIndex(\n server,\n sessionId,\n beforeIndex,\n concurrency,\n turns,\n );\n}\n\n/** Rebuilds session state from the first `turnIndex` turns (excludes that turn). */\nexport async function buildSnapshotBeforeTurnIndex(\n server: AgentChatServer,\n sessionId: string,\n turnIndex: number,\n _concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,\n orderedTurns?: Turn[],\n): Promise<SessionSnapshot> {\n if (turnIndex <= 0) {\n return createEmptySessionSnapshot();\n }\n\n const turns = orderedTurns ?? (await listSessionTurnsOrdered(server, sessionId));\n const turnsToInclude = turns.slice(0, turnIndex);\n const lastTurnId = turnsToInclude.at(-1)?.id;\n if (lastTurnId == null) {\n return createEmptySessionSnapshot();\n }\n\n // Anchor the session events window at the newest included turn so the\n // ancestor chain matches `[turns[0], …, turns[turnIndex - 1]]`.\n const items = await fetchAllSessionEvents(server, sessionId, { lastTurnId });\n const snapshot = createEmptySessionSnapshot();\n ingestSessionEventsIntoSnapshot(snapshot, items);\n return snapshot;\n}\n\n/** Turn id to branch from when resubmitting at `turnIndex` (`\"none\"` for first turn). */\nexport async function resolveGatewayBranchPreviousTurnId(\n server: AgentChatServer,\n sessionId: string,\n turnIndex: number,\n orderedTurns?: Turn[],\n): Promise<string> {\n if (turnIndex <= 0) {\n return \"none\";\n }\n const turns = orderedTurns ?? (await listSessionTurnsOrdered(server, sessionId));\n return turns[turnIndex - 1]?.id ?? \"none\";\n}\n\n/** Resolves `previousTurnId` by turn id so partial history windows stay correct. */\nexport async function resolveGatewayBranchPreviousTurnIdForTurn(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n): Promise<string> {\n const turns = await listSessionTurnsOrdered(server, sessionId);\n const turnIndex = turns.findIndex((turn) => turn.id === turnId);\n return resolveGatewayBranchPreviousTurnId(server, sessionId, turnIndex, turns);\n}\n\nasync function listSessionTurnsOrdered(\n server: AgentChatServer,\n sessionId: string,\n): Promise<Turn[]> {\n const turns = await drainListPages((pageToken) =>\n server.listTurns({\n sessionId,\n ...(pageToken != null ? { pageToken } : {}),\n }),\n );\n turns.reverse();\n return turns;\n}\n\nexport async function buildTurnAssistantContent(\n server: AgentChatServer,\n sessionId: string,\n turn: Pick<Turn, \"id\" | \"state\">,\n foldState?: PeerThreadFoldState,\n): Promise<AssistantContentPart[]> {\n const state = foldState ?? new PeerThreadFoldState();\n const beforeCount =\n state.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;\n await ingestTurnEventsIntoFold(server, sessionId, turn.id, state);\n const afterIds = state.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n const rootModelMessageIds = afterIds.slice(beforeCount);\n return buildTurnUpdateFromFold(state, turn, rootModelMessageIds).content;\n}\n\nexport async function convertTurnsToThreadMessages(\n server: AgentChatServer,\n sessionId: string,\n): Promise<ConvertTurnsResult> {\n const snapshot = await buildSnapshotFromSession(server, sessionId);\n const messages = projectSessionMessages(snapshot);\n\n return {\n messages,\n foldState: snapshot.fold,\n ...(snapshot.runningTurn != null\n ? {\n runningTurn: snapshot.runningTurn,\n unstable_resume: true as const,\n }\n : {}),\n };\n}\n\nexport function getTurnMessageContent(message: AppendMessage): string {\n const parts: string[] = [];\n for (const part of message.content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n }\n }\n const text = parts.join(\"\\n\").trim();\n if (!text) {\n throw new Error(\"User message must contain text content.\");\n }\n return text;\n}\n\n/**\n * Gateway `user.message` content (string for text-only, or text/file parts).\n * Derived from SDK `TurnInputItem` so it tracks API changes.\n */\nexport type UserMessageContent = Extract<\n TurnInputItem,\n { type: \"user.message\" }\n>[\"content\"];\n\ntype UserMessageContentItem = Exclude<UserMessageContent, string>[number];\ntype FileContent = Extract<UserMessageContentItem, { type: \"file\" }>;\ntype TextContent = Extract<UserMessageContentItem, { type: \"text\" }>;\n\nfunction toFileDataUri(data: string, mimeType: string): string {\n // FileContent expects a data URI (`data:<mime>;base64,<payload>`).\n // Attachment adapters typically already produce one via FileReader.readAsDataURL;\n // only wrap bare base64 payloads.\n if (data.startsWith(\"data:\")) {\n return data;\n }\n return `data:${mimeType};base64,${data}`;\n}\n\nfunction toFileContent(name: string, data: string, mimeType: string): FileContent {\n return {\n type: \"file\",\n name,\n data: toFileDataUri(data, mimeType),\n };\n}\n\n/**\n * Builds the gateway turn input content from a composer message, forwarding\n * attachments as SDK `FileContent` parts. Mirrors how assistant-ui surfaces\n * attachment content on `message.attachments[].content`.\n */\nexport function buildUserMessageContent(message: AppendMessage): UserMessageContent {\n const contentParts = message.content as readonly ThreadUserMessagePart[];\n const inputParts: (ThreadUserMessagePart & { filename?: string })[] = [\n ...contentParts,\n ...(message.attachments?.flatMap((attachment) =>\n attachment.content.map((part) => ({\n ...part,\n filename: attachment.name,\n })),\n ) ?? []),\n ];\n\n const items: UserMessageContentItem[] = [];\n for (const part of inputParts) {\n switch (part.type) {\n case \"text\":\n if (part.text.trim().length > 0) {\n const textPart: TextContent = { type: \"text\", text: part.text };\n items.push(textPart);\n }\n break;\n case \"image\":\n items.push(\n toFileContent(part.filename ?? \"image\", part.image, \"image/png\"),\n );\n break;\n case \"file\":\n items.push(\n toFileContent(\n part.filename ?? \"file\",\n part.data,\n part.mimeType,\n ),\n );\n break;\n default:\n break;\n }\n }\n\n const hasFile = items.some((item): item is FileContent => item.type === \"file\");\n if (!hasFile) {\n // Text-only: keep the string form and the non-empty invariant.\n return getTurnMessageContent(message);\n }\n return items;\n}\n\n/** Derives display text from gateway user-message content (drops file parts). */\nexport function userMessageContentToText(content: UserMessageContent): string {\n if (typeof content === \"string\") {\n return content;\n }\n return content\n .filter(\n (item): item is TextContent => item.type === \"text\",\n )\n .map((item) => item.text)\n .join(\"\\n\")\n .trim();\n}\n\n/** Strips the `-user` suffix from a projected user message id to recover the turn id. */\nexport function parseTurnIdFromMessageId(messageId: string): string {\n return messageId.replace(/-user$/, \"\");\n}\n\n/** Parent turn id for branching before `turnId`; `null` when editing the first turn. */\nexport function resolveBranchPreviousTurnId(\n turns: readonly SessionTurnRecord[],\n turnId: string,\n): string | null {\n const turnIndex = turns.findIndex((turn) => turn.id === turnId);\n if (turnIndex <= 0) {\n return null;\n }\n return turns[turnIndex - 1]!.id;\n}\n\n/** Extracts edited text from an assistant-ui append message (text parts only). */\nexport function extractEditedText(message: AppendMessage): string {\n return getTurnMessageContent(message);\n}\n\n/** Original gateway user-message content from a turn record (for reset). */\nexport function extractTurnUserMessageContent(\n input: TurnInputItem[] | undefined,\n): UserMessageContent {\n for (const item of input ?? []) {\n if (item.type === \"user.message\") {\n return item.content;\n }\n }\n return \"\";\n}\n\n/**\n * Builds resubmit content for a text-only edit: replaces text with `editedText`\n * while preserving original file parts from the turn record.\n */\nexport function buildEditedUserMessageContent(\n editedText: string,\n originalInput: TurnInputItem[] | undefined,\n): UserMessageContent {\n const fileParts: FileContent[] = [];\n for (const item of originalInput ?? []) {\n if (item.type !== \"user.message\") {\n continue;\n }\n const content = item.content;\n if (typeof content === \"string\") {\n continue;\n }\n for (const part of content) {\n if (part.type === \"file\") {\n fileParts.push(part);\n }\n }\n }\n\n if (fileParts.length === 0) {\n return editedText;\n }\n\n const items: UserMessageContentItem[] = [];\n if (editedText.trim().length > 0) {\n items.push({ type: \"text\", text: editedText });\n }\n items.push(...fileParts);\n return items;\n}\n\nfunction buildMcpAuthUpdate(\n pendingMcpAuth: McpAuthRequiredEvent,\n foldState: PeerThreadFoldState,\n groupRootBaseline?: readonly string[],\n): TurnStreamUpdate {\n const base =\n groupRootBaseline != null\n ? buildRootAssistantContentForIds(\n foldState,\n rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline),\n )\n : buildRootAssistantContent(foldState);\n return {\n content: [...base, ...buildMcpAuthTextParts(pendingMcpAuth.mcpServers)],\n status: mcpAuthAssistantStatus(),\n metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) },\n };\n}\n\nexport async function* streamTurnEvents(\n stream: AsyncIterable<TurnStreamData>,\n foldState: PeerThreadFoldState,\n groupRootBaseline?: readonly string[],\n onTurnIdAvailable?: (turnId: string) => void,\n): AsyncGenerator<TurnStreamUpdate> {\n let pendingMcpAuth: McpAuthRequiredEvent | undefined;\n let sandboxId: string | undefined;\n let sandboxIdYielded = false;\n\n const withSandbox = (update: TurnStreamUpdate): TurnStreamUpdate => {\n if (sandboxId == null) {\n return update;\n }\n sandboxIdYielded = true;\n return {\n ...update,\n metadata: { ...update.metadata, custom: { ...update.metadata?.custom, sandboxId } },\n };\n };\n\n const yieldContent = (): AssistantContentPart[] | undefined => {\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n const content = buildRootAssistantContentForIds(foldState, ids);\n return content.length > 0 ? content : undefined;\n };\n\n for await (const data of stream) {\n const event = data.event;\n\n if (event.type === \"turn.created\") {\n onTurnIdAvailable?.(event.turnId);\n continue;\n }\n\n if (event.type === \"sandbox.created\") {\n sandboxId = event.sandboxId;\n continue;\n }\n\n if (event.type === \"mcp.auth_required\") {\n pendingMcpAuth = event;\n continue;\n }\n\n if (event.type === \"turn.done\") {\n if (event.state.status === \"error\") {\n throw new Error(event.state.message);\n }\n // The turn is logically complete once `turn.done` is observed. The\n // resumed-turn transport (`subscribeToTurn`) is a reconnectable live\n // tail and is not guaranteed to close its SSE body right after this\n // event, so we must stop consuming explicitly rather than waiting\n // for the underlying stream to end — otherwise `isRunning` never\n // clears and the composer's cancel/spinner button gets stuck.\n break;\n }\n\n if (!ingestStreamEvent(foldState, event)) {\n continue;\n }\n\n const content = yieldContent();\n if (content != null) {\n yield withSandbox({ content });\n }\n }\n\n if (pendingMcpAuth != null) {\n yield withSandbox(buildMcpAuthUpdate(pendingMcpAuth, foldState, groupRootBaseline));\n return;\n }\n\n const approvalThreadId = findFirstPendingApprovalThreadId(foldState);\n const responseThreadId = findFirstPendingResponseThreadId(foldState);\n if (approvalThreadId != null || responseThreadId != null) {\n const custom: Record<string, unknown> = {};\n if (approvalThreadId != null) {\n Object.assign(\n custom,\n toolApprovalMessageCustom(\n approvalThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : approvalThreadId,\n ),\n );\n }\n if (responseThreadId != null) {\n Object.assign(\n custom,\n toolResponseMessageCustom(\n responseThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : responseThreadId,\n ),\n );\n }\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n yield withSandbox({\n content: buildRootAssistantContentForIds(foldState, ids),\n status:\n approvalThreadId != null ? toolApprovalStatus() : toolResponseStatus(),\n metadata: { custom },\n });\n return;\n }\n\n if (sandboxId != null && !sandboxIdYielded) {\n const ids =\n groupRootBaseline != null\n ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline)\n : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];\n yield withSandbox({ content: buildRootAssistantContentForIds(foldState, ids) });\n }\n}\n\nexport function turnStreamUpdateToAssistantMessage(\n turnId: string,\n update: TurnStreamUpdate,\n existing?: ThreadMessage,\n options?: ProjectSessionMessagesOptions,\n): ThreadMessage {\n const id =\n existing?.role === \"assistant\"\n ? existing.id\n : `${turnId}-assistant`;\n const fallbackCreatedAt = existing?.createdAt ?? new Date();\n return {\n id,\n role: \"assistant\",\n content: update.content,\n status: update.status ?? { type: \"running\" },\n createdAt: resolveCreatedAt(id, fallbackCreatedAt, options),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {\n ...(existing?.role === \"assistant\" ? existing.metadata.custom : {}),\n ...update.metadata?.custom,\n turnId,\n },\n },\n };\n}\n\nexport function repositoryItemsFromMessages(\n messages: readonly ThreadMessage[],\n): ExportedMessageRepositoryItem[] {\n const items: ExportedMessageRepositoryItem[] = [];\n let parentId: string | null = null;\n for (const message of messages) {\n items.push({ parentId, message });\n parentId = message.id;\n }\n return items;\n}\n\nexport type { SessionSnapshot, ProjectSessionMessagesOptions } from \"./sessionSnapshot.js\";\n","import type { AgentChatServer, AgentSpec } from \"../server/types.js\";\n\nexport const DRAFT_SESSION_LAST_UPDATED_AT_HEADER = \"x-tfy-session-last-updated-at\";\n\nexport type DraftSessionBridge = {\n syncAgentSpec: (draftSessionId: string, agentSpec: AgentSpec) => Promise<string>;\n getDraftAgentSpec: (draftSessionId: string) => Promise<AgentSpec>;\n};\n\nexport function createDraftSessionBridge(\n server: AgentChatServer,\n): DraftSessionBridge {\n return {\n async getDraftAgentSpec(draftSessionId) {\n const session = await server.getSession({ sessionId: draftSessionId });\n if (session.agentSpec == null) {\n throw new Error(\n `Session ${draftSessionId} has no agentSpec (isMutable=${session.isMutable}).`,\n );\n }\n return session.agentSpec;\n },\n\n async syncAgentSpec(draftSessionId, agentSpec) {\n const updated = await server.updateSession({\n sessionId: draftSessionId,\n agentSpec,\n });\n return updated.updatedAt;\n },\n };\n}\n","/** ISO timestamp one year before now — used as `listSessions` `startTimestamp`. */\nexport function sessionListStartTimestamp(): string {\n const start = new Date();\n start.setFullYear(start.getFullYear() - 1);\n return start.toISOString();\n}\n","import type { AgentSpec } from \"../server/types.js\";\n\n/** @deprecated Use Session with isMutable: true instead. Kept for title helper. */\nexport type DraftSession = {\n title?: string | null;\n agentSpec: AgentSpec;\n};\n\n/** Partial update — host fields flow through when `TSpec` is widened. */\nexport type AgentSpecUpdate<TSpec extends AgentSpec = AgentSpec> = {\n [K in keyof TSpec]?: K extends \"model\"\n ? Omit<Partial<TSpec[\"model\"]>, \"params\"> & {\n params?: Partial<NonNullable<TSpec[\"model\"][\"params\"]>>;\n }\n : TSpec[K];\n};\n\nexport function mergeAgentSpec<TSpec extends AgentSpec>(\n base: TSpec,\n update: AgentSpecUpdate<TSpec>,\n): TSpec {\n const { model: modelUpdate, ...rest } = update;\n\n const next = {\n ...base,\n ...rest,\n } as TSpec;\n\n if (modelUpdate != null) {\n next.model = {\n ...base.model,\n ...modelUpdate,\n name: modelUpdate.name ?? base.model.name,\n params:\n modelUpdate.params != null\n ? { ...base.model.params, ...modelUpdate.params }\n : base.model.params,\n } as TSpec[\"model\"];\n }\n\n return next;\n}\n\nexport function draftSessionTitle(draft: DraftSession): string {\n return draft.title ?? draft.agentSpec.model.name;\n}\n","import type { RemoteThreadMetadata } from \"@assistant-ui/core\";\n\nimport { draftSessionTitle } from \"./draft/agentSpec.js\";\nimport type { AgentSpec, Session } from \"./server/types.js\";\n\n/**\n * Title for a session row in a mixed (draft + named) thread list.\n * Mutable sessions use draftSessionTitle (optionally falling back to\n * `defaultAgentSpec`); named sessions use title → agentName → id.\n */\nexport function sessionDisplayTitle(\n session: Session,\n defaultAgentSpec?: AgentSpec,\n): string {\n if (session.isMutable) {\n const agentSpec = session.agentSpec ?? defaultAgentSpec;\n if (agentSpec != null) {\n return draftSessionTitle({\n title: session.title,\n agentSpec,\n });\n }\n }\n return session.title ?? session.agentName ?? session.id;\n}\n\n/** Map a Session DTO onto RemoteThreadMetadata (mutability + display name in custom). */\nexport function sessionToThreadMetadata(\n session: Session,\n title: string | undefined,\n): RemoteThreadMetadata {\n return {\n status: \"regular\",\n remoteId: session.id,\n title,\n lastMessageAt: new Date(session.updatedAt),\n custom: {\n isMutable: session.isMutable,\n ...(session.agentName != null ? { agentName: session.agentName } : {}),\n },\n };\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"../server/types.js\";\nimport type { AgentSpec } from \"../server/types.js\";\nimport { sessionListStartTimestamp } from \"../sessionListStartTimestamp.js\";\nimport {\n sessionDisplayTitle,\n sessionToThreadMetadata,\n} from \"../sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\nexport function createTrueFoundryDraftThreadListAdapter(options: {\n server: AgentChatServer;\n defaultAgentSpec: AgentSpec;\n getAgentSpec?: () => AgentSpec;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, defaultAgentSpec, getAgentSpec, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(\n session,\n sessionDisplayTitle(session, defaultAgentSpec),\n ),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize(_threadId: string) {\n const draft = await server.createSession({\n agentSpec: getAgentSpec?.() ?? defaultAgentSpec,\n });\n return { remoteId: draft.id, externalId: undefined };\n },\n\n async fetch(remoteId) {\n const draft = await server.getSession({ sessionId: remoteId });\n return sessionToThreadMetadata(\n draft,\n sessionDisplayTitle(draft, defaultAgentSpec),\n );\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","import { createRuntimeExtras } from \"@assistant-ui/core/internal\";\nimport type { McpAuthRequiredEvent } from \"./server/index.js\";\n\nimport type { AgentSpec } from \"./server/types.js\";\nimport type { AgentSpecUpdate } from \"./draft/agentSpec.js\";\nimport type { PendingApproval, PendingToolResponse } from \"./collectPending.js\";\nimport type { RespondToToolApprovalOptions } from \"./toolApproval.js\";\nimport type { RespondToToolResponseOptions } from \"./toolResponse.js\";\n\nexport type { PendingApproval, PendingToolResponse };\n\nexport type TrueFoundryDraftRuntimeExtras = {\n agentSpec: AgentSpec | null;\n draftSessionId: string | undefined;\n isSpecLoading: boolean;\n isSpecSyncing: boolean;\n specError: unknown | null;\n updateAgentSpec: (update: AgentSpecUpdate) => void;\n flushAgentSpec: () => Promise<void>;\n adoptAgentSpec: (request: {\n agentSpec: AgentSpec;\n updatedAt?: string;\n }) => void;\n};\n\nexport type TrueFoundryRuntimeExtras = {\n pendingApprovals: PendingApproval[];\n pendingToolResponses: PendingToolResponse[];\n pendingMcpAuth: { mcpServers: McpAuthRequiredEvent[\"mcpServers\"] } | null;\n resumeUnavailable: boolean;\n sandboxId: string | undefined;\n respondToToolApproval: (response: RespondToToolApprovalOptions) => void;\n respondToToolResponse: (response: RespondToToolResponseOptions) => void;\n resumeMcpAuth: () => Promise<void>;\n downloadSandboxFile: (req: { turnId: string; path: string }) => Promise<Blob>;\n cancel: () => Promise<void>;\n resetFromTurn: (turnId: string) => Promise<void>;\n reload: () => void;\n hasOlderHistory: boolean;\n isLoadingOlderHistory: boolean;\n loadOlderHistory: () => Promise<void>;\n draft: TrueFoundryDraftRuntimeExtras | null;\n};\n\nexport const trueFoundryExtras = createRuntimeExtras<TrueFoundryRuntimeExtras>(\n \"useTrueFoundryAgentRuntime\",\n);\n\nexport const EMPTY_DRAFT_EXTRAS: TrueFoundryDraftRuntimeExtras = {\n agentSpec: null,\n draftSessionId: undefined,\n isSpecLoading: false,\n isSpecSyncing: false,\n specError: null,\n updateAgentSpec: () => {\n throw new Error(\"Draft agent extras are only available in draft mode.\");\n },\n flushAgentSpec: async () => {\n throw new Error(\"Draft agent extras are only available in draft mode.\");\n },\n adoptAgentSpec: () => {\n throw new Error(\"Draft agent extras are only available in draft mode.\");\n },\n};\n","import type { AgentChatServer, Session } from \"./server/types.js\";\n\nconst inflightBySessionId = new Map<string, Promise<Session>>();\n\n/** `sessionId` is the assistant-ui thread `remoteId` from `RemoteThreadListAdapter.initialize`. */\nexport function getSession(\n server: AgentChatServer,\n sessionId: string,\n): Promise<Session> {\n let inflight = inflightBySessionId.get(sessionId);\n if (inflight == null) {\n inflight = server.getSession({ sessionId }).finally(() => {\n if (inflightBySessionId.get(sessionId) === inflight) {\n inflightBySessionId.delete(sessionId);\n }\n });\n inflightBySessionId.set(sessionId, inflight);\n }\n return inflight;\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"./server/types.js\";\nimport { getSession } from \"./sessions.js\";\nimport { sessionListStartTimestamp } from \"./sessionListStartTimestamp.js\";\nimport { sessionToThreadMetadata } from \"./sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\nexport function createTrueFoundryThreadListAdapter(options: {\n server: AgentChatServer;\n agentName: string;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, agentName, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(session, session.title ?? undefined),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize(_threadId: string) {\n const session = await server.createSession({ agentName });\n return { remoteId: session.id, externalId: undefined };\n },\n\n async fetch(remoteId) {\n const session = await getSession(server, remoteId);\n return sessionToThreadMetadata(session, session.title ?? undefined);\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","import type {\n AttachmentAdapter,\n DictationAdapter,\n ExternalStoreSharedOptions,\n FeedbackAdapter,\n RealtimeVoiceAdapter,\n SpeechSynthesisAdapter,\n} from \"@assistant-ui/core\";\n\nimport type { AgentChatServer, AgentSpec } from \"./server/types.js\";\n\nexport type NamedAgentConfig = {\n mode: \"named\";\n agentName: string;\n};\n\nexport type DraftAgentConfig = {\n mode: \"draft\";\n defaultAgentSpec: AgentSpec;\n onAgentSpecChange?: ((spec: AgentSpec) => void) | undefined;\n};\n\nexport type TrueFoundryAgentConfig = NamedAgentConfig | DraftAgentConfig;\n\ntype TrueFoundryAgentRuntimeBaseOptions = ExternalStoreSharedOptions & {\n server: AgentChatServer;\n initialSessionId?: string | undefined;\n threadId?: string | undefined;\n onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;\n onError?: ((error: unknown) => void) | undefined;\n listEventsConcurrency?: number | undefined;\n /**\n * Optional filter forwarded to `listSessions({ agentId })`.\n * Omit for all chats; hosts that key agents by name pass that name as the id.\n */\n listSessionsAgentId?: string | undefined;\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n speech?: SpeechSynthesisAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n }\n | undefined;\n};\n\nexport type UseTrueFoundryAgentRuntimeOptions = TrueFoundryAgentRuntimeBaseOptions & {\n /** Discriminated agent source. Omit when using legacy `agentName`. */\n agent?: TrueFoundryAgentConfig | undefined;\n /** Legacy named-agent shorthand. Prefer `agent: { mode: \"named\", agentName }`. */\n agentName?: string | undefined;\n};\n\nexport type ResolvedTrueFoundryAgentRuntimeOptions = TrueFoundryAgentRuntimeBaseOptions & {\n agent: TrueFoundryAgentConfig;\n};\n\nexport function resolveTrueFoundryAgentConfig(\n options: Pick<UseTrueFoundryAgentRuntimeOptions, \"agent\" | \"agentName\">,\n): TrueFoundryAgentConfig {\n if (options.agent != null) {\n if (options.agent.mode === \"named\" && options.agentName != null) {\n return { mode: \"named\", agentName: options.agentName };\n }\n return options.agent;\n }\n if (options.agentName != null) {\n return { mode: \"named\", agentName: options.agentName };\n }\n throw new Error(\n \"useTrueFoundryAgentRuntime requires `agent` or legacy `agentName`.\",\n );\n}\n\nexport function resolveTrueFoundryAgentRuntimeOptions(\n options: UseTrueFoundryAgentRuntimeOptions,\n): ResolvedTrueFoundryAgentRuntimeOptions {\n const agent = resolveTrueFoundryAgentConfig(options);\n\n return {\n ...options,\n agent,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { AgentSpec } from \"../server/types.js\";\nimport { mergeAgentSpec, type AgentSpecUpdate } from \"./agentSpec.js\";\nimport type { DraftSessionBridge } from \"./draftSessionBridge.js\";\n\nconst SPEC_SYNC_DEBOUNCE_MS = 400;\n\nexport type UseDraftAgentSpecOptions = {\n draftSessionId: string | undefined;\n draftBridge: DraftSessionBridge | null;\n defaultAgentSpec: AgentSpec;\n onAgentSpecChange?: ((spec: AgentSpec) => void) | undefined;\n onError?: ((error: unknown) => void) | undefined;\n};\n\nexport type UseDraftAgentSpecResult = {\n agentSpec: AgentSpec | null;\n draftSessionId: string | undefined;\n isSpecLoading: boolean;\n isSpecSyncing: boolean;\n specError: unknown | null;\n updateAgentSpec: (update: AgentSpecUpdate) => void;\n flushAgentSpec: () => Promise<void>;\n adoptAgentSpec: (request: {\n agentSpec: AgentSpec;\n updatedAt?: string;\n }) => void;\n takeTurnHeaderTimestamp: () => Promise<string | undefined>;\n};\n\nexport function useDraftAgentSpec({\n draftSessionId,\n draftBridge,\n defaultAgentSpec,\n onAgentSpecChange,\n onError,\n}: UseDraftAgentSpecOptions): UseDraftAgentSpecResult {\n const enabled = draftBridge != null;\n const [agentSpec, setAgentSpec] = useState<AgentSpec>(defaultAgentSpec);\n const [isSpecLoading, setIsSpecLoading] = useState(false);\n const [isSpecSyncing, setIsSpecSyncing] = useState(false);\n const [specError, setSpecError] = useState<unknown | null>(null);\n\n const agentSpecRef = useRef(agentSpec);\n agentSpecRef.current = agentSpec;\n\n const syncTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const syncGenerationRef = useRef(0);\n const loadedDraftIdRef = useRef<string | undefined>(undefined);\n const localDirtyRef = useRef(false);\n const lastUpdatedAtRef = useRef<string | undefined>(undefined);\n const pendingFlushRef = useRef<(() => Promise<void>) | undefined>(undefined);\n const inFlightFlushRef = useRef<Promise<void> | undefined>(undefined);\n const activeDraftIdRef = useRef(draftSessionId);\n\n // Invalidate sync state from the previous draft so a stale pending flush or\n // stored updatedAt can't update the wrong draft or leak into the next\n // turn's header. Bumping the generation makes any in-flight sync a no-op.\n useEffect(() => {\n const previousDraftId = activeDraftIdRef.current;\n if (previousDraftId === draftSessionId) {\n return;\n }\n activeDraftIdRef.current = draftSessionId;\n syncGenerationRef.current++;\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n syncTimeoutRef.current = undefined;\n }\n pendingFlushRef.current = undefined;\n inFlightFlushRef.current = undefined;\n lastUpdatedAtRef.current = undefined;\n setIsSpecSyncing(false);\n // Dirty edits made against a previous draft must not be replayed onto\n // the new one. Keep them only for lazy creation (undefined -> id).\n if (previousDraftId != null) {\n localDirtyRef.current = false;\n }\n }, [draftSessionId]);\n\n useEffect(() => {\n if (!enabled || draftBridge == null) {\n return;\n }\n if (draftSessionId == null) {\n loadedDraftIdRef.current = undefined;\n setAgentSpec(defaultAgentSpec);\n localDirtyRef.current = false;\n setSpecError(null);\n setIsSpecLoading(false);\n return;\n }\n\n if (loadedDraftIdRef.current === draftSessionId) {\n return;\n }\n\n let cancelled = false;\n setIsSpecLoading(true);\n void (async () => {\n try {\n const loaded = await draftBridge.getDraftAgentSpec(draftSessionId);\n if (cancelled) {\n return;\n }\n loadedDraftIdRef.current = draftSessionId;\n\n if (localDirtyRef.current) {\n scheduleSpecSyncRef.current?.(draftSessionId, agentSpecRef.current);\n localDirtyRef.current = false;\n setSpecError(null);\n setIsSpecLoading(false);\n return;\n }\n\n setAgentSpec(loaded);\n setSpecError(null);\n setIsSpecLoading(false);\n } catch (error) {\n if (!cancelled) {\n onError?.(error);\n setSpecError(error);\n setIsSpecLoading(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n // The cancelled load can no longer clear the flag itself. Releasing it\n // here keeps it from sticking when the next run early-returns on an\n // already-loaded draft; a run that starts a fresh load re-raises it in\n // the same commit.\n setIsSpecLoading(false);\n };\n }, [defaultAgentSpec, draftBridge, draftSessionId, enabled, onError]);\n\n const flushSpecSync = useCallback(\n async (draftId: string, spec: AgentSpec, generation: number) => {\n if (draftBridge == null) {\n return;\n }\n setIsSpecSyncing(true);\n try {\n const updatedAt = await draftBridge.syncAgentSpec(draftId, spec);\n if (generation !== syncGenerationRef.current) {\n return;\n }\n lastUpdatedAtRef.current =\n updatedAt || new Date().toISOString();\n setSpecError(null);\n onAgentSpecChange?.(spec);\n } catch (error) {\n if (generation === syncGenerationRef.current) {\n setSpecError(error);\n onError?.(error);\n }\n } finally {\n if (generation === syncGenerationRef.current) {\n setIsSpecSyncing(false);\n }\n }\n },\n [draftBridge, onAgentSpecChange, onError],\n );\n\n const scheduleSpecSync = useCallback(\n (draftId: string, spec: AgentSpec) => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n }\n const generation = ++syncGenerationRef.current;\n const flush = () => {\n pendingFlushRef.current = undefined;\n syncTimeoutRef.current = undefined;\n const promise = flushSpecSync(draftId, spec, generation).finally(() => {\n if (inFlightFlushRef.current === promise) {\n inFlightFlushRef.current = undefined;\n }\n });\n inFlightFlushRef.current = promise;\n return promise;\n };\n pendingFlushRef.current = flush;\n syncTimeoutRef.current = setTimeout(() => {\n void flush();\n }, SPEC_SYNC_DEBOUNCE_MS);\n },\n [flushSpecSync],\n );\n\n const scheduleSpecSyncRef = useRef(scheduleSpecSync);\n scheduleSpecSyncRef.current = scheduleSpecSync;\n\n const flushPendingSpecSyncNow = useCallback(async () => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n syncTimeoutRef.current = undefined;\n }\n const pending = pendingFlushRef.current;\n if (pending != null) {\n pendingFlushRef.current = undefined;\n await pending();\n return;\n }\n if (inFlightFlushRef.current != null) {\n await inFlightFlushRef.current;\n }\n }, []);\n\n const adoptAgentSpec = useCallback(\n ({\n agentSpec: persistedSpec,\n updatedAt,\n }: {\n agentSpec: AgentSpec;\n updatedAt?: string;\n }) => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n syncTimeoutRef.current = undefined;\n }\n syncGenerationRef.current++;\n pendingFlushRef.current = undefined;\n inFlightFlushRef.current = undefined;\n localDirtyRef.current = false;\n // Keep the last successful sync timestamp when the caller omits\n // updatedAt (e.g. a save that did not return sessionUpdatedAt).\n if (updatedAt !== undefined) {\n lastUpdatedAtRef.current = updatedAt;\n }\n agentSpecRef.current = persistedSpec;\n setAgentSpec(persistedSpec);\n setSpecError(null);\n setIsSpecSyncing(false);\n },\n [],\n );\n\n const takeTurnHeaderTimestamp = useCallback(async () => {\n await flushPendingSpecSyncNow();\n const updatedAt = lastUpdatedAtRef.current;\n lastUpdatedAtRef.current = undefined;\n return updatedAt;\n }, [flushPendingSpecSyncNow]);\n\n useEffect(\n () => () => {\n if (syncTimeoutRef.current != null) {\n clearTimeout(syncTimeoutRef.current);\n }\n },\n [],\n );\n\n const updateAgentSpec = useCallback(\n (update: AgentSpecUpdate) => {\n if (!enabled || draftBridge == null) {\n return;\n }\n const next = mergeAgentSpec(agentSpecRef.current, update);\n setAgentSpec(next);\n localDirtyRef.current = true;\n if (draftSessionId != null) {\n scheduleSpecSync(draftSessionId, next);\n }\n },\n [draftBridge, draftSessionId, enabled, scheduleSpecSync],\n );\n\n return useMemo(\n () => ({\n agentSpec: enabled ? agentSpec : null,\n draftSessionId: enabled ? draftSessionId : undefined,\n isSpecLoading: enabled ? isSpecLoading : false,\n isSpecSyncing: enabled ? isSpecSyncing : false,\n specError: enabled ? specError : null,\n updateAgentSpec,\n flushAgentSpec: flushPendingSpecSyncNow,\n adoptAgentSpec,\n takeTurnHeaderTimestamp,\n }),\n [\n agentSpec,\n draftSessionId,\n enabled,\n isSpecLoading,\n isSpecSyncing,\n specError,\n flushPendingSpecSyncNow,\n adoptAgentSpec,\n takeTurnHeaderTimestamp,\n updateAgentSpec,\n ],\n );\n}\n","\"use client\";\n\nimport { generateId } from \"@assistant-ui/core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n McpAuthRequiredEvent,\n ToolApprovalRequiredEvent,\n ToolResponseRequiredEvent,\n Turn,\n TurnInputItem,\n TurnStateDone,\n} from \"./server/index.js\";\nimport type { AgentChatServer } from \"./server/types.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n buildEditedUserMessageContent,\n buildSnapshotBeforeTurn,\n computeGroupRootBaseline,\n extractTurnUserMessageContent,\n prependOlderSessionHistory,\n projectSessionMessages,\n resolveGatewayBranchPreviousTurnIdForTurn,\n rootModelMessageIdsSinceBaseline,\n userMessageContentToText,\n type UserMessageContent,\n} from \"./convertTurnMessages.js\";\nimport { extractTurnUserText } from \"./extractTurnUserText.js\";\nimport { loadSessionSnapshot } from \"./loadSessionSnapshot.js\";\nimport { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from \"./mcpAuth.js\";\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n collectRequiredActionInputs,\n findPausedAssistantMessage,\n messageHasPendingRequiredActions,\n type RequiredActionInput,\n} from \"./requiredActionInputs.js\";\nimport {\n createEmptySessionSnapshot,\n replaceSessionSnapshot,\n type SessionSnapshot,\n type SessionTurnRecord,\n} from \"./sessionSnapshot.js\";\nimport { resumeTurnStream, streamTurnContent } from \"./streamTurn.js\";\nimport {\n TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY,\n type RespondToToolApprovalOptions,\n} from \"./toolApproval.js\";\nimport {\n applyUserToolResponsesToFold,\n TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,\n type RespondToToolResponseOptions,\n} from \"./toolResponse.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport type UseTrueFoundryAgentMessagesOptions = {\n server: AgentChatServer;\n sessionId: string | undefined;\n /** When true the thread is the currently selected (main) thread. */\n isMain?: boolean | undefined;\n /** URL-selected session may load before the thread list marks it as main. */\n isInitialSession?: boolean | undefined;\n listEventsConcurrency?: number | undefined;\n onError?: ((error: unknown) => void) | undefined;\n initializeSession?: () => Promise<{\n remoteId: string;\n externalId: string | undefined;\n }>;\n /** Maps a thread `remoteId` to the gateway session id used for turns. */\n resolveConversationSessionId?: (remoteId: string) => Promise<string>;\n /**\n * Optional per-turn headers for createTurn. Invoked once per `sendTurn` after\n * the session is resolved; return value is forwarded to `turn.execute`.\n */\n getTurnHeaders?: () => Promise<Record<string, string> | undefined>;\n};\n\nexport type SendTurnOptions =\n | {\n userMessage: UserMessageContent;\n previousTurnId?: string | null;\n /** Invoked only when the user turn fails before the gateway registers it. */\n onPreTurnFailure?: () => void;\n /**\n * When branching (edit/reset), the already-rewound history to send from.\n * Applied atomically with `pendingUser` so a stale React snapshot cannot\n * keep pre-branch turns while the new user message is appended.\n */\n branchFromSnapshot?: SessionSnapshot;\n /** Original history restored when a branch fails before turn.created. */\n branchRollbackSnapshot?: SessionSnapshot;\n }\n | { inputs: RequiredActionInput[] }\n | { resumeMcpAuth: true };\n\nfunction buildCompletedTurnState(\n completedAt: string,\n requiredActions: TurnStateDone[\"requiredActions\"] = [],\n): TurnStateDone {\n return {\n status: \"done\",\n requiredActions,\n completedAt,\n };\n}\n\n/**\n * Reconstructs the pending required actions a paused in-flight update carried,\n * so the pause survives `commitActiveStream`'s synthetic \"done\" state.\n *\n * `commitActiveStream` fabricates a `TurnStateDone` for the just-finished\n * stream, and the projection derives an assistant message's `requires-action`\n * status from `turn.state.requiredActions` (see `findApprovalRequiredInTurn` /\n * `findResponseRequiredInTurn` / `findMcpAuthRequired`). If we returned an empty\n * list here, the committed turn would look \"complete\", the projected message\n * would lose its `requires-action` status, and `findPausedAssistantMessage`\n * (used by `trySendCollectedRequiredActions`) would never see it — so answering\n * a tool approval or an `ask_user_question` would never send the resume turn.\n *\n * The paused update already carries the pause state: `status` is\n * `requires-action` and `metadata.custom` holds the pending thread id(s) (and,\n * for MCP, the server list). Only the thread id is read downstream, so an empty\n * `toolCalls` list is sufficient here — the resume inputs are collected from the\n * message content, not from these reconstructed actions.\n */\nexport function requiredActionsFromActiveUpdate(\n update: TurnStreamUpdate,\n): TurnStateDone[\"requiredActions\"] {\n const custom = update.metadata?.custom as TrueFoundryMessageCustomMetadata | undefined;\n const requiredActions: TurnStateDone[\"requiredActions\"] = [];\n const createdAt = new Date().toISOString();\n\n if (custom?.pendingMcpAuth === true && Array.isArray(custom.mcpServers)) {\n const mcpAuthRequired: McpAuthRequiredEvent = {\n type: \"mcp.auth_required\",\n id: generateId(),\n createdAt,\n mcpServers: custom.mcpServers,\n };\n requiredActions.push(mcpAuthRequired);\n }\n\n if (update.status?.type === \"requires-action\") {\n const approvalThreadId = custom?.[TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY];\n if (typeof approvalThreadId === \"string\") {\n const approvalRequired: ToolApprovalRequiredEvent = {\n type: \"tool.approval_required\",\n id: generateId(),\n createdAt,\n threadId: approvalThreadId,\n toolCalls: [],\n };\n requiredActions.push(approvalRequired);\n }\n\n const responseThreadId = custom?.[TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY];\n if (typeof responseThreadId === \"string\") {\n const responseRequired: ToolResponseRequiredEvent = {\n type: \"tool.response_required\",\n id: generateId(),\n createdAt,\n threadId: responseThreadId,\n toolCalls: [],\n };\n requiredActions.push(responseRequired);\n }\n }\n\n return requiredActions;\n}\n\nfunction buildUserTurnInput(content: UserMessageContent): TurnInputItem {\n return { type: \"user.message\", content };\n}\n\nfunction appendTurnInputs(\n base: TurnInputItem[],\n continuationInputs?: RequiredActionInput[],\n): TurnInputItem[] {\n if (continuationInputs == null || continuationInputs.length === 0) {\n return base;\n }\n return [...base, ...continuationInputs];\n}\n\nfunction commitActiveStream(\n snapshot: SessionSnapshot,\n continuationInputs?: RequiredActionInput[],\n): SessionSnapshot {\n const active = snapshot.activeStream;\n if (active == null || active.streamComplete !== true) {\n return snapshot;\n }\n\n const activeSandboxId = (\n active.update.metadata?.custom as { sandboxId?: string } | undefined\n )?.sandboxId;\n\n const completedState = buildCompletedTurnState(\n new Date().toISOString(),\n requiredActionsFromActiveUpdate(active.update),\n );\n const baseline =\n snapshot.groupRootBaseline ?? computeGroupRootBaseline(snapshot.turns);\n const rootModelMessageIds = rootModelMessageIdsSinceBaseline(\n snapshot.fold,\n baseline,\n );\n\n const lastTurn = snapshot.turns.at(-1);\n if (lastTurn?.id === active.turnId) {\n return replaceSessionSnapshot(snapshot, {\n turns: snapshot.turns.map((turn) =>\n turn.id === active.turnId\n ? {\n ...turn,\n state: completedState,\n input: appendTurnInputs(turn.input ?? [], continuationInputs),\n ...(rootModelMessageIds != null\n ? { rootModelMessageIds }\n : {}),\n ...(activeSandboxId != null ? { sandboxId: activeSandboxId } : {}),\n }\n : turn,\n ),\n pendingUser: undefined,\n activeStream: undefined,\n });\n }\n\n const record: SessionTurnRecord = {\n id: active.turnId,\n createdAt:\n snapshot.pendingUser?.createdAt.toISOString() ?? new Date().toISOString(),\n state: completedState,\n input: appendTurnInputs(\n snapshot.pendingUser\n ? [buildUserTurnInput(snapshot.pendingUser.content)]\n : [],\n continuationInputs,\n ),\n ...(snapshot.pendingUser != null\n ? { userText: userMessageContentToText(snapshot.pendingUser.content) }\n : {}),\n ...(rootModelMessageIds != null ? { rootModelMessageIds } : {}),\n ...(activeSandboxId != null ? { sandboxId: activeSandboxId } : {}),\n };\n\n return replaceSessionSnapshot(snapshot, {\n turns: [...snapshot.turns, record],\n pendingUser: undefined,\n activeStream: undefined,\n });\n}\n\nasync function resolveActiveSessionId(\n remoteId: string,\n resolveConversationSessionId?: (remoteId: string) => Promise<string>,\n): Promise<string> {\n if (resolveConversationSessionId != null) {\n return resolveConversationSessionId(remoteId);\n }\n return remoteId;\n}\n\nfunction findTurnIndex(snapshot: SessionSnapshot, turnId: string): number {\n const committedIndex = snapshot.turns.findIndex((turn) => turn.id === turnId);\n if (committedIndex !== -1) {\n return committedIndex;\n }\n if (snapshot.pendingUser?.turnId === turnId) {\n return snapshot.turns.length;\n }\n throw new Error(`Turn ${turnId} not found in session snapshot`);\n}\n\nfunction resolveTurnInput(\n snapshot: SessionSnapshot,\n turnId: string,\n): TurnInputItem[] | undefined {\n const turnRecord = snapshot.turns.find((turn) => turn.id === turnId);\n if (turnRecord?.input != null) {\n return turnRecord.input;\n }\n if (snapshot.pendingUser?.turnId === turnId) {\n return [{ type: \"user.message\", content: snapshot.pendingUser.content }];\n }\n return undefined;\n}\n\nexport function useTrueFoundryAgentMessages({\n server,\n sessionId,\n isMain,\n isInitialSession,\n listEventsConcurrency,\n onError,\n initializeSession,\n resolveConversationSessionId,\n getTurnHeaders,\n}: UseTrueFoundryAgentMessagesOptions) {\n const [snapshot, setSnapshot] = useState<SessionSnapshot>(createEmptySessionSnapshot);\n const [isRunning, setIsRunning] = useState(false);\n // Existing sessions have history pending from the first render. Starting at\n // false causes consumers to briefly render an empty thread before the load\n // effect runs and flips this flag to true.\n const [isLoading, setIsLoading] = useState(\n sessionId != null && (isMain !== false || isInitialSession === true),\n );\n const [isLoadingOlderHistory, setIsLoadingOlderHistory] = useState(false);\n const [loadRetryTrigger, setLoadRetryTrigger] = useState(0);\n const [resumeUnavailable, setResumeUnavailable] = useState(false);\n\n const snapshotRef = useRef(snapshot);\n snapshotRef.current = snapshot;\n const loadOlderInflightRef = useRef<Promise<void> | null>(null);\n\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const resolveConversationSessionIdRef = useRef(resolveConversationSessionId);\n resolveConversationSessionIdRef.current = resolveConversationSessionId;\n const initializeSessionRef = useRef(initializeSession);\n initializeSessionRef.current = initializeSession;\n const getTurnHeadersRef = useRef(getTurnHeaders);\n getTurnHeadersRef.current = getTurnHeaders;\n\n const createdAtByMessageIdRef = useRef(new Map<string, Date>());\n const abortControllerRef = useRef<AbortController | null>(null);\n const activeRunRef = useRef<Promise<void> | null>(null);\n // Mirrors `resumeUnavailable` for `cancel`, which reads it outside render.\n const resumeUnavailableRef = useRef(false);\n const runningTurnRef = useRef<Turn | undefined>(undefined);\n const loadGenerationRef = useRef(0);\n const streamGenerationRef = useRef(0);\n const lazilyCreatedSessionIdRef = useRef<string | undefined>(undefined);\n const initialLoadStartedForRef = useRef<string | undefined>(undefined);\n const skipInitialPromotionLoadForRef = useRef<string | undefined>(undefined);\n\n /**\n * A turn is running that this server cannot stream. Nothing will deliver its\n * result to this client, so the UI shows a waiting state until the run is\n * cancelled or the session is reloaded.\n */\n const markResumeUnavailable = useCallback((value: boolean) => {\n resumeUnavailableRef.current = value;\n setResumeUnavailable(value);\n }, []);\n\n const projectOptions = useMemo(\n () => ({\n getCreatedAt: (messageId: string, fallback: Date) => {\n const cache = createdAtByMessageIdRef.current;\n const existing = cache.get(messageId);\n if (existing != null) {\n return existing;\n }\n cache.set(messageId, fallback);\n return fallback;\n },\n }),\n [],\n );\n\n const messages = useMemo(\n () => projectSessionMessages(snapshot, projectOptions),\n [snapshot, projectOptions],\n );\n\n const runStream = useCallback(\n (\n createStream: (signal: AbortSignal) => AsyncGenerator<TurnStreamUpdate>,\n /**\n * A mutable ref whose `.current` is the turn ID to use for\n * `activeStream.turnId`. Callers that capture the gateway turn ID\n * via `onTurnIdAvailable` update this ref in-place so that both the\n * pending-update flush and `commitActiveStream` always see the real\n * gateway ID rather than the locally-generated optimistic one.\n */\n turnIdRef: { current: string },\n isContinuation: boolean,\n ): Promise<void> => {\n const streamGeneration = ++streamGenerationRef.current;\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n setIsRunning(true);\n // This stream's `finally` owns the running flag from here on.\n markResumeUnavailable(false);\n\n const run = (async () => {\n // Sub-agent turns can emit 100+ stream events per frame. Coalesce to one\n // setSnapshot per animation frame so assistant-ui does not remount the whole\n // message tree (UI hang). The buffer belongs to this stream only.\n let pendingStreamUpdate: {\n update: TurnStreamUpdate;\n isContinuation: boolean;\n } | null = null;\n let streamUpdateRaf: number | null = null;\n\n const flushPendingStreamUpdate = () => {\n streamUpdateRaf = null;\n const pending = pendingStreamUpdate;\n pendingStreamUpdate = null;\n if (\n pending == null ||\n streamGeneration !== streamGenerationRef.current\n ) {\n return;\n }\n const { update, isContinuation: pendingIsContinuation } = pending;\n setSnapshot((prev) =>\n replaceSessionSnapshot(prev, {\n activeStream: {\n // Read from the ref so we always use the latest ID,\n // including any gateway ID that arrived after the RAf\n // was scheduled.\n turnId: turnIdRef.current,\n update,\n isContinuation: pendingIsContinuation,\n },\n }),\n );\n };\n\n const applyStreamUpdate = (update: TurnStreamUpdate) => {\n pendingStreamUpdate = { update, isContinuation };\n if (streamUpdateRaf == null) {\n streamUpdateRaf = requestAnimationFrame(flushPendingStreamUpdate);\n }\n };\n\n try {\n for await (const update of createStream(abortController.signal)) {\n if (abortController.signal.aborted) {\n return;\n }\n applyStreamUpdate(update);\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n onErrorRef.current?.(error);\n throw error;\n } finally {\n if (streamUpdateRaf != null) {\n cancelAnimationFrame(streamUpdateRaf);\n streamUpdateRaf = null;\n }\n if (streamGeneration !== streamGenerationRef.current) {\n return;\n }\n flushPendingStreamUpdate();\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsRunning(false);\n setSnapshot((prev) => {\n if (prev.activeStream == null) {\n return prev;\n }\n const marked = replaceSessionSnapshot(prev, {\n activeStream: {\n ...prev.activeStream,\n streamComplete: true,\n },\n requiredActions: {\n approvals: new Map(),\n toolResponses: new Map(),\n },\n });\n return commitActiveStream(marked);\n });\n }\n })();\n\n activeRunRef.current = run;\n void run\n .catch(() => undefined)\n .finally(() => {\n if (activeRunRef.current === run) {\n activeRunRef.current = null;\n }\n });\n return run;\n },\n [onError],\n );\n\n const load = useCallback(async () => {\n // Reading the retry counter intentionally makes retryLoad recreate this callback.\n void loadRetryTrigger;\n if (sessionId == null) {\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(createEmptySessionSnapshot());\n return;\n }\n\n // Allow the URL-selected session one early load before assistant-ui marks\n // it main. Suppress only that first promotion; later selections still reload.\n const isEarlyInitialLoad =\n isMain === false &&\n isInitialSession === true &&\n initialLoadStartedForRef.current !== sessionId;\n if (isMain === false) {\n if (!isEarlyInitialLoad) return;\n initialLoadStartedForRef.current = sessionId;\n skipInitialPromotionLoadForRef.current = sessionId;\n } else if (\n isMain === true &&\n skipInitialPromotionLoadForRef.current === sessionId\n ) {\n skipInitialPromotionLoadForRef.current = undefined;\n return;\n }\n if (isInitialSession === true) {\n initialLoadStartedForRef.current = sessionId;\n }\n\n // When we are loading a *different* session the user has navigated away\n // from the lazily-created one — clear the guard so navigating back to it\n // later triggers a proper reload instead of silently skipping.\n if (lazilyCreatedSessionIdRef.current != null && sessionId !== lazilyCreatedSessionIdRef.current) {\n lazilyCreatedSessionIdRef.current = undefined;\n }\n\n if (sessionId === lazilyCreatedSessionIdRef.current) {\n return;\n }\n\n const generation = ++loadGenerationRef.current;\n ++streamGenerationRef.current;\n setIsRunning(false);\n markResumeUnavailable(false);\n abortControllerRef.current?.abort();\n loadOlderInflightRef.current = null;\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(createEmptySessionSnapshot());\n setIsLoading(true);\n setIsLoadingOlderHistory(false);\n\n try {\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n const loadedSnapshot = await loadSessionSnapshot(\n server,\n conversationSessionId,\n (snap) => {\n if (generation === loadGenerationRef.current) {\n setSnapshot(snap);\n }\n },\n );\n if (generation !== loadGenerationRef.current) {\n return;\n }\n\n createdAtByMessageIdRef.current = new Map();\n setSnapshot(loadedSnapshot);\n runningTurnRef.current = loadedSnapshot.runningTurn;\n\n // History (and any seeded pendingUser for the in-flight turn) is\n // ready — clear loading before resuming. Awaiting the subscribe\n // stream here previously kept isLoading true for the entire\n // backend run, so reconnect UIs stayed on shimmers even though\n // subscribe was already live.\n setIsLoading(false);\n\n if (loadedSnapshot.runningTurn != null) {\n const turn = loadedSnapshot.runningTurn;\n\n // subscribeToTurn is optional, so a server can leave us without\n // a reconnect path. The turn still runs on the backend: show the\n // loaded history as running and let the host explain the gap.\n if (server.subscribeToTurn == null) {\n setIsRunning(true);\n markResumeUnavailable(true);\n return;\n }\n\n const isContinuation = !extractTurnUserText(turn.input);\n // TODO: pass afterSequenceNumber once stream ingestion tracks sequence numbers.\n // Use loadedSnapshot directly — snapshotRef.current still points at\n // the empty snapshot cleared above until the setSnapshot(loadedSnapshot)\n // call re-renders.\n void runStream(\n (signal) =>\n resumeTurnStream(\n server,\n conversationSessionId,\n turn.id,\n loadedSnapshot.fold,\n signal,\n undefined,\n loadedSnapshot.groupRootBaseline,\n ),\n { current: turn.id },\n isContinuation,\n ).catch(() => undefined);\n }\n } catch (error) {\n if (generation === loadGenerationRef.current) {\n if (isEarlyInitialLoad) {\n // Allow retryLoad while still backgrounded (before isMain promotion).\n initialLoadStartedForRef.current = undefined;\n skipInitialPromotionLoadForRef.current = undefined;\n }\n onErrorRef.current?.(error);\n }\n throw error;\n } finally {\n if (generation === loadGenerationRef.current) {\n setIsLoading(false);\n }\n }\n }, [\n server,\n runStream,\n sessionId,\n loadRetryTrigger,\n isMain,\n isInitialSession,\n ]);\n\n useEffect(() => {\n void load().catch(() => undefined);\n }, [load]);\n\n const sendTurn = useCallback(\n async (options: SendTurnOptions) => {\n // A turn.created event means the gateway registered the user message.\n // Errors after that point must keep the message in chat.\n let gatewayTurnAccepted = false;\n let pendingUserWasSet = false;\n let runStreamStarted = false;\n let pendingUserTurnId: string | undefined;\n\n try {\n let activeSessionId = sessionId;\n if (activeSessionId == null) {\n if (initializeSessionRef.current == null) {\n throw new Error(\"Cannot send a turn without an active session.\");\n }\n const { remoteId } = await initializeSessionRef.current();\n activeSessionId = remoteId;\n lazilyCreatedSessionIdRef.current = remoteId;\n }\n\n const conversationSessionId = await resolveActiveSessionId(\n activeSessionId,\n resolveConversationSessionIdRef.current,\n );\n const turnHeaders = await getTurnHeadersRef.current?.();\n const streamHeaders =\n turnHeaders != null ? { headers: turnHeaders } : {};\n const isContinuation =\n \"inputs\" in options ||\n (\"resumeMcpAuth\" in options && options.resumeMcpAuth === true);\n const continuationTurnId = snapshotRef.current.activeStream?.turnId;\n const turnId =\n isContinuation && continuationTurnId != null\n ? continuationTurnId\n : generateId();\n // First turns must send previousTurnId: \"none\".\n const isFirstTurnInSession =\n \"userMessage\" in options &&\n options.previousTurnId === undefined &&\n snapshotRef.current.turns.length === 0 &&\n snapshotRef.current.pendingUser == null &&\n snapshotRef.current.activeStream == null;\n\n // Mutable ref so runStream always reads the latest ID. For new\n // user-message turns the local `generateId()` value is replaced\n // with the gateway-assigned ID once the first SSE event arrives.\n const turnIdRef = { current: turnId };\n\n if (\"inputs\" in options) {\n applyUserToolResponsesToFold(\n snapshotRef.current.fold,\n options.inputs,\n );\n }\n\n const branchBase =\n \"userMessage\" in options ? options.branchFromSnapshot : undefined;\n\n let groupRootBaseline: readonly string[] | undefined;\n\n if (branchBase != null && \"userMessage\" in options) {\n // Atomic apply: never merge pendingUser onto a stale React `prev`\n // that still holds pre-branch turns (edit would show old + new).\n const rootBucket = branchBase.fold.threads.get(ROOT_THREAD_ID);\n groupRootBaseline = [...(rootBucket?.modelMessageIds ?? [])];\n const nextSnapshot = replaceSessionSnapshot(branchBase, {\n pendingUser: {\n turnId,\n content: options.userMessage,\n createdAt: new Date(),\n },\n activeStream: undefined,\n groupRootBaseline,\n });\n snapshotRef.current = nextSnapshot;\n setSnapshot(nextSnapshot);\n pendingUserWasSet = true;\n pendingUserTurnId = turnId;\n } else {\n setSnapshot((prev) =>\n commitActiveStream(\n prev,\n \"inputs\" in options ? options.inputs : undefined,\n ),\n );\n\n if (\"userMessage\" in options) {\n const rootBucket =\n snapshotRef.current.fold.threads.get(ROOT_THREAD_ID);\n groupRootBaseline = [...(rootBucket?.modelMessageIds ?? [])];\n setSnapshot((prev) => {\n const next = replaceSessionSnapshot(prev, {\n pendingUser: {\n turnId,\n content: options.userMessage,\n createdAt: new Date(),\n },\n activeStream: undefined,\n groupRootBaseline,\n });\n snapshotRef.current = next;\n return next;\n });\n pendingUserWasSet = true;\n pendingUserTurnId = turnId;\n } else {\n groupRootBaseline =\n snapshotRef.current.groupRootBaseline ??\n computeGroupRootBaseline(snapshotRef.current.turns);\n }\n }\n\n runStreamStarted = true;\n await runStream(\n (signal) => {\n if (\"inputs\" in options) {\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n { inputs: options.inputs, ...streamHeaders },\n signal,\n groupRootBaseline,\n );\n }\n if (\"resumeMcpAuth\" in options) {\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n { resumeMcpAuth: true, ...streamHeaders },\n signal,\n groupRootBaseline,\n );\n }\n return streamTurnContent(\n server,\n conversationSessionId,\n snapshotRef.current.fold,\n {\n userMessage: options.userMessage,\n ...(options.previousTurnId !== undefined\n ? { previousTurnId: options.previousTurnId ?? \"none\" }\n : isFirstTurnInSession\n ? { previousTurnId: \"none\" }\n : {}),\n ...streamHeaders,\n },\n signal,\n groupRootBaseline,\n // Rename the optimistic local ID to the gateway turn ID\n // so that edit/retry can resolve the turn via the gateway.\n (gatewayTurnId) => {\n const oldId = turnIdRef.current;\n // turn.created proves the gateway registered the message.\n gatewayTurnAccepted = true;\n if (gatewayTurnId === oldId) return;\n turnIdRef.current = gatewayTurnId;\n // Rename in the ref immediately so any synchronous read\n // (e.g. commitActiveStream) sees the correct ID.\n const renamePendingUser = (prev: SessionSnapshot): SessionSnapshot => {\n if (prev.pendingUser?.turnId !== oldId) return prev;\n return replaceSessionSnapshot(prev, {\n pendingUser: { ...prev.pendingUser, turnId: gatewayTurnId },\n });\n };\n snapshotRef.current = renamePendingUser(snapshotRef.current);\n setSnapshot(renamePendingUser);\n },\n );\n },\n turnIdRef,\n isContinuation,\n );\n } catch (error) {\n if (\"userMessage\" in options && !gatewayTurnAccepted) {\n const branchRollbackSnapshot =\n options.branchRollbackSnapshot;\n const canRestoreBranch =\n branchRollbackSnapshot != null &&\n (snapshotRef.current === options.branchFromSnapshot ||\n snapshotRef.current.pendingUser?.turnId ===\n pendingUserTurnId);\n if (canRestoreBranch) {\n snapshotRef.current = branchRollbackSnapshot;\n setSnapshot(branchRollbackSnapshot);\n } else if (pendingUserWasSet) {\n const clearPendingUser = (\n previous: SessionSnapshot,\n ): SessionSnapshot => {\n if (previous.pendingUser?.turnId !== pendingUserTurnId) {\n return previous;\n }\n return replaceSessionSnapshot(previous, {\n pendingUser: undefined,\n });\n };\n snapshotRef.current = clearPendingUser(snapshotRef.current);\n setSnapshot(clearPendingUser);\n }\n options.onPreTurnFailure?.();\n }\n if (!runStreamStarted) {\n onErrorRef.current?.(error);\n }\n throw error;\n }\n },\n [server, runStream, sessionId],\n );\n\n const cancel = useCallback(async () => {\n if (sessionId == null) {\n abortControllerRef.current?.abort();\n return;\n }\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n // Request cancellation but keep consuming the stream. After cancel(),\n // the backend gracefully closes the SSE stream: it emits a terminal\n // turn.done event and then ends the stream, which lets the active run\n // drain to completion on its own instead of being torn down mid-flight.\n await server.cancelSession({ sessionId: conversationSessionId }).catch(() => undefined);\n // Wait for the in-flight stream to finish draining. No explicit\n // reconcile is needed here — the cancelled turn is terminal and local\n // state reconciles against the event log on the next session load.\n await activeRunRef.current?.catch(() => undefined);\n // Nothing drained when the load could not attach a stream, so clear the\n // running flag here or the composer stays blocked until a reload.\n if (resumeUnavailableRef.current) {\n markResumeUnavailable(false);\n setIsRunning(false);\n }\n }, [server, sessionId, markResumeUnavailable]);\n\n const isRunningRef = useRef(isRunning);\n isRunningRef.current = isRunning;\n\n const trySendCollectedRequiredActions = useCallback(\n (nextSnapshot: SessionSnapshot) => {\n if (isRunningRef.current) {\n return;\n }\n const projected = projectSessionMessages(nextSnapshot, projectOptions);\n const paused = findPausedAssistantMessage(projected);\n if (paused == null || messageHasPendingRequiredActions(paused)) {\n return;\n }\n const inputs = collectRequiredActionInputs(paused);\n if (inputs.length > 0) {\n // sendTurn/runStream already report via onError; swallow to avoid duplicates.\n void sendTurn({ inputs }).catch(() => undefined);\n }\n },\n [projectOptions, sendTurn],\n );\n\n const respondToToolApproval = useCallback(\n (response: RespondToToolApprovalOptions) => {\n const prev = snapshotRef.current;\n const approvals = new Map(prev.requiredActions.approvals);\n approvals.set(response.approvalId, {\n approved: response.approved,\n ...(response.reason != null ? { reason: response.reason } : {}),\n });\n const nextSnapshot = replaceSessionSnapshot(prev, {\n requiredActions: {\n ...prev.requiredActions,\n approvals,\n },\n });\n setSnapshot(nextSnapshot);\n trySendCollectedRequiredActions(nextSnapshot);\n },\n [trySendCollectedRequiredActions],\n );\n\n const respondToToolResponse = useCallback(\n (response: RespondToToolResponseOptions) => {\n const prev = snapshotRef.current;\n const toolResponses = new Map(prev.requiredActions.toolResponses);\n toolResponses.set(response.toolCallId, { content: response.content });\n const nextSnapshot = replaceSessionSnapshot(prev, {\n requiredActions: {\n ...prev.requiredActions,\n toolResponses,\n },\n });\n setSnapshot(nextSnapshot);\n trySendCollectedRequiredActions(nextSnapshot);\n },\n [trySendCollectedRequiredActions],\n );\n\n const resumeRun = useCallback(async () => {\n const turn = runningTurnRef.current;\n if (turn == null) {\n return;\n }\n if (server.subscribeToTurn == null) {\n markResumeUnavailable(true);\n return;\n }\n // TODO: pass afterSequenceNumber once stream ingestion tracks sequence numbers.\n await runStream(\n (signal) =>\n resumeTurnStream(\n server,\n turn.sessionId,\n turn.id,\n snapshotRef.current.fold,\n signal,\n undefined,\n snapshotRef.current.groupRootBaseline,\n ),\n { current: turn.id },\n true,\n );\n }, [runStream, server]);\n\n const branchFromTurn = useCallback(\n async (turnId: string, userMessage: UserMessageContent) => {\n let committed: SessionSnapshot;\n let previousTurnId: string;\n let rewound: SessionSnapshot;\n try {\n let activeSessionId = sessionId;\n if (activeSessionId == null) {\n throw new Error(\"Cannot branch from a turn without an active session.\");\n }\n\n committed = commitActiveStream(snapshotRef.current);\n setSnapshot(committed);\n\n await cancel();\n\n const conversationSessionId = await resolveActiveSessionId(\n activeSessionId,\n resolveConversationSessionIdRef.current,\n );\n previousTurnId = await resolveGatewayBranchPreviousTurnIdForTurn(\n server,\n conversationSessionId,\n turnId,\n );\n rewound = await buildSnapshotBeforeTurn(\n server,\n conversationSessionId,\n turnId,\n listEventsConcurrency,\n );\n createdAtByMessageIdRef.current = new Map();\n // Keep the ref aligned before awaiting sendTurn so any intermediate\n // reads (and the atomic pendingUser apply) see the rewound history.\n snapshotRef.current = rewound;\n setSnapshot(rewound);\n } catch (error) {\n // Setup failures never reach sendTurn/runStream reporting.\n onErrorRef.current?.(error);\n throw error;\n }\n\n // sendTurn/runStream own error reporting for the turn itself.\n await sendTurn({\n userMessage,\n previousTurnId,\n branchFromSnapshot: rewound,\n branchRollbackSnapshot: committed,\n });\n },\n [\n cancel,\n server,\n listEventsConcurrency,\n sendTurn,\n sessionId,\n ],\n );\n\n const resetFromTurn = useCallback(\n async (turnId: string) => {\n const committed = commitActiveStream(snapshotRef.current);\n const originalInput = resolveTurnInput(committed, turnId);\n if (originalInput == null) {\n const error = new Error(`Turn ${turnId} not found in session snapshot`);\n onErrorRef.current?.(error);\n throw error;\n }\n const userMessage = extractTurnUserMessageContent(originalInput);\n await branchFromTurn(turnId, userMessage);\n },\n [branchFromTurn],\n );\n\n const editFromTurn = useCallback(\n async (turnId: string, editedText: string) => {\n const committed = commitActiveStream(snapshotRef.current);\n const originalInput = resolveTurnInput(committed, turnId);\n if (originalInput == null) {\n const error = new Error(`Turn ${turnId} not found in session snapshot`);\n onErrorRef.current?.(error);\n throw error;\n }\n const userMessage = buildEditedUserMessageContent(\n editedText,\n originalInput,\n );\n await branchFromTurn(turnId, userMessage);\n },\n [branchFromTurn],\n );\n\n const retryLoad = useCallback(() => {\n setLoadRetryTrigger((n) => n + 1);\n }, []);\n\n const hasOlderHistory = snapshot.historyPagination?.hasOlder === true;\n\n const loadOlderHistory = useCallback(async () => {\n if (sessionId == null || isMain === false) {\n return;\n }\n if (loadOlderInflightRef.current != null) {\n return loadOlderInflightRef.current;\n }\n\n const current = snapshotRef.current;\n if (current.historyPagination?.hasOlder !== true) {\n return;\n }\n if (current.historyPagination.olderPageToken == null) {\n return;\n }\n\n const generation = loadGenerationRef.current;\n setIsLoadingOlderHistory(true);\n\n const run = (async () => {\n try {\n const conversationSessionId = await resolveActiveSessionId(\n sessionId,\n resolveConversationSessionIdRef.current,\n );\n const next = await prependOlderSessionHistory(\n server,\n conversationSessionId,\n snapshotRef.current,\n );\n if (generation !== loadGenerationRef.current) {\n return;\n }\n setSnapshot(next);\n } catch (error) {\n if (generation === loadGenerationRef.current) {\n onErrorRef.current?.(error);\n }\n throw error;\n } finally {\n if (generation === loadGenerationRef.current) {\n setIsLoadingOlderHistory(false);\n }\n loadOlderInflightRef.current = null;\n }\n })();\n\n loadOlderInflightRef.current = run;\n return run;\n }, [server, isMain, sessionId]);\n\n return {\n messages,\n isRunning,\n resumeUnavailable,\n isLoading,\n isLoadingOlderHistory,\n hasOlderHistory,\n loadOlderHistory,\n retryLoad,\n sendTurn,\n cancel,\n respondToToolApproval,\n respondToToolResponse,\n resumeRun,\n branchFromTurn,\n resetFromTurn,\n editFromTurn,\n };\n}\n\nexport { findPausedAssistantMessage, MCP_AUTH_RESUME_RUN_CUSTOM_KEY };\n","import type { AgentChatServer } from \"./server/types.js\";\n\nimport { buildSnapshotFromSessionEvents } from \"./convertTurnMessages.js\";\nimport { getSession } from \"./sessions.js\";\nimport type { SessionSnapshot } from \"./sessionSnapshot.js\";\n\nconst inflightBySessionId = new Map<string, Promise<SessionSnapshot>>();\n\n/**\n * Loads a session snapshot once per concurrent burst for a given session id.\n * React Strict Mode and overlapping fetch/load paths share the same in-flight\n * request instead of duplicating getSession + listEvents calls.\n *\n * `onProgress` is called after each complete turn is ingested so the caller\n * can update the UI progressively while history is being processed.\n */\nexport function loadSessionSnapshot(\n server: AgentChatServer,\n sessionId: string,\n onProgress?: (snap: SessionSnapshot) => void,\n): Promise<SessionSnapshot> {\n let inflight = inflightBySessionId.get(sessionId);\n if (inflight == null) {\n inflight = getSession(server, sessionId)\n .then(() => buildSnapshotFromSessionEvents(server, sessionId, onProgress))\n .finally(() => {\n if (inflightBySessionId.get(sessionId) === inflight) {\n inflightBySessionId.delete(sessionId);\n }\n });\n inflightBySessionId.set(sessionId, inflight);\n }\n return inflight;\n}\n","import type { ThreadMessage } from \"@assistant-ui/core\";\nimport type {\n TurnInputItem,\n UserToolApprovalEvent,\n UserToolResponseEvent,\n} from \"./server/index.js\";\n\nimport { ROOT_THREAD_ID } from \"./constants.js\";\nimport {\n collectApprovalInputs,\n messageHasPendingApprovals,\n} from \"./toolApproval.js\";\nimport {\n collectResponseInputs,\n messageHasPendingResponses,\n} from \"./toolResponse.js\";\n\nexport type RequiredActionInput = Extract<\n TurnInputItem,\n UserToolApprovalEvent | UserToolResponseEvent\n>;\n\nexport function messageHasPendingRequiredActions(\n message: ThreadMessage | undefined,\n): boolean {\n return (\n messageHasPendingApprovals(message) || messageHasPendingResponses(message)\n );\n}\n\nexport function collectRequiredActionInputs(\n message: ThreadMessage,\n defaultThreadId: string = ROOT_THREAD_ID,\n): RequiredActionInput[] {\n if (messageHasPendingRequiredActions(message)) {\n return [];\n }\n return [\n ...collectApprovalInputs(message, defaultThreadId),\n ...collectResponseInputs(message, defaultThreadId),\n ];\n}\n\nexport function isRequiredActionInput(\n item: TurnInputItem,\n): item is RequiredActionInput {\n return (\n item.type === \"user.tool_approval\" || item.type === \"user.tool_response\"\n );\n}\n\nexport function findPausedAssistantMessage(\n messages: readonly ThreadMessage[],\n): Extract<ThreadMessage, { role: \"assistant\" }> | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const candidate = messages[i];\n if (\n candidate?.role === \"assistant\" &&\n candidate.status?.type === \"requires-action\"\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n","import type {\n AgentChatServer,\n PreviousTurnIdInput,\n TurnInputItem,\n} from \"./server/types.js\";\nimport type { TurnStreamData } from \"./server/events.js\";\n\nimport {\n streamTurnEvents,\n type UserMessageContent,\n} from \"./convertTurnMessages.js\";\nimport { PeerThreadFoldState } from \"./foldPeerThreads.js\";\nimport type { RequiredActionInput } from \"./requiredActionInputs.js\";\nimport type { TurnStreamUpdate } from \"./turnStreamUpdate.js\";\n\nexport type StreamTurnOptions = {\n userMessage?: UserMessageContent;\n resumeMcpAuth?: boolean;\n inputs?: RequiredActionInput[];\n /**\n * Branch anchor for createTurn. Omit for `\"auto\"`. Pass `\"none\"` for a fresh\n * root turn.\n */\n previousTurnId?: PreviousTurnIdInput;\n /** Extra headers for the turn request. */\n headers?: Record<string, string>;\n};\n\nfunction buildTurnInput(options: StreamTurnOptions): TurnInputItem[] {\n if (options.inputs != null) {\n return options.inputs;\n }\n if (options.resumeMcpAuth === true) {\n return [];\n }\n return [{ type: \"user.message\", content: options.userMessage ?? \"\" }];\n}\n\nfunction bindAbort(\n server: AgentChatServer,\n sessionId: string,\n abortSignal: AbortSignal,\n): () => void {\n const onAbort = () => {\n void server.cancelSession({ sessionId }).catch(() => undefined);\n };\n if (abortSignal.aborted) {\n onAbort();\n return onAbort;\n }\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n return onAbort;\n}\n\nexport async function* streamTurnContent(\n server: AgentChatServer,\n sessionId: string,\n foldState: PeerThreadFoldState,\n options: StreamTurnOptions,\n abortSignal: AbortSignal,\n groupRootBaseline?: readonly string[],\n /**\n * Called once with the turn ID as soon as it becomes available (first\n * `turn.created` SSE event). Use this to reconcile the locally-generated\n * optimistic ID with the real turn ID.\n */\n onTurnIdAvailable?: (turnId: string) => void,\n): AsyncGenerator<TurnStreamUpdate> {\n const onAbort = bindAbort(server, sessionId, abortSignal);\n if (abortSignal.aborted) {\n return;\n }\n\n let turnIdNotified = false;\n const notifyTurnId = (turnId: string) => {\n if (!turnIdNotified) {\n onTurnIdAvailable?.(turnId);\n turnIdNotified = true;\n }\n };\n\n const stream: AsyncIterable<TurnStreamData> = server.createTurn({\n sessionId,\n input: buildTurnInput(options),\n previousTurnId: options.previousTurnId ?? \"auto\",\n abortSignal,\n ...(options.headers != null ? { headers: options.headers } : {}),\n });\n\n try {\n for await (const update of streamTurnEvents(\n stream,\n foldState,\n groupRootBaseline,\n notifyTurnId,\n )) {\n yield update;\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n throw error;\n } finally {\n abortSignal.removeEventListener(\"abort\", onAbort);\n }\n}\n\n/** TODO: wire `afterSequenceNumber` from the last ingested stream event to skip replay on reconnect. */\nexport async function* resumeTurnStream(\n server: AgentChatServer,\n sessionId: string,\n turnId: string,\n foldState: PeerThreadFoldState,\n abortSignal: AbortSignal,\n afterSequenceNumber?: number,\n groupRootBaseline?: readonly string[],\n): AsyncGenerator<TurnStreamUpdate> {\n // Optional on custom backends. Callers detect the gap and report it, so an\n // empty stream here is safer than throwing mid-render.\n if (server.subscribeToTurn == null) {\n return;\n }\n\n const onAbort = () => {\n void server.cancelSession({ sessionId }).catch(() => undefined);\n };\n if (abortSignal.aborted) {\n onAbort();\n return;\n }\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n yield* streamTurnEvents(\n server.subscribeToTurn({\n sessionId,\n turnId,\n ...(afterSequenceNumber != null\n ? { afterSequenceNumber }\n : {}),\n abortSignal,\n }),\n foldState,\n groupRootBaseline,\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n return;\n }\n throw error;\n } finally {\n abortSignal.removeEventListener(\"abort\", onAbort);\n }\n}\n","import type { RemoteThreadListAdapter } from \"@assistant-ui/core\";\n\nimport type { AgentChatServer } from \"./server/types.js\";\nimport { sessionListStartTimestamp } from \"./sessionListStartTimestamp.js\";\nimport {\n sessionDisplayTitle,\n sessionToThreadMetadata,\n} from \"./sessionThreadMetadata.js\";\n\nconst THREAD_LIST_PAGE_SIZE = 20;\n\n/**\n * Read-only thread-list adapter backed by `AgentChatServer.listSessions`.\n * Hosts that previously used listOwnedSessions should filter in their server impl.\n */\nexport function createTrueFoundryOwnedSessionsThreadListAdapter(options: {\n server: AgentChatServer;\n /** When set, filters `listSessions` by this agent id. Omit for all chats. */\n listSessionsAgentId?: string;\n}): RemoteThreadListAdapter {\n const { server, listSessionsAgentId } = options;\n\n return {\n async list({ after } = {}) {\n const page = await server.listSessions({\n ...(listSessionsAgentId != null ? { agentId: listSessionsAgentId } : {}),\n limit: THREAD_LIST_PAGE_SIZE,\n pageToken: after,\n startTimestamp: sessionListStartTimestamp(),\n });\n const threads = page.data.map((session) =>\n sessionToThreadMetadata(session, sessionDisplayTitle(session)),\n );\n return {\n threads,\n nextCursor: page.nextPageToken ?? undefined,\n };\n },\n\n async initialize() {\n throw new Error(\n \"Owned sessions history adapter is read-only; create sessions via a named or draft runtime.\",\n );\n },\n\n async fetch(remoteId) {\n const session = await server.getSession({ sessionId: remoteId });\n return sessionToThreadMetadata(session, sessionDisplayTitle(session));\n },\n\n async rename() {},\n async archive() {},\n async unarchive() {},\n async delete(remoteId) {\n if (typeof server.deleteSession !== \"function\") return;\n await server.deleteSession({ sessionId: remoteId });\n },\n\n async generateTitle() {\n return new ReadableStream();\n },\n };\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\nimport type { TrueFoundryMessageCustomMetadata } from \"./messageCustomMetadata.js\";\nimport {\n EMPTY_DRAFT_EXTRAS,\n trueFoundryExtras,\n type TrueFoundryDraftRuntimeExtras,\n} from \"./truefoundryExtras.js\";\nimport type { RespondToToolApprovalOptions } from \"./toolApproval.js\";\nimport type { RespondToToolResponseOptions } from \"./toolResponse.js\";\n\n/** Pending tool approvals plus a respond action. */\nexport const useTrueFoundryApprovals = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingApprovals ?? [],\n respond:\n extras?.respondToToolApproval ??\n (() => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Pending ask-user tool responses plus a respond action. */\nexport const useTrueFoundryToolResponses = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingToolResponses ?? [],\n respond:\n extras?.respondToToolResponse ??\n ((_response: RespondToToolResponseOptions) => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Pending MCP OAuth plus a resume action. */\nexport const useTrueFoundryMcpAuth = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n pending: extras?.pendingMcpAuth ?? null,\n resume:\n extras?.resumeMcpAuth ??\n (async () => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/** Returns a function to respond to a tool approval from any render context. */\nexport const useTrueFoundryRespondToToolApproval = () => {\n const aui = useAui();\n return (response: RespondToToolApprovalOptions) =>\n trueFoundryExtras.get(aui).respondToToolApproval(response);\n};\n\n/** Returns a function to respond to a pending tool response from any render context. */\nexport const useTrueFoundryRespondToToolResponse = () => {\n const aui = useAui();\n return (response: RespondToToolResponseOptions) =>\n trueFoundryExtras.get(aui).respondToToolResponse(response);\n};\n\n/** Returns a function to resume after MCP OAuth from any render context. */\nexport const useTrueFoundryResumeMcpAuth = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).resumeMcpAuth();\n};\n\n/** Current sandboxId for this session, if a sandbox has been created. */\nexport const useTrueFoundrySandboxId = (): string | undefined =>\n trueFoundryExtras.use((e) => e.sandboxId, undefined);\n\n/** Turn that produced the message being rendered. Only defined inside a message scope. */\nexport const useTrueFoundryTurnId = (): string | undefined =>\n useAuiState(\n (state) =>\n (state.message.metadata?.custom as TrueFoundryMessageCustomMetadata | undefined)\n ?.turnId,\n );\n\n/**\n * Returns a function to download a file the current turn wrote to its sandbox. Must be called\n * from a message scope, since the artifact belongs to the turn that rendered it.\n */\nexport const useTrueFoundryDownloadSandboxFile = () => {\n const aui = useAui();\n const turnId = useTrueFoundryTurnId();\n return (path: string) => {\n if (turnId == null) {\n throw new Error(\n \"Downloading a sandbox file requires a message scope to resolve its turn.\",\n );\n }\n return trueFoundryExtras.get(aui).downloadSandboxFile({ turnId, path });\n };\n};\n\n/** Returns a function to cancel the current run from any render context. */\nexport const useTrueFoundryCancel = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).cancel();\n};\n\n/** Returns a function to reload (retry) the current session from any render context. */\nexport const useTrueFoundryReload = () => {\n const aui = useAui();\n return () => trueFoundryExtras.get(aui).reload();\n};\n\n/** Older history pagination state plus a load-more action for scroll-up. */\nexport const useTrueFoundryHistoryPagination = () => {\n const extras = trueFoundryExtras.use((e) => e, undefined);\n\n return useMemo(\n () => ({\n hasOlderHistory: extras?.hasOlderHistory ?? false,\n isLoadingOlderHistory: extras?.isLoadingOlderHistory ?? false,\n loadOlderHistory:\n extras?.loadOlderHistory ??\n (async () => {\n throw new Error(\"TrueFoundry runtime is not ready yet\");\n }),\n }),\n [extras],\n );\n};\n\n/**\n * True while a turn runs that this server cannot stream, so its result will not\n * arrive in this client. Falls back to `false` on runtimes that predate the flag.\n */\nexport const useTrueFoundryResumeUnavailable = () =>\n trueFoundryExtras.use((e) => e.resumeUnavailable, false) ?? false;\n\n/** Returns a function to reset (re-submit) a user turn from any render context. */\nexport const useTrueFoundryResetFromTurn = () => {\n const aui = useAui();\n return (turnId: string) => trueFoundryExtras.get(aui).resetFromTurn(turnId);\n};\n\n/** Current draft agent spec and sync state (draft mode only). */\nexport const useTrueFoundryAgentSpec = () => {\n const extras = trueFoundryExtras.use((e) => e.draft, null);\n\n return useMemo(\n () => ({ ...EMPTY_DRAFT_EXTRAS, ...extras }),\n [extras],\n );\n};\n\n/** Returns a draft spec updater from any render context. */\nexport const useTrueFoundryUpdateAgentSpec = () => {\n const aui = useAui();\n return (update: Parameters<TrueFoundryDraftRuntimeExtras[\"updateAgentSpec\"]>[0]) =>\n trueFoundryExtras.get(aui).draft?.updateAgentSpec(update);\n};\n\n/** Flushes any pending draft-spec synchronization before a coordinated write. */\nexport const useTrueFoundryFlushAgentSpec = () => {\n const aui = useAui();\n return () =>\n trueFoundryExtras.get(aui).draft?.flushAgentSpec() ?? Promise.resolve();\n};\n\n/** Adopts a spec already persisted by another server operation without syncing again. */\nexport const useTrueFoundryAdoptAgentSpec = () => {\n const aui = useAui();\n return (\n request: Parameters<TrueFoundryDraftRuntimeExtras[\"adoptAgentSpec\"]>[0],\n ) => trueFoundryExtras.get(aui).draft?.adoptAgentSpec(request);\n};\n\n","import {\n generateId,\n type AttachmentAdapter,\n type PendingAttachment,\n} from \"@assistant-ui/core\";\n\nconst bytesToBase64 = (bytes: Uint8Array): string =>\n globalThis.Buffer.from(bytes).toString(\"base64\");\n\nconst getFileDataURL = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n const buffer = await file.arrayBuffer();\n return `data:${file.type};base64,${bytesToBase64(new Uint8Array(buffer))}`;\n }\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n};\n\n/**\n * Reads composer files into `CompleteAttachment` `file` parts for send.\n * Wire via `adapters: { attachments: trueFoundryAttachmentAdapter }`.\n */\nexport const trueFoundryAttachmentAdapter: AttachmentAdapter = {\n accept: \"*\",\n async add({ file }) {\n return {\n id: generateId(),\n type: \"file\",\n name: file.name,\n file,\n contentType: file.type,\n content: [],\n status: {\n type: \"requires-action\",\n reason: \"composer-send\",\n },\n };\n },\n async send(attachment: PendingAttachment) {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n mimeType: attachment.contentType ?? \"\",\n filename: attachment.name,\n data: await getFileDataURL(attachment.file),\n },\n ],\n };\n },\n async remove() {},\n};\n"],"mappings":"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","names":["useCallback","useMemo","useRef","useState","existing","bucket","itemsAsc","parseDataUriMime","THREAD_LIST_PAGE_SIZE","useCallback","useEffect","useMemo","useRef","useState","inflightBySessionId","useState","useRef","useCallback","useMemo","useEffect","useRef","useCallback","useState","useMemo","THREAD_LIST_PAGE_SIZE","useMemo","useAui","useAuiState","useMemo","useAui","useAuiState","generateId"]}