@blade-hq/agent-react 2612.0.0-beta.57 → 2612.0.0-beta.58

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/use-agent-session.ts","../src/hooks/use-replay.ts","../src/components/ReplayBar.tsx","../src/components/ReplayMismatchPrompt.tsx","../src/components/AgentChat.tsx","../src/chat/ChatPanel.tsx","../src/components/SessionQueuePanel.tsx","../src/components/queue-panel-adjacency.ts","../src/chat/ConnectionBanner.tsx","../src/chat/CurrentPlanPanel.tsx","../src/chat/customization.ts","../src/chat/followup-interaction.ts","../src/chat/LightComposer.tsx","../src/components/ChatInput.tsx","../src/chat/ChatLoadingIndicator.tsx","../src/chat/LiteMessageList.tsx","../src/chat/lib/citations.ts","../src/components/BackgroundWakeNotice.tsx","../src/chat/AssistantTurnBlock.tsx","../src/chat/lib/ui-meta.ts","../src/chat/lib/loopback.ts","../../ui/src/components/collapsible.tsx","../src/chat/ai-elements/reasoning.tsx","../src/chat/ai-elements/shimmer.tsx","../src/chat/card/CardContext.tsx","../src/chat/FileDeliveryCards.tsx","../src/chat/MessageActions.tsx","../src/chat/MessageFileAttachmentList.tsx","../src/chat/ToolUiCard.tsx","../src/chat/ToolCallBlock.tsx","../src/chat/AskUserQuestionBlock.tsx","../src/chat/WorkflowRunBlock.tsx","../src/chat/AgentLoopBlock.tsx","../src/chat/ContextAttachmentPills.tsx","../src/chat/lib/use-async-value.ts","../src/chat/AttachmentPreviewDialog.tsx","../src/chat/lib/preview-dispatch.ts","../src/chat/UserMessageBubble.tsx","../src/lib/whatif-prompt.ts","../src/chat/MessageContextPills.tsx","../src/chat/TextAttachmentPills.tsx","../src/components/WhatIfUserBubble.tsx","../src/chat/reasoning-visibility.ts","../src/chat/assistant-turn-questions.ts","../src/hooks/use-message-pin.ts","../src/chat/message-list-blocks.ts","../src/components/ContextCard.tsx","../src/chat/ResultFeedback.tsx","../src/chat/MessageList.tsx","../../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js","../../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js","../src/hooks/use-turn-navigation.ts","../src/hooks/use-typewriter-reveal.ts","../src/chat/plan/PlanSummaryCard.tsx","../../../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs","../src/chat/plan/parse-plan-tree.ts","../src/chat/plan/parse-plan-messages.ts","../src/chat/plan/extract-plan-messages.ts","../src/chat/PostChatFollowupBlock.tsx","../src/chat/FinalArtifactCards.tsx","../src/chat/RenderErrorBoundary.tsx","../src/chat/TurnNavRail.tsx","../src/chat/scroll-anchor.ts","../src/chat/runtime/use-chat-actions.ts","../src/chat/runtime/use-session-replay.ts","../src/chat/SessionReplayBar.tsx","../src/components/SessionPluginSelector.tsx","../src/components/LlmChat.tsx","../src/hooks/use-llm-chat.ts","../src/components/LlmAdvancedSettings.tsx","../src/components/ChatView.tsx","../src/components/TopicAssetSubmitDialog.tsx"],"sourcesContent":["import type {\n AgentSession,\n CreateSessionRequest,\n SessionState,\n} from \"@blade-hq/agent-client\"\nimport { useEffect, useMemo, useRef, useState, useSyncExternalStore } from \"react\"\nimport { useBladeClient } from \"../context\"\n\nexport interface UseAgentSessionOptions {\n /** 不传 sessionId 时按此配置新建会话;两者都不传则新建默认对话。 */\n createOptions?: CreateSessionRequest\n /** 自动创建出的 sessionId 通过此回调交还调用方持有(重挂载复用的依据)。 */\n onSessionCreated?: (sessionId: string) => void\n /**\n * 会话进入实时事件路由后、历史加载与房间订阅开始前同步执行。\n * 返回的清理函数会在切换会话或卸载时执行。\n */\n onSessionConnected?: (session: AgentSession) => () => void\n}\n\nexport interface UseAgentSessionResult {\n /** 连接/创建完成前为 null。 */\n session: AgentSession | null\n /** 会话状态快照;session 未就绪时为 null。 */\n state: SessionState | null\n /** 连接或创建失败的错误。 */\n error: Error | null\n}\n\nconst EMPTY_SUBSCRIBE = () => () => {}\n\nconst DISPOSE_DELAY_MS = 1000\n\n/**\n * 连接(或创建)一个会话并订阅其状态。\n *\n * - 优先级:sessionId(连接既有会话)> createOptions(按配置新建)> 默认新建。\n * - 同一 sessionId 重复调用复用同一 AgentSession 实例(SessionHub 引用计数)。\n * - 自动创建只发生一次(含 StrictMode 双跑);创建出的 id 经 onSessionCreated\n * 交还调用方。\n *\n * **连接与 sessionId 变更分离**:连接在挂载时建立、仅在卸载时释放;只有\n * 当 sessionId 明确切到一个「与当前已连接会话不同」的 id 时才重连。这样宿主\n * (如 Vue 把自动创建的 id 写回 `session-id` 属性)回填同一个 id 不会触发\n * 拆–重连——否则会把正在流式的会话换成新实例、当前渲染整个丢失。\n */\nexport function useAgentSession(\n sessionId?: string,\n options: UseAgentSessionOptions = {},\n): UseAgentSessionResult {\n const client = useBladeClient()\n const [session, setSession] = useState<AgentSession | null>(null)\n const [error, setError] = useState<Error | null>(null)\n\n const connRef = useRef<{\n id: string | null\n session: AgentSession | null\n cleanup: (() => void) | null\n gen: number\n }>({\n id: null,\n session: null,\n cleanup: null,\n gen: 0,\n })\n const createdIdPromiseRef = useRef<Promise<string> | null>(null)\n const onCreatedRef = useRef(options.onSessionCreated)\n onCreatedRef.current = options.onSessionCreated\n const onConnectedRef = useRef(options.onSessionConnected)\n onConnectedRef.current = options.onSessionConnected\n const createOptionsRef = useRef(options.createOptions)\n createOptionsRef.current = options.createOptions\n const sessionIdRef = useRef(sessionId)\n sessionIdRef.current = sessionId\n\n const connect = useMemo(() => {\n return (targetId: string | undefined) => {\n const gen = ++connRef.current.gen\n let pendingCleanup: (() => void) | null = null\n const idPromise = targetId\n ? Promise.resolve(targetId)\n : // biome-ignore lint/suspicious/noAssignInExpressions: ??= 挂 ref 是 StrictMode 下\"只创建一次\"的关键\n (createdIdPromiseRef.current ??= (createOptionsRef.current?.anonymous\n ? client.sessions.createSessionWithRequest(createOptionsRef.current).then(({ session_id }) => {\n onCreatedRef.current?.(session_id)\n return session_id\n })\n : client.sessions\n .create(createOptionsRef.current ?? {})\n .then((created) => {\n const id = created.sessionId\n created.dispose()\n onCreatedRef.current?.(id)\n return id\n })))\n\n idPromise\n .then((id) =>\n (createOptionsRef.current?.anonymous ? client.forAnonymousSession(id) : client).hub.connect(id, {\n setup: (next) => {\n pendingCleanup = onConnectedRef.current?.(next) ?? null\n },\n }),\n )\n .then((next) => {\n if (connRef.current.gen !== gen) {\n pendingCleanup?.()\n next.dispose()\n return\n }\n connRef.current.id = next.sessionId\n connRef.current.session = next\n connRef.current.cleanup = pendingCleanup\n setSession(next)\n setError(null)\n })\n .catch((err) => {\n pendingCleanup?.()\n if (connRef.current.gen !== gen) return\n createdIdPromiseRef.current = null\n setError(err instanceof Error ? err : new Error(String(err)))\n })\n }\n }, [client])\n\n useEffect(() => {\n connect(sessionIdRef.current)\n return () => {\n connRef.current.gen++\n const toRelease = connRef.current.session\n const cleanup = connRef.current.cleanup\n connRef.current.id = null\n connRef.current.session = null\n connRef.current.cleanup = null\n cleanup?.()\n setSession(null)\n if (toRelease) setTimeout(() => toRelease.dispose(), DISPOSE_DELAY_MS)\n }\n }, [connect])\n\n useEffect(() => {\n if (!sessionId) return\n if (connRef.current.id === null) return\n if (sessionId === connRef.current.id) return\n const previous = connRef.current.session\n const cleanup = connRef.current.cleanup\n connRef.current.id = null\n connRef.current.session = null\n connRef.current.cleanup = null\n cleanup?.()\n if (previous) setTimeout(() => previous.dispose(), DISPOSE_DELAY_MS)\n connect(sessionId)\n }, [sessionId, connect])\n\n const store = useMemo(\n () => ({\n subscribe: session ? (listener: () => void) => session.subscribe(listener) : EMPTY_SUBSCRIBE,\n getSnapshot: () => (session ? session.getState() : null),\n }),\n [session],\n )\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot)\n\n return { session, state, error }\n}\n","import { DEFAULT_REPLAY_SPEED } from \"@blade-hq/agent-client/internal\"\nimport type { AgentSession, ReplaySpeed, SessionState } from \"@blade-hq/agent-client/internal\"\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useBladeClient } from \"../context\"\n\n/** 回放中用户说的话和录制内容对不上,需要当场决定往哪走。 */\nexport interface ReplayMismatch {\n /** 用户这次实际发出的内容。 */\n actualMessage: string\n /** 源会话里录制的下一句。 */\n expectedMessage: string\n /** keep_replay:按录制内容继续;continue_replay:从这里转为真实运行。 */\n resolve: (decision: \"keep_replay\" | \"continue_replay\") => void\n}\n\nexport interface UseReplayResult {\n /** 当前会话是不是正在回放(转自主运行后为 false)。 */\n isReplay: boolean\n /** 当前播放倍速,非回放会话固定为 1。 */\n speed: ReplaySpeed\n setSpeed: (speed: ReplaySpeed) => Promise<void>\n /** 退出回放,之后的对话交给真实模型运行。 */\n exitToAutonomous: () => Promise<void>\n /** 待决策的输入冲突;处理完自动清空。 */\n mismatch: ReplayMismatch | null\n /** 能不能改回放(改回放是 owner 专属)。只读身份下仍然显示\"在回放\",但不能操作。 */\n canControl: boolean\n\n /** 当前会话能否作为回放来源(并行子智能体等场景不支持)。 */\n canReplay: boolean\n /** canReplay 为 false 时的原因,可直接展示。 */\n unsupportedReason: string | null\n /** 从当前会话派生一个回放会话,返回新会话 id。 */\n startReplay: (speed?: ReplaySpeed) => Promise<string>\n isStarting: boolean\n /** 最近一次回放操作失败的原因。 */\n error: Error | null\n}\n\nconst replayCreating = new Set<string>()\n\n/**\n * 会话回放(演示 / 彩排模式)。\n *\n * 回放会话不会自动播放:用户照常发消息,只要这句和源会话录制的下一句意图一致,\n * 服务端就按倍速重放当时的回复和工具调用,完全不调用模型;对不上就抛出\n * `mismatch` 交给界面决定。\n *\n * 同一个 hook 覆盖两种身份——传入的会话既可能是回放会话(isReplay / setSpeed /\n * exitToAutonomous / mismatch),也可能是准备被回放的源会话(canReplay /\n * startReplay)。\n *\n * 回放状态本身住在 `SessionState.replay` 里(非 React 宿主直接订阅它即可),\n * 这里只做 React 绑定:订阅快照 + 接管冲突 + 拉一次 preview。\n *\n * **注册即接管**:底层的 `replayMismatch` 只交给最先注册的处理器。调用本 hook\n * 就意味着由它接管冲突;不调用则维持 SDK 默认行为——直接转为真实运行。\n */\nexport function useReplay(session: AgentSession | null): UseReplayResult {\n const client = useBladeClient()\n const sessionId = session?.sessionId ?? null\n\n const [replay, setReplay] = useState<SessionState[\"replay\"]>(null)\n const [viewerRole, setViewerRole] = useState<SessionState[\"viewerRole\"]>(null)\n const [sourceRunning, setSourceRunning] = useState(false)\n const [mismatch, setMismatch] = useState<ReplayMismatch | null>(null)\n const [preview, setPreview] = useState<\n { status: \"loading\" } | { status: \"ready\"; supported: boolean; reason: string | null }\n >({ status: \"loading\" })\n const [isStarting, setIsStarting] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const [draftSpeed, setDraftSpeed] = useState<ReplaySpeed>(DEFAULT_REPLAY_SPEED)\n\n useEffect(() => {\n if (!session) {\n setReplay(null)\n setViewerRole(null)\n setSourceRunning(false)\n return\n }\n const pull = () => {\n const state = session.getState()\n setReplay(state.replay)\n setViewerRole(state.viewerRole)\n setSourceRunning(state.isStreaming || state.status === \"running\")\n }\n pull()\n return session.subscribe(pull)\n }, [session])\n\n const [lastSessionId, setLastSessionId] = useState(sessionId)\n if (sessionId !== lastSessionId) {\n setLastSessionId(sessionId)\n setMismatch(null)\n setError(null)\n setDraftSpeed(DEFAULT_REPLAY_SPEED)\n }\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: sourceRunning 跨过\"运行中\"这条线就是重新查询的触发条件——这一轮跑完了本该能回放,新一轮开始了就不该再放行\n useEffect(() => {\n setPreview({ status: \"loading\" })\n if (!sessionId) return\n let alive = true\n client.sessions\n .getReplayPreview(sessionId)\n .then((result) => {\n if (!alive) return\n setPreview({\n status: \"ready\",\n supported: result.supported,\n reason: result.reason ?? null,\n })\n })\n .catch(() => {\n if (alive) setPreview({ status: \"ready\", supported: true, reason: null })\n })\n return () => {\n alive = false\n }\n }, [client, sessionId, sourceRunning])\n\n useEffect(() => {\n if (!session) return\n return session.on(\"replayMismatch\", ({ actualMessage, expectedMessage, respond }) => {\n setMismatch({\n actualMessage: actualMessage ?? \"\",\n expectedMessage: expectedMessage ?? \"\",\n resolve: (decision) => {\n setMismatch(null)\n respond(decision)\n },\n })\n })\n }, [session])\n\n const isReplay = replay?.isReplay ?? false\n\n const setSpeed = useCallback(\n async (next: ReplaySpeed) => {\n setDraftSpeed(next)\n if (!session) return\n setError(null)\n try {\n await session.setReplaySpeed(next)\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n }\n },\n [session],\n )\n\n const exitToAutonomous = useCallback(async () => {\n if (!session) return\n setError(null)\n const pending = mismatch\n if (pending) {\n pending.resolve(\"continue_replay\")\n return\n }\n try {\n await session.exitReplay()\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n }\n }, [session, mismatch])\n\n const startReplay = useCallback(\n async (speed?: ReplaySpeed) => {\n if (!sessionId) throw new Error(\"当前没有可回放的会话\")\n if (replayCreating.has(sessionId)) throw new Error(\"正在创建回放会话,请稍候\")\n replayCreating.add(sessionId)\n setIsStarting(true)\n setError(null)\n try {\n const result = await client.sessions.startReplaySession(sessionId, speed ?? draftSpeed)\n return result.session_id\n } catch (err) {\n const failure = err instanceof Error ? err : new Error(String(err))\n setError(failure)\n throw failure\n } finally {\n replayCreating.delete(sessionId)\n setIsStarting(false)\n }\n },\n [client, sessionId, draftSpeed],\n )\n\n return {\n isReplay,\n speed: isReplay ? (replay?.speed ?? 1) : draftSpeed,\n setSpeed,\n exitToAutonomous,\n mismatch,\n canControl: viewerRole !== \"viewer\",\n canReplay:\n Boolean(sessionId) &&\n preview.status === \"ready\" &&\n preview.supported &&\n viewerRole !== \"viewer\",\n unsupportedReason:\n preview.status === \"ready\" && !preview.supported ? preview.reason : null,\n startReplay,\n isStarting,\n error,\n }\n}\n","import type { ReplaySpeed } from \"@blade-hq/agent-client/internal\"\nimport { Play } from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nconst SPEED_OPTIONS: ReplaySpeed[] = [1, 2, 5]\n\nexport interface ReplayBarProps {\n /** 非回放会话传 false 时整条不渲染。 */\n isReplay: boolean\n speed: ReplaySpeed\n onSpeedChange: (speed: ReplaySpeed) => void\n onExit: () => void\n /** 传 useReplay().canControl。只读身份下仍然显示\"在回放\",但操作按钮禁用。 */\n canControl?: boolean\n className?: string\n}\n\n/** 回放会话的顶部状态条:说明当前在回放、切换倍速、随时退出回放。 */\nexport function ReplayBar({\n isReplay,\n speed,\n onSpeedChange,\n onExit,\n canControl = true,\n className,\n}: ReplayBarProps) {\n if (!isReplay) return null\n\n return (\n <div\n part=\"replay-bar\"\n className={cn(\n \"blade-chat-replay-bar flex flex-wrap items-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))]/40 px-3 py-2 text-[11px]\",\n className,\n )}\n >\n <span className=\"inline-flex shrink-0 items-center gap-1.5 font-medium text-[hsl(var(--foreground))]\">\n <Play size={12} />\n 回放模式\n </span>\n <span className=\"min-w-0 text-[hsl(var(--muted-foreground))]\">\n 正在重现之前的对话\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-1.5\">\n <div className=\"flex items-center gap-0.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-0.5\">\n {SPEED_OPTIONS.map((option) => (\n <button\n key={option}\n type=\"button\"\n onClick={() => onSpeedChange(option)}\n aria-pressed={speed === option}\n disabled={!canControl}\n className={cn(\n \"h-5 rounded px-1.5 font-medium transition-colors\",\n speed === option\n ? \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\"\n : \"text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\",\n !canControl && \"cursor-not-allowed opacity-50\",\n )}\n >\n {option}x\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={onExit}\n disabled={!canControl}\n className={cn(\n \"h-6 rounded-md border border-[hsl(var(--border))] px-2 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\",\n !canControl && \"cursor-not-allowed opacity-50 hover:bg-transparent\",\n )}\n >\n 退出回放\n </button>\n </div>\n </div>\n )\n}\n","import type { ReplayMismatch } from \"../hooks/use-replay\"\nimport { cn } from \"../lib/utils\"\n\nexport interface ReplayMismatchPromptProps {\n /** 来自 useReplay().mismatch;为 null 时不渲染。 */\n mismatch: ReplayMismatch | null\n className?: string\n}\n\n/** 回放中输入和录制内容对不上时的选择卡:按录制继续,还是从这里真跑。 */\nexport function ReplayMismatchPrompt({ mismatch, className }: ReplayMismatchPromptProps) {\n if (!mismatch) return null\n\n return (\n <div\n className={cn(\n \"mx-auto my-3 max-w-3xl rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-4 py-3 text-sm\",\n className,\n )}\n >\n <div className=\"font-medium text-[hsl(var(--foreground))]\">\n 这句话和之前录制的不一样\n </div>\n <dl className=\"mt-2 space-y-1 text-xs text-[hsl(var(--muted-foreground))]\">\n <div className=\"flex gap-2\">\n <dt className=\"shrink-0\">录制的是</dt>\n <dd className=\"min-w-0 break-words text-[hsl(var(--foreground))]\">\n {mismatch.expectedMessage || \"(空)\"}\n </dd>\n </div>\n <div className=\"flex gap-2\">\n <dt className=\"shrink-0\">你输入的</dt>\n <dd className=\"min-w-0 break-words text-[hsl(var(--foreground))]\">\n {mismatch.actualMessage || \"(空)\"}\n </dd>\n </div>\n </dl>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => mismatch.resolve(\"keep_replay\")}\n className=\"h-8 rounded-md bg-[hsl(var(--primary))] px-3 text-xs font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90\"\n >\n 按录制内容继续\n </button>\n <button\n type=\"button\"\n onClick={() => mismatch.resolve(\"continue_replay\")}\n className=\"h-8 rounded-md border border-[hsl(var(--border))] px-3 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n 从这里开始真的运行\n </button>\n </div>\n </div>\n )\n}\n","import type { AgentSession, BladeClient, CreateSessionRequest } from \"@blade-hq/agent-client/internal\"\nimport { BladeApiError } from \"@blade-hq/agent-client/internal\"\nimport { LockKeyhole } from \"lucide-react\"\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\"\nimport { ChatPanel } from \"../chat/ChatPanel\"\nimport type { ChatPresentationProps } from \"../chat/customization\"\nimport type { FollowupInteractionEvent } from \"../chat/followup-interaction\"\nimport { type ChatEnvironment, ChatEnvironmentProvider } from \"../chat/runtime/environment\"\nimport { SessionSourceProvider, useSingleSessionSource } from \"../chat/runtime/session-source\"\nimport { BladeProvider, useBladeClient, useBladeHost } from \"../context\"\nimport { useAgentSession } from \"../hooks/use-agent-session\"\nimport { useReplay } from \"../hooks/use-replay\"\nimport { cn } from \"../lib/utils\"\nimport { ReplayMismatchPrompt } from \"./ReplayMismatchPrompt\"\nimport { SessionPluginSelector } from \"./SessionPluginSelector\"\n\nexport interface AgentChatProps extends ChatPresentationProps {\n /** follow-up、成果和评分交互;SDK 不绑定任何分析厂商。 */\n onFollowupInteraction?: (event: FollowupInteractionEvent) => void\n /** 连接既有会话;不传则按 createOptions 自动新建。 */\n sessionId?: string\n createOptions?: CreateSessionRequest\n /** 自动创建出的 sessionId 通过此回调交还调用方持有。 */\n onSessionCreated?: (sessionId: string) => void\n /** 会话连接完成后回调(页面协作场景拿 AgentSession 实例用)。 */\n onSessionReady?: (session: AgentSession) => void\n /** 智能体下发给宿主页面的指令处理器(action → handler)。 */\n commands?: Record<string, (data: unknown) => void>\n /** 覆盖默认会话插件选择器。 */\n sessionPluginControls?: (sessionId: string) => ReactNode\n}\n\nfunction isUnauthorizedError(error: Error | null): boolean {\n return error instanceof BladeApiError && error.status === 401\n}\n\nfunction LoginCard({ client, onLoggedIn }: { client: BladeClient; onLoggedIn: () => void }) {\n const [loggingIn, setLoggingIn] = useState(false)\n const [loginError, setLoginError] = useState<string | null>(null)\n\n const handleLogin = async () => {\n setLoggingIn(true)\n setLoginError(null)\n try {\n await client.login()\n onLoggedIn()\n } catch (error) {\n setLoginError(error instanceof Error && error.message ? error.message : \"登录失败,请重试\")\n } finally {\n setLoggingIn(false)\n }\n }\n\n return (\n <div className=\"blade-chat-login flex flex-1 items-center justify-center p-6\">\n <div className=\"flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center\">\n <LockKeyhole size={28} className=\"text-[hsl(var(--muted-foreground))]\" />\n <div className=\"text-base font-medium text-[hsl(var(--foreground))]\">需要登录后使用</div>\n <div className=\"text-sm text-[hsl(var(--muted-foreground))]\">\n 登录后即可与智能体对话,你的会话内容仅自己可见。\n </div>\n <button\n type=\"button\"\n onClick={handleLogin}\n disabled={loggingIn}\n className=\"w-full rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-sm font-semibold text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:opacity-60\"\n >\n {loggingIn ? \"登录中…\" : \"登录\"}\n </button>\n {loginError && <div className=\"text-xs text-[hsl(var(--destructive))]\">{loginError}</div>}\n </div>\n </div>\n )\n}\n\n/**\n * 智能体模式的聊天界面:连接(或新建)一个 Blade 会话,渲染消息流与输入框。\n * 状态全部来自 useAgentSession,不依赖任何全局 store。\n */\nexport function AgentChat(props: AgentChatProps) {\n const client = useBladeClient()\n const [attempt, setAttempt] = useState(0)\n const [needLogin, setNeedLogin] = useState(() => !client.hasToken())\n\n if (needLogin) {\n return (\n <div\n data-theme={props.theme}\n part=\"root\"\n className={cn(\"blade-chat flex min-h-0 flex-1 flex-col\", props.classNames?.root)}\n >\n <LoginCard\n client={client}\n onLoggedIn={() => {\n setNeedLogin(false)\n setAttempt((value) => value + 1)\n }}\n />\n </div>\n )\n }\n\n return <ChatSessionView key={attempt} {...props} onUnauthorized={() => setNeedLogin(true)} />\n}\n\nfunction ChatSessionView({\n sessionId,\n createOptions,\n onSessionCreated,\n onSessionReady,\n commands,\n classNames,\n renderers,\n slots,\n placeholder,\n theme,\n onFollowupInteraction,\n sessionPluginControls,\n onUnauthorized,\n}: AgentChatProps & { onUnauthorized: () => void }) {\n const client = useBladeClient()\n const host = useBladeHost()\n const { session, state, error } = useAgentSession(sessionId, {\n createOptions,\n onSessionCreated,\n })\n const replay = useReplay(session)\n const [notice, setNotice] = useState<string | null>(null)\n const source = useSingleSessionSource(session, !session || state === null)\n const resolvedSessionId = session?.sessionId\n const isViewer = state?.viewerRole === \"viewer\"\n const replaySpeed = state?.replay?.speed\n const replaying = state?.replay?.isReplay\n // biome-ignore lint/correctness/useExhaustiveDependencies: 这几个值只作为清除时机\n useEffect(() => {\n setNotice(null)\n }, [resolvedSessionId, replaySpeed, replaying])\n const onSessionReadyRef = useRef(onSessionReady)\n const readySessionRef = useRef<AgentSession | null>(null)\n const hasOnSessionReady = onSessionReady !== undefined\n\n useEffect(() => {\n onSessionReadyRef.current = onSessionReady\n }, [onSessionReady])\n\n useEffect(() => {\n const handler = onSessionReadyRef.current\n if (!session || !hasOnSessionReady || !handler || readySessionRef.current === session) return\n readySessionRef.current = session\n handler(session)\n }, [session, hasOnSessionReady])\n\n useEffect(() => {\n if (isUnauthorizedError(error)) {\n onUnauthorized()\n }\n }, [error, onUnauthorized])\n\n useEffect(() => {\n if (!session || !commands) return\n const unsubscribes = Object.entries(commands).map(([action, handler]) =>\n session.onCommand(action, (payload) => handler(payload)),\n )\n return () => {\n for (const unsubscribe of unsubscribes) unsubscribe()\n }\n }, [session, commands])\n\n const environment = useMemo<ChatEnvironment>(\n () => ({\n notify: (kind, message) => {\n setNotice(kind === \"error\" ? message : null)\n },\n }),\n [],\n )\n const connectError =\n error && !isUnauthorizedError(error)\n ? error.message || \"连接失败,请稍后重试\"\n : null\n\n const sessionClient = resolvedSessionId && createOptions?.anonymous && !client.options.anonymousSessionId\n ? client.forAnonymousSession(resolvedSessionId)\n : client\n return (\n <BladeProvider client={sessionClient} host={host}>\n <SessionSourceProvider source={source}>\n <ChatEnvironmentProvider value={environment}>\n <ChatPanel\n sessionId={resolvedSessionId ?? \"\"}\n theme={theme}\n classNames={classNames}\n renderers={renderers}\n header={slots?.header}\n footer={slots?.footer}\n emptyState={slots?.emptyState}\n placeholder={placeholder}\n onFollowupInteraction={onFollowupInteraction}\n errorMessage={connectError ?? replay.error?.message ?? notice}\n onExitReplay={() => void replay.exitToAutonomous()}\n banner={\n <>\n {resolvedSessionId && !isViewer && (sessionPluginControls\n ? sessionPluginControls(resolvedSessionId)\n : (client.options.anonymousSessionId || createOptions?.anonymous ? null : <SessionPluginSelector client={client} sessionId={resolvedSessionId} />))}\n <ReplayMismatchPrompt mismatch={replay.mismatch} />\n </>\n }\n />\n </ChatEnvironmentProvider>\n </SessionSourceProvider>\n </BladeProvider>\n )\n}\n","import { CircleAlert, Eye } from \"lucide-react\"\nimport { type ReactNode, useCallback, useEffect, useMemo, useState } from \"react\"\nimport {\n chatErrorForDisplay,\n latestPostChatFollowup,\n type MessageContent,\n type QueuedMessage,\n type ResultFeedback,\n} from \"@blade-hq/agent-client/internal\"\nimport { SessionQueuePanel } from \"../components/SessionQueuePanel\"\nimport { McpAppMessageContext } from \"../components/McpAppCard\"\nimport { useBladeClient } from \"../context\"\nimport { cn } from \"../lib/utils\"\nimport type { AskUserAnswerData } from \"./AskUserQuestionBlock\"\nimport { ConnectionBanner } from \"./ConnectionBanner\"\nimport { CurrentPlanPanel } from \"./CurrentPlanPanel\"\nimport {\n ChatCustomizationProvider,\n type ChatSendOptions,\n type ChatViewCustomization,\n type ComposerProps,\n} from \"./customization\"\nimport { FollowupInteractionProvider, type FollowupInteractionEvent } from \"./followup-interaction\"\nimport { LightComposer } from \"./LightComposer\"\nimport { LiteMessageList } from \"./LiteMessageList\"\nimport { MessageList as FullMessageList } from \"./MessageList\"\nimport {\n ChatEnvironmentProvider,\n type ChatRenderMode,\n useChatEnvironment,\n useChatRenderMode,\n useChatSessionDetail,\n useComposerBridge,\n} from \"./runtime/environment\"\nimport { useChatActions } from \"./runtime/use-chat-actions\"\nimport { useSessionReplay } from \"./runtime/use-session-replay\"\nimport {\n CurrentChatSessionProvider,\n useIsSessionHistoryLoading,\n useSessionHandle,\n useSessionState,\n} from \"./runtime/session-source\"\nimport { SessionReplayBar } from \"./SessionReplayBar\"\n\n/**\n * 队列条目上移 / 下移后的完整 pending 顺序;越界或条目不在 pending 里返回 null。\n *\n * 服务端要求 `ordered_ids` 是当前 pending 条目的完整集合(顺序任意),所以这里\n * 始终提交全量,而不是只报移动的那一条;`delivering` 条目固定位置、不参与。\n */\nexport function nextQueuedOrder(\n items: QueuedMessage[],\n itemId: string,\n delta: -1 | 1,\n): string[] | null {\n const pending = items.filter((item) => item.status === \"pending\")\n const index = pending.findIndex((item) => item.id === itemId)\n const target = index + delta\n if (index < 0 || target < 0 || target >= pending.length) return null\n const ordered = [...pending]\n const [moved] = ordered.splice(index, 1)\n ordered.splice(target, 0, moved)\n return ordered.map((item) => item.id)\n}\n\nexport interface ChatPanelProps extends ChatViewCustomization {\n sessionId: string\n /** 配色主题;宿主已经在祖先元素上写了 data-theme 时不用传。 */\n theme?: \"light\" | \"dark\"\n /** 下一条消息的模式与切换(内置 Web 由会话 store 管);不传时用会话自己的模式、不给切换。 */\n mode?: \"planning\" | \"executing\"\n onToggleMode?: () => void\n /** 连接状态条下方的横幅(插件选择、回放冲突提示等)。 */\n banner?: ReactNode\n /** 消息列表上方 / 输入框下方的自定义区域,无消息时的空状态。 */\n header?: ReactNode\n footer?: ReactNode\n emptyState?: ReactNode\n /**\n * 回放条的「退出回放」。SDK 外壳用 `useReplay` 接管了「输入对不上录制内容」的决定,退出要先了结\n * 待定的那次决定,所以由它传入;不传时回放条直接退出回放。\n */\n onExitReplay?: () => void\n /** 额外的出错说明(例如 SDK 外壳的连接失败),显示在出错条里。 */\n errorMessage?: string | null\n placeholder?: string\n onFollowupInteraction?: (event: FollowupInteractionEvent) => void\n renderAttachments?: () => ReactNode\n onBeforeSend?: (content: MessageContent) => MessageContent | Promise<MessageContent>\n onCommand?: (commandId: string) => void | Promise<void>\n /** 宿主是否接住了「创建后台任务」;见输入框上的说明。 */\n canCreateBoardTask?: boolean\n canShareSession?: boolean\n /** 打开技能页;由宿主导航。 */\n onOpenSkills?: () => void\n inputLabel?: string\n onDoubleEscape?: (anchorRect: DOMRect | null) => void\n composerHint?: ReactNode\n composerBanner?: ReactNode\n scrollToStartKey?: string | null\n scrollToEntryKey?: string | null\n initialDraft?: string\n initialDraftKey?: string\n renderMode?: ChatRenderMode\n /**\n * 开发者视图专用的输入框底部统计插槽。宿主(内置 Web 页面)注入;普通与精简视图不会调用它,\n * 因此也不会发出统计请求。\n */\n renderComposerStats?: (sessionId: string) => ReactNode\n}\n\n/**\n * 聊天面板:消息流 + 队列 + 输入框。数据只来自 SessionSourceProvider 提供的会话实例与 props;\n * 内置 Web、浏览器插件与 SDK 的 ChatView / `<blade-chat>` 渲染的都是它。\n */\nexport function ChatPanel({\n sessionId,\n theme,\n mode: providedMode,\n onToggleMode,\n banner,\n header,\n footer,\n emptyState,\n errorMessage: externalError,\n onExitReplay,\n placeholder,\n onFollowupInteraction,\n renderAttachments,\n onBeforeSend,\n onCommand,\n canCreateBoardTask,\n canShareSession = false,\n onOpenSkills,\n inputLabel,\n onDoubleEscape,\n composerHint,\n composerBanner,\n scrollToStartKey,\n scrollToEntryKey,\n initialDraft,\n initialDraftKey,\n renderMode: requestedRenderMode,\n renderComposerStats,\n classNames,\n components,\n renderers,\n}: ChatPanelProps) {\n const client = useBladeClient()\n const environment = useChatEnvironment()\n const globalRenderMode = useChatRenderMode()\n const requested = requestedRenderMode ?? globalRenderMode\n const renderMode: ChatRenderMode =\n requested === \"lite\" && !environment.useVirtualizer\n ? \"normal\"\n : requested === \"developer\" && !environment.DeveloperMessageList\n ? \"normal\"\n : requested\n const lite = renderMode === \"lite\"\n const developer = renderMode === \"developer\"\n const scopedEnvironment = useMemo(() => ({ ...environment, renderMode }), [environment, renderMode])\n const DeveloperMessageList = environment.DeveloperMessageList\n const agentSession = useSessionHandle(sessionId)\n const messages = useSessionState(sessionId, (state) => state.messages)\n const isStreaming = useSessionState(sessionId, (state) => state.isStreaming)\n const queue = useSessionState(sessionId, (state) => state.queue)\n const turns = useSessionState(sessionId, (state) => state.turns)\n const stateMode = useSessionState(sessionId, (state) => state.mode)\n const connection = useSessionState(sessionId, (state) => state.connection)\n const stateStatus = useSessionState(sessionId, (state) => state.status)\n const viewerRole = useSessionState(sessionId, (state) => state.viewerRole)\n const stateError = useSessionState(sessionId, (state) => state.errorMessage)\n const nextBefore = useSessionState(sessionId, (state) => state.nextBefore)\n const historyLoadingOlder = useSessionState(sessionId, (state) => state.loadingOlder)\n const historyLoadRevision = useSessionState(sessionId, (state) => state.historyRevision)\n const historyRewriteRevision = useSessionState(sessionId, (state) => state.timelineRevision)\n const activeCompaction = useSessionState(sessionId, (state) => state.activeCompaction)\n const compactionPending = useSessionState(sessionId, (state) => state.compactionPending)\n const {\n isStopping,\n send,\n stop,\n queueNotice,\n pendingQueueItemId,\n queueMessage,\n updateQueuedMessage,\n reorderQueuedMessages,\n cancelQueuedMessage,\n deliverQueuedMessage,\n resumeQueue,\n } = useChatActions(sessionId)\n const [isRevealing, setIsRevealing] = useState(false)\n const isStreamingDisplay = isStreaming || isRevealing\n const detail = useChatSessionDetail(sessionId)\n const { isReplay } = useSessionReplay(sessionId)\n const isLoadingHistory = useIsSessionHistoryLoading(sessionId)\n const [queuePanelVisible, setQueuePanelVisible] = useState(false)\n const loadOlder = useCallback(\n async (beforeCommit?: () => void) => {\n if (!agentSession) return false\n const before = agentSession.getState().nextBefore\n await agentSession.loadOlderHistory({ beforeCommit })\n return agentSession.getState().nextBefore !== before\n },\n [agentSession],\n )\n const [paginationActivation, setPaginationActivation] = useState(() => ({\n sessionId,\n activated: Boolean(nextBefore),\n }))\n useEffect(() => {\n setPaginationActivation((current) => {\n if (current.sessionId !== sessionId) {\n return { sessionId, activated: Boolean(nextBefore) }\n }\n if (!current.activated && nextBefore) {\n return { sessionId, activated: true }\n }\n return current\n })\n }, [nextBefore, sessionId])\n const onLoadOlder =\n paginationActivation.sessionId === sessionId && paginationActivation.activated\n ? loadOlder\n : undefined\n const mode = providedMode ?? stateMode ?? \"executing\"\n const sessionStatus = stateStatus ?? detail?.status\n const isViewer = (viewerRole ?? detail?.viewer_role) === \"viewer\"\n const isCompacting = activeCompaction != null || compactionPending\n const postChatFollowup = useMemo(() => latestPostChatFollowup(turns), [turns])\n const [resultFeedback, setResultFeedback] = useState<ResultFeedback[]>([])\n useEffect(() => {\n setResultFeedback([])\n if (isViewer || !sessionId) return\n let cancelled = false\n void client.sessions.listResultFeedback(sessionId).then(\n (items) => {\n if (cancelled) return\n setResultFeedback((current) => {\n const merged = new Map(items.map((item) => [item.assistant_entry_id, item]))\n for (const item of current) {\n const fetched = merged.get(item.assistant_entry_id)\n if (!fetched || fetched.updated_at < item.updated_at) {\n merged.set(item.assistant_entry_id, item)\n }\n }\n return [...merged.values()]\n })\n },\n () => {},\n )\n return () => {\n cancelled = true\n }\n }, [client, isViewer, sessionId])\n const resultFeedbackByEntry = useMemo(\n () => new Map(resultFeedback.map((item) => [item.assistant_entry_id, item])),\n [resultFeedback],\n )\n const handleResultFeedbackSaved = useCallback((saved: ResultFeedback) => {\n setResultFeedback((current) => [\n ...current.filter((item) => item.assistant_entry_id !== saved.assistant_entry_id),\n saved,\n ])\n }, [])\n const sendUserMessage = useCallback(\n (\n message: MessageContent,\n targetMode: string,\n answerData?: Record<string, unknown>,\n options?: ChatSendOptions,\n ) => {\n return send(message, targetMode, answerData, {\n model: options?.model || undefined,\n thinkingOverride: options?.thinkingOverride,\n reasoningLevel: options?.reasoningLevel,\n refs: options?.refs,\n contextAttachments: options?.contextAttachments,\n topicAssetRefs: options?.topicAssetRefs,\n queueWhenRunning: options?.queueWhenRunning,\n })\n },\n [send],\n )\n const onConfirmPlan = useCallback(\n (action: \"execute\" | \"revise\", text?: string) => {\n if (action === \"execute\") {\n void sendUserMessage(\"计划已确认,开始执行\", \"executing\")\n } else if (text) {\n void sendUserMessage(text, \"planning\")\n }\n },\n [sendUserMessage],\n )\n const sendNewUserMessage = useCallback(\n (message: MessageContent, options?: ChatSendOptions) =>\n sendUserMessage(message, mode, undefined, options),\n [mode, sendUserMessage],\n )\n const answerQuestion = useCallback(\n (msg: string, toolCallId: string, answerData: AskUserAnswerData) => {\n void sendUserMessage(msg, mode, {\n tool_call_id: toolCallId,\n ...answerData,\n })\n },\n [mode, sendUserMessage],\n )\n const moveQueuedMessage = useCallback(\n (item: QueuedMessage, delta: -1 | 1) => {\n const ordered = nextQueuedOrder(queue.items, item.id, delta)\n if (!ordered) return\n void reorderQueuedMessages(queue.revision, ordered)\n },\n [queue, reorderQueuedMessages],\n )\n const composer = useComposerBridge(sessionId)\n const handleMcpAppMessage = useCallback(\n (message: { sessionId: string; label: string; content: string }) => {\n if (message.sessionId !== sessionId || isViewer) throw new Error(\"当前会话不能接收应用消息\")\n composer.addContext({ label: message.label, content: message.content })\n },\n [composer, isViewer, sessionId],\n )\n\n const customization = useMemo(\n () => ({ classNames, components, renderers }),\n [classNames, components, renderers],\n )\n const SkillStatus = components?.SkillStatusBar\n const Composer = components?.Composer ?? environment.Composer ?? LightComposer\n const errorMessage = externalError ?? stateError\n const composerProps: ComposerProps = {\n sessionId,\n onSend: sendNewUserMessage,\n onStop: stop,\n isStreaming: isStreamingDisplay || (!developer && isCompacting),\n queueWhileRunning: true,\n isCompacting,\n isStopping,\n mode,\n onToggleMode,\n renderAttachments,\n onBeforeSend,\n onCommand,\n canCreateBoardTask,\n canShareSession,\n planPanel: !lite ? (\n <CurrentPlanPanel sessionId={sessionId} className=\"border-b border-[hsl(var(--border))] px-4\" />\n ) : null,\n maxWidthClassName: cn(\"max-w-3xl\", classNames?.chatInputInner),\n mergesWithPanelAbove: queuePanelVisible && !composerBanner,\n className: classNames?.chatInputRoot,\n innerClassName: classNames?.chatInputInner,\n SkillStatusBarComponent: SkillStatus,\n skillStatusBarClassName: classNames?.skillStatusBarRoot,\n skillStatusBarInnerClassName: classNames?.skillStatusBarInner,\n onOpenSkills,\n inputLabel,\n placeholderText: placeholder,\n onDoubleEscape,\n composerHint,\n statusBarAddon: composerBanner,\n slotBelowActions: developer ? renderComposerStats?.(sessionId) : null,\n initialDraft,\n initialDraftKey,\n lite,\n }\n\n return (\n <ChatEnvironmentProvider value={scopedEnvironment}>\n <CurrentChatSessionProvider sessionId={sessionId || null}>\n <ChatCustomizationProvider value={customization}>\n <FollowupInteractionProvider value={onFollowupInteraction}>\n <McpAppMessageContext.Provider value={handleMcpAppMessage}>\n <div\n data-theme={theme}\n part=\"root\"\n className={cn(\"blade-chat flex min-h-0 flex-1 flex-col overflow-hidden\", classNames?.root)}\n >\n {isViewer && (\n <div\n className={cn(\n \"flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))]\",\n classNames?.viewerBanner,\n )}\n >\n <Eye size={14} />\n 你正在查看分享的会话(只读)\n </div>\n )}\n {!isViewer && <ConnectionBanner connection={connection} />}\n {banner}\n <SessionReplayBar sessionId={sessionId} onExit={onExitReplay} />\n {errorMessage && (\n <div\n part=\"error-bar\"\n className=\"blade-chat-error-bar flex items-start gap-2 border-b border-[hsl(var(--swf-danger)/0.3)] bg-[hsl(var(--swf-danger-soft))] px-4 py-3 text-sm text-[hsl(var(--swf-danger))]\"\n >\n <CircleAlert size={16} className=\"mt-0.5 shrink-0\" />\n <span className=\"min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]\">\n {chatErrorForDisplay(errorMessage, developer)}\n </span>\n </div>\n )}\n {header}\n {developer && DeveloperMessageList ? (\n <DeveloperMessageList\n key={sessionId}\n sessionId={sessionId}\n turns={turns}\n isViewer={isViewer}\n isLoadingHistory={isLoadingHistory}\n onLoadOlder={onLoadOlder}\n isLoadingOlder={historyLoadingOlder}\n historyLoadRevision={historyLoadRevision}\n isStreaming={isStreaming}\n sessionStatus={sessionStatus ?? undefined}\n postChatFollowup={postChatFollowup}\n resultFeedbackByEntry={resultFeedbackByEntry}\n onResultFeedbackSaved={handleResultFeedbackSaved}\n onAnswer={isViewer ? undefined : (msg, toolCallId, answerData) =>\n void send(msg, mode, { tool_call_id: toolCallId, ...answerData })}\n isStopping={isStopping}\n onRevealingChange={setIsRevealing}\n isReplay={isReplay}\n />\n ) : lite ? (\n <LiteMessageList\n key={sessionId}\n sessionId={sessionId}\n messages={messages}\n followup={postChatFollowup}\n isViewer={isViewer}\n isLoadingHistory={isLoadingHistory}\n onLoadOlder={onLoadOlder}\n historyLoadRevision={historyLoadRevision}\n isStreaming={isStreaming}\n sessionStatus={sessionStatus ?? undefined}\n resultFeedbackByEntry={resultFeedbackByEntry}\n onResultFeedbackSaved={handleResultFeedbackSaved}\n onAnswer={isViewer ? undefined : answerQuestion}\n />\n ) : (\n <FullMessageList\n key={sessionId}\n sessionId={sessionId}\n messages={messages}\n onAnswer={isViewer ? undefined : answerQuestion}\n sessionStatus={sessionStatus ?? undefined}\n onConfirmPlan={isViewer ? undefined : onConfirmPlan}\n customization={customization}\n emptyState={emptyState}\n scrollToStartKey={scrollToStartKey}\n scrollToEntryKey={scrollToEntryKey}\n postChatFollowup={postChatFollowup}\n resultFeedbackByEntry={resultFeedbackByEntry}\n onResultFeedbackSaved={handleResultFeedbackSaved}\n isViewer={isViewer}\n isLoadingHistory={isLoadingHistory}\n onLoadOlder={onLoadOlder}\n historyLoadRevision={historyLoadRevision}\n historyRewriteRevision={historyRewriteRevision}\n isStopping={isStopping}\n onRevealingChange={setIsRevealing}\n isReplay={isReplay}\n />\n )}\n {isViewer && !lite ? (\n <CurrentPlanPanel\n sessionId={sessionId}\n className={cn(\"mx-auto w-full max-w-3xl px-5 pb-3\", classNames?.chatInputInner)}\n />\n ) : null}\n {!isViewer && (\n <>\n <SessionQueuePanel\n key={sessionId}\n snapshot={queue}\n canDeliver={isStreaming}\n pendingItemId={pendingQueueItemId}\n notice={queueNotice}\n onResume={() => void resumeQueue()}\n onCancel={(item) => void cancelQueuedMessage(item.id, item.version)}\n onEdit={(item, content) => updateQueuedMessage(item.id, item.version, content)}\n onRequeue={queueMessage}\n onMove={moveQueuedMessage}\n onReorder={(orderedIds) => void reorderQueuedMessages(queue.revision, orderedIds)}\n onDeliver={(item) => void deliverQueuedMessage(item.id, item.version)}\n mergesWithInputBelow={!composerBanner}\n contentWidthClassName={cn(\"max-w-3xl\", classNames?.chatInputInner)}\n rootClassName={classNames?.queuePanelRoot}\n onVisibleChange={setQueuePanelVisible}\n />\n <Composer {...composerProps} />\n </>\n )}\n {footer}\n </div>\n </McpAppMessageContext.Provider>\n </FollowupInteractionProvider>\n </ChatCustomizationProvider>\n </CurrentChatSessionProvider>\n </ChatEnvironmentProvider>\n )\n}\n","import {\n canCancelQueuedMessage,\n canDeliverQueuedMessage,\n canEditQueuedMessage,\n type QueuedMessage,\n queuePauseReasonLabel,\n queuedMessageStatusLabel,\n type SessionQueueSnapshot,\n} from \"@blade-hq/agent-client/internal\"\nimport { ChevronDown, CircleAlert, Loader2, Menu, PauseCircle, Pencil, Send, Trash2 } from \"lucide-react\"\nimport { useContext, useLayoutEffect, useRef, useState, type JSX } from \"react\"\nimport { cn } from \"../lib/utils\"\nimport { QueuePanelAdjacencyContext } from \"./queue-panel-adjacency\"\n\nexport interface SessionQueuePanelProps {\n snapshot: SessionQueueSnapshot\n /** 当前是否有可接收补充的运行任务(决定「立刻发送」是否可用) */\n canDeliver: boolean\n /** 正在等服务端确认的条目 id:禁用该条目的操作,避免重复提交 */\n pendingItemId?: string | null\n /** 冲突/失败提示,例如「该消息已开始执行」;展示在面板顶部 */\n notice?: string | null\n onResume: () => void\n onCancel: (item: QueuedMessage) => void\n onEdit: (item: QueuedMessage, content: string) => boolean | undefined | Promise<boolean>\n onRequeue?: (content: string) => Promise<boolean>\n onMove: (item: QueuedMessage, delta: -1 | 1) => void\n onReorder: (orderedIds: string[]) => void\n onDeliver: (item: QueuedMessage) => void\n /**\n * 队列内容与外层留白的宽度类,要和下面输入框用同一个值。\n *\n * 队列卡片是\"比输入框窄一圈、露在它上方\"的形态,所以这里的宽度必须跟着\n * 输入框走:输入框宽度由调用方决定(内置 Web 默认 max-w-3xl,软件工厂用\n * `max-w-[748px]!` 覆盖,SDK 侧是 max-w-[748px])。写死一个值的话,两种\n * 布局里总有一种对不齐——之前写死 max-w-[748px] 且外层 px-4,而输入框\n * 外层是 px-5,软件工厂恰好都是 748 看着还行,普通聊天里输入框是 768,\n * 队列连缩进一起窄了 22px。\n */\n contentWidthClassName?: string\n /** 根节点附加类。宿主用它在根上重设 `--blade-chat-queue-gutter`(或别的变量)。 */\n rootClassName?: string\n /**\n * 面板占位状态变化时回调(true = 正在占位)。\n *\n * 面板有本地 `editing` 状态:用户编辑到一半、那条等待消息被服务端拿走后,\n * 面板仍要留在原地保住没保存的正文(见 `detachedEdit`)。这时 `items` 是空的,\n * 光凭 snapshot 判不出面板还在,宿主就会把输入框上两角恢复成圆角、接缝上露出\n * 尖角。让面板自己上报,宿主不必也无法复刻这个判据。\n */\n onVisibleChange?: (visible: boolean) => void\n /**\n * 面板是否真的紧贴下面的输入框。\n *\n * 中间夹着别的内容时(MCP 暂存内容、内置 Web 的 `composerBanner`)两者并不\n * 相接,这时面板下两角也要圆起来——直角是\"被下面的输入框接住\"的表示,露出\n * 直角却下面空着一块,看起来像被削掉一角。\n *\n * 不传时读 context(见 `QueuePanelAdjacencyContext`):面板通常由宿主创建、\n * 挂进 `ChatSurface`,而\"中间有没有内容\"是 `ChatSurface` 内部的 state,\n * 宿主拿不到。内置 Web 自己管布局,直接把值传进来即可。\n */\n mergesWithInputBelow?: boolean\n}\n\nconst QUEUE_INSET_CLASS = \"mx-3\"\n\n/**\n * 队列面板此刻会不会占位。\n *\n * 输入框要据此把自己的上两角改成直角:队列贴在它上方、而且比它窄一圈,\n * 输入框上角若还是 22px 圆弧,那两段弧会从队列两侧露出来,形成两个尖角。\n *\n * 抽成一个函数而不是两边各判一次,是为了让\"面板可见\"和\"输入框顶角改直角\"\n * 永远同步——这正是仓库里反复出现的\"改了一个入口漏了另一个\"。\n * 传入的 `editing` 是面板自己的本地编辑态,默认 false。\n */\nexport function isQueuePanelVisible(\n snapshot: Pick<SessionQueueSnapshot, \"items\" | \"paused\">,\n notice: string | null | undefined,\n editing = false,\n): boolean {\n return snapshot.items.length > 0 || snapshot.paused || Boolean(notice) || editing\n}\n\nconst DEFAULT_CONTENT_WIDTH_CLASS = \"max-w-[748px]\"\n\nconst ICON_BUTTON =\n \"flex h-6 w-6 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent\"\n\nconst LABEL_BUTTON =\n \"inline-flex h-6 items-center gap-1 rounded-md px-2 text-[11px] text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent\"\n\n/**\n * 会话消息队列面板:输入框上方的「待执行 · N」区域。\n *\n * 一行一条:左边三条横向的拖动手柄、中间单行截断的正文、右边 hover 才出现的操作\n * (立刻发送 / 编辑 / 删除)。顺序靠拖动整行调整,手柄上也能用 Alt+↑/↓ 调(键盘\n * 可达性不能因为去掉上下箭头按钮就没了)。\n *\n * 纯展示组件,不持有会话状态;能否编辑/删除/补充全部用 agent-client 的判定函数,\n * 不在本包重写一份。拖动与键盘调整最终都由调用方提交完整的 pending id 顺序。\n */\nexport function SessionQueuePanel({\n snapshot,\n canDeliver,\n pendingItemId = null,\n notice = null,\n onResume,\n onCancel,\n onEdit,\n onRequeue,\n onMove,\n onReorder,\n onDeliver,\n contentWidthClassName = DEFAULT_CONTENT_WIDTH_CLASS,\n rootClassName,\n onVisibleChange,\n mergesWithInputBelow: mergesWithInputBelowProp,\n}: SessionQueuePanelProps): JSX.Element | null {\n const [collapsed, setCollapsed] = useState(false)\n const [editing, setEditing] = useState<{ id: string; version: number; text: string } | null>(null)\n const [draggingId, setDraggingId] = useState<string | null>(null)\n const [dropAt, setDropAt] = useState<{ id: string; edge: \"before\" | \"after\" } | null>(null)\n // 拖动的来源用 ref 存一份:落点判定不能依赖「dragstart 的 setState 已经重渲染过」,\n // 同一个任务里连着发 dragstart/drop(真实浏览器里也够快)时 state 还是旧值。\n const draggingRef = useRef<string | null>(null)\n const dropRef = useRef<{ id: string; edge: \"before\" | \"after\" } | null>(null)\n const requeuePending = useRef(false)\n const [requeueing, setRequeueing] = useState(false)\n\n const adjacency = useContext(QueuePanelAdjacencyContext)\n const mergesWithInputBelow = mergesWithInputBelowProp ?? adjacency ?? true\n const items = snapshot.items\n const visible = isQueuePanelVisible(snapshot, notice, Boolean(editing))\n const onVisibleChangeRef = useRef(onVisibleChange)\n onVisibleChangeRef.current = onVisibleChange\n useLayoutEffect(() => {\n onVisibleChangeRef.current?.(visible)\n return () => onVisibleChangeRef.current?.(false)\n }, [visible])\n if (!visible) return null\n\n const pendingIds = items.filter(canEditQueuedMessage).map((item) => item.id)\n const collapsible = items.length > 3\n const visibleItems = collapsible && collapsed ? items.slice(0, 1) : items\n const pauseLabel = queuePauseReasonLabel(snapshot.pause_reason) ?? \"已暂停\"\n const activeEdit =\n editing &&\n (() => {\n const current = items.find((entry) => entry.id === editing.id)\n if (!current || current.status !== \"pending\" || current.version !== editing.version) {\n return null\n }\n return editing\n })()\n const detachedEdit = editing && !activeEdit ? editing : null\n\n const startEdit = (item: QueuedMessage) => {\n setEditing({ id: item.id, version: item.version, text: item.content })\n }\n\n const stopEdit = () => setEditing(null)\n\n const commitEdit = async (item: QueuedMessage) => {\n const content = editing?.text.trim() ?? \"\"\n if (!content) return\n const submitted = editing\n if (await onEdit(item, content)) {\n setEditing((current) => (current === submitted ? null : current))\n }\n }\n\n const handleDrop = (targetId: string, edge: \"before\" | \"after\") => {\n const sourceId = draggingRef.current\n draggingRef.current = null\n dropRef.current = null\n setDraggingId(null)\n setDropAt(null)\n if (!sourceId || sourceId === targetId) return\n const from = pendingIds.indexOf(sourceId)\n const to = pendingIds.indexOf(targetId)\n if (from < 0 || to < 0) return\n const next = [...pendingIds]\n next.splice(from, 1)\n const target = next.indexOf(targetId)\n next.splice(edge === \"after\" ? target + 1 : target, 0, sourceId)\n onReorder(next)\n }\n\n return (\n <section part=\"queue\" className={cn(\"blade-chat-queue shrink-0 pt-2\", rootClassName)} aria-label=\"待执行消息\">\n <div className={cn(\"mx-auto\", contentWidthClassName)}>\n {snapshot.paused || collapsible ? (\n <div className=\"flex items-center gap-2 px-0.5 text-[11px] text-[hsl(var(--muted-foreground))]\">\n <span className=\"font-medium\">待执行 · {items.length}</span>\n {snapshot.paused && (\n <>\n <span className=\"inline-flex items-center gap-1 text-[hsl(var(--destructive))]\">\n <PauseCircle size={12} />\n {pauseLabel}\n </span>\n <button\n type=\"button\"\n onClick={onResume}\n className=\"h-6 rounded-md border border-[hsl(var(--border))] px-2 font-medium text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]\"\n >\n 继续执行\n </button>\n </>\n )}\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => setCollapsed((value) => !value)}\n aria-expanded={!collapsed}\n className=\"ml-auto inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n {collapsed ? \"展开\" : \"折叠\"}\n <ChevronDown size={12} className={cn(!collapsed && \"rotate-180\")} />\n </button>\n )}\n </div>\n ) : null}\n {notice && (\n <div className=\"blade-chat-queue-notice mt-2 flex items-start gap-1.5 text-xs text-[hsl(var(--destructive))]\">\n <CircleAlert size={13} className=\"mt-0.5 shrink-0\" />\n <span className=\"min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]\">{notice}</span>\n </div>\n )}\n {detachedEdit && (\n <div className=\"mt-2 flex flex-col gap-2 text-xs\">\n <span>原消息已变化,修改内容已保留</span>\n <textarea\n aria-label=\"保留的修改内容\"\n value={detachedEdit.text}\n onChange={(event) => setEditing((current) => current ? { ...current, text: event.target.value } : current)}\n rows={2}\n className=\"w-full rounded border border-[hsl(var(--border))] bg-transparent p-2\"\n />\n <div className=\"flex justify-end gap-2\">\n <button type=\"button\" className=\"rounded border border-[hsl(var(--border))] px-2 py-1\" disabled={requeueing} onClick={stopEdit}>放弃修改</button>\n {onRequeue && <button type=\"button\" className=\"rounded bg-[hsl(var(--primary))] px-2 py-1 text-[hsl(var(--primary-foreground))] disabled:opacity-40\" disabled={requeueing || !detachedEdit.text.trim()} onClick={async () => {\n if (requeuePending.current) return\n requeuePending.current = true\n setRequeueing(true)\n const submitted = editing\n try {\n if (await onRequeue(detachedEdit.text.trim())) {\n setEditing((current) => current === submitted ? null : current)\n }\n } finally {\n requeuePending.current = false\n setRequeueing(false)\n }\n }}>作为排队消息发送</button>}\n </div>\n </div>\n )}\n <ul\n className={cn(\n QUEUE_INSET_CLASS,\n \"flex max-h-56 flex-col overflow-y-auto rounded-t-[22px] border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-1.5 py-1.5\",\n !mergesWithInputBelow && \"rounded-b-[22px]\",\n )}\n >\n {visibleItems.map((item) => {\n const position = items.indexOf(item) + 1\n const pending = canEditQueuedMessage(item)\n const busy = pendingItemId === item.id\n const isEditing = activeEdit?.id === item.id\n const pendingIndex = pendingIds.indexOf(item.id)\n const statusLabel = item.status === \"pending\" ? null : queuedMessageStatusLabel(item.status)\n const deliverable = canDeliver && canDeliverQueuedMessage(item)\n return (\n <li\n key={item.id}\n draggable={pending && !busy && !isEditing}\n onDragStart={(event) => {\n draggingRef.current = item.id\n setDraggingId(item.id)\n const text = event.currentTarget.querySelector(\"[data-queue-text]\")\n if (text && event.dataTransfer) {\n const rect = text.getBoundingClientRect()\n event.dataTransfer.setDragImage(\n text,\n event.clientX - rect.left,\n event.clientY - rect.top,\n )\n }\n }}\n onDragEnd={() => {\n draggingRef.current = null\n dropRef.current = null\n setDraggingId(null)\n setDropAt(null)\n }}\n onDragOver={(event) => {\n if (!pending) return\n event.preventDefault()\n if (!draggingRef.current || draggingRef.current === item.id) return\n const rect = event.currentTarget.getBoundingClientRect()\n const edge = event.clientY > rect.top + rect.height / 2 ? \"after\" : \"before\"\n dropRef.current = { id: item.id, edge }\n setDropAt((current) =>\n current?.id === item.id && current.edge === edge ? current : { id: item.id, edge },\n )\n }}\n onDragLeave={() => {\n if (dropRef.current?.id === item.id) dropRef.current = null\n setDropAt((current) => (current?.id === item.id ? null : current))\n }}\n onDrop={(event) => {\n event.preventDefault()\n const landed = dropRef.current\n if (pending) handleDrop(item.id, landed?.id === item.id ? landed.edge : \"before\")\n }}\n className={cn(\n \"blade-chat-queue-item group relative flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[11px]\",\n pending && !isEditing && \"cursor-grab active:cursor-grabbing\",\n busy && \"opacity-60\",\n draggingId === item.id && \"opacity-40\",\n )}\n >\n {isEditing ? (\n <div className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <textarea\n value={activeEdit?.text ?? \"\"}\n onChange={(event) =>\n setEditing((current) =>\n current ? { ...current, text: event.target.value } : current,\n )\n }\n rows={2}\n aria-label={`编辑第 ${position} 条消息`}\n className=\"w-full resize-none rounded-md border border-[hsl(var(--border))] bg-transparent px-2 py-1.5 text-sm leading-5 text-[hsl(var(--foreground))] outline-none\"\n />\n <div className=\"flex justify-end gap-1.5\">\n <button\n type=\"button\"\n onClick={stopEdit}\n className=\"h-7 rounded-md border border-[hsl(var(--border))] px-2 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n 取消\n </button>\n <button\n type=\"button\"\n onClick={() => commitEdit(item)}\n disabled={busy || !activeEdit?.text.trim()}\n className=\"h-7 rounded-md bg-[hsl(var(--primary))] px-2 text-xs font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:opacity-40\"\n >\n 保存\n </button>\n </div>\n </div>\n ) : (\n <>\n {dropAt?.id === item.id ? (\n <span\n aria-hidden=\"true\"\n style={{ background: \"var(--resize-line-hover, hsl(var(--foreground) / 0.55))\" }}\n className={cn(\n \"pointer-events-none absolute inset-x-1 h-[2px] rounded-full\",\n dropAt.edge === \"before\" ? \"top-0\" : \"bottom-0\",\n )}\n />\n ) : null}\n <button\n type=\"button\"\n disabled={!pending || busy}\n aria-label={`调整第 ${position} 条的顺序(拖动,或按 Alt+上/下)`}\n title=\"拖动调整顺序(Alt+上/下 也行)\"\n onKeyDown={(event) => {\n if (!event.altKey) return\n if (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return\n event.preventDefault()\n const delta = event.key === \"ArrowUp\" ? -1 : 1\n if (pendingIndex < 0) return\n if (delta < 0 && pendingIndex === 0) return\n if (delta > 0 && pendingIndex === pendingIds.length - 1) return\n onMove(item, delta)\n }}\n className=\"-ml-0.5 flex h-5 w-4 shrink-0 cursor-grab items-center justify-center rounded text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] active:cursor-grabbing disabled:cursor-default disabled:opacity-60 disabled:hover:bg-transparent\"\n >\n <Menu size={14} aria-hidden=\"true\" />\n </button>\n <span\n data-queue-text\n className=\"min-w-0 flex-1 truncate pt-px text-[hsl(var(--foreground))]\"\n >\n {item.content}\n </span>\n {item.error ? (\n <span className=\"shrink-0 pt-1 text-[11px] text-[hsl(var(--destructive))]\">{item.error}</span>\n ) : busy ? (\n <span className=\"mt-0.5 inline-flex shrink-0 items-center gap-1 text-[11px] text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={11} className=\"animate-spin\" />\n 处理中\n </span>\n ) : statusLabel ? (\n <span className=\"shrink-0 pt-1 text-[11px] text-[hsl(var(--muted-foreground))]\">{statusLabel}</span>\n ) : null}\n <div className=\"flex shrink-0 items-center gap-0.5 opacity-0 [@media(hover:none)]:opacity-100 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100\">\n <button\n type=\"button\"\n aria-label={`立刻发送第 ${position} 条`}\n title={deliverable ? \"发送引导消息\" : \"当前没有可接收补充的任务\"}\n disabled={busy || !deliverable}\n onClick={() => onDeliver(item)}\n className={LABEL_BUTTON}\n >\n <Send size={13} aria-hidden=\"true\" />\n 立刻发送\n </button>\n <button\n type=\"button\"\n aria-label={`编辑第 ${position} 条`}\n title=\"编辑\"\n disabled={busy || !pending}\n onClick={() => startEdit(item)}\n className={ICON_BUTTON}\n >\n <Pencil size={13} aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n aria-label={`删除第 ${position} 条`}\n title=\"删除\"\n disabled={busy || !canCancelQueuedMessage(item)}\n onClick={() => onCancel(item)}\n className={ICON_BUTTON}\n >\n <Trash2 size={13} aria-hidden=\"true\" />\n </button>\n </div>\n </>\n )}\n </li>\n )\n })}\n </ul>\n </div>\n </section>\n )\n}\n","import { createContext } from \"react\"\n\nexport const QueuePanelAdjacencyContext = createContext<boolean | null>(null)\n","import type { ConnectionStatus } from \"@blade-hq/agent-client/internal\"\nimport { AlertTriangle, LoaderCircle } from \"lucide-react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\nconst CONNECTION_NOTICE_DELAY_MS = 3_000\nconst CONNECTION_ERROR_DELAY_MS = 15_000\n\ntype ConnectionNoticePhase = \"hidden\" | \"recovering\" | \"failed\"\n\nfunction useConnectionNoticePhase(connected: boolean): ConnectionNoticePhase {\n const [phase, setPhase] = useState<ConnectionNoticePhase>(\"hidden\")\n const connectedRef = useRef(connected)\n const timersRef = useRef<ReturnType<typeof setTimeout>[]>([])\n\n connectedRef.current = connected\n\n useEffect(() => {\n const clearTimers = () => {\n for (const timer of timersRef.current) clearTimeout(timer)\n timersRef.current = []\n }\n const startGracePeriod = () => {\n clearTimers()\n setPhase(\"hidden\")\n timersRef.current = [\n setTimeout(() => setPhase(\"recovering\"), CONNECTION_NOTICE_DELAY_MS),\n setTimeout(() => setPhase(\"failed\"), CONNECTION_ERROR_DELAY_MS),\n ]\n }\n\n if (connected) {\n clearTimers()\n setPhase(\"hidden\")\n } else {\n startGracePeriod()\n }\n\n const handleForeground = () => {\n if (!connectedRef.current) startGracePeriod()\n }\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"visible\") handleForeground()\n }\n\n window.addEventListener(\"blade:app-active\", handleForeground)\n window.addEventListener(\"focus\", handleForeground)\n window.addEventListener(\"pageshow\", handleForeground)\n document.addEventListener(\"visibilitychange\", handleVisibilityChange)\n return () => {\n clearTimers()\n window.removeEventListener(\"blade:app-active\", handleForeground)\n window.removeEventListener(\"focus\", handleForeground)\n window.removeEventListener(\"pageshow\", handleForeground)\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange)\n }\n }, [connected])\n\n return phase\n}\n\nfunction getBannerCopy(phase: Exclude<ConnectionNoticePhase, \"hidden\">, hasEverConnected: boolean) {\n if (phase === \"recovering\") {\n return {\n icon: <LoaderCircle size={14} className=\"animate-spin\" />,\n toneClass:\n \"border-[hsl(var(--swf-warning)/0.25)] bg-[hsl(var(--swf-warning-soft))] text-[hsl(var(--swf-warning))]\",\n title: hasEverConnected ? \"正在恢复连接…\" : \"正在连接…\",\n detail: \"恢复后会自动同步最新消息,请稍候\",\n }\n }\n\n return {\n icon: <AlertTriangle size={14} />,\n toneClass:\n \"border-[hsl(var(--swf-danger)/0.25)] bg-[hsl(var(--swf-danger-soft))] text-[hsl(var(--swf-danger))]\",\n title: hasEverConnected ? \"暂时无法恢复连接\" : \"暂时无法连接\",\n detail: \"请检查网络或服务状态,系统会继续自动重试\",\n }\n}\n\n/**\n * 连接状态提示:短暂断线不打扰(3 秒容错),恢复不了再提示。`hasEverConnected` 不传时按本组件\n * 挂载以来是否连上过判断(决定文案是「无法恢复」还是「无法连接」)。\n */\nexport function ConnectionBanner({\n connection,\n hasEverConnected: hasEverConnectedProp,\n className,\n}: {\n connection: ConnectionStatus\n hasEverConnected?: boolean\n className?: string\n}) {\n const status = connection\n const everConnectedRef = useRef(false)\n if (status === \"connected\") everConnectedRef.current = true\n const hasEverConnected = hasEverConnectedProp ?? everConnectedRef.current\n const connected = status === \"connected\"\n const phase = useConnectionNoticePhase(connected)\n\n if (connected || phase === \"hidden\") return null\n\n const copy = getBannerCopy(phase, hasEverConnected)\n\n return (\n <div part=\"banner\" className={cn(\"blade-chat-banner bg-[hsl(var(--background))] px-5 pt-3\", className)}>\n <div\n className={cn(\n \"mx-auto flex max-w-3xl items-start gap-3 rounded-2xl border px-4 py-3\",\n copy.toneClass,\n )}\n >\n <span className=\"mt-0.5 shrink-0\">{copy.icon}</span>\n <div className=\"min-w-0\">\n <div className=\"text-sm font-medium\">{copy.title}</div>\n <div className=\"text-xs opacity-80\">{copy.detail}</div>\n </div>\n </div>\n </div>\n )\n}\n","import { Loader2 } from \"lucide-react\"\nimport { useEffect, useMemo, useRef } from \"react\"\nimport type { ChatMessage } from \"@blade-hq/agent-client/internal\"\nimport { usePlanRevealRevision, useSessionState } from \"./runtime/session-source\"\nimport { useHideTodo } from \"./runtime/environment\"\nimport { getPlanUpdateDisplayState, parsePlanUpdate, PlanUpdateBlock } from \"../components/PlanUpdateBlock\"\nimport { cn } from \"../lib/utils\"\nimport { useChatCustomization } from \"./customization\"\n\nfunction PlanUpdatingNotice() {\n return (\n <div className=\"mb-2 flex items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={14} className=\"shrink-0 animate-spin\" />\n <span>正在更新任务进度…</span>\n </div>\n )\n}\n\nexport function CurrentPlanPanelContent({\n messages,\n running = false,\n autoReveal = false,\n sessionId,\n hideTodo = false,\n}: {\n messages: ChatMessage[]\n running?: boolean\n autoReveal?: boolean\n sessionId?: string\n hideTodo?: boolean\n}) {\n const { current, updating } = getPlanUpdateDisplayState(messages)\n\n if (hideTodo) return null\n if (!current && !updating) return null\n\n return (\n <>\n {updating ? <PlanUpdatingNotice /> : null}\n {current ? (\n <PlanUpdateBlock\n key={sessionId ?? \"current-session\"}\n toolCall={current}\n running={running}\n autoReveal={autoReveal}\n />\n ) : null}\n </>\n )\n}\n\nexport function CurrentPlanPanel({\n sessionId,\n className,\n}: {\n sessionId: string\n /**\n * Wrapper classes applied only when there is a plan to show, so callers can\n * add chrome (e.g. the composer's bottom divider) without leaving an empty\n * bordered strip behind when the session never called `update_plan`.\n */\n className?: string\n}) {\n const messages = useSessionState(sessionId, (state) => state.messages)\n const isStreaming = useSessionState(sessionId, (state) => state.isStreaming)\n const hideTodo = useHideTodo()\n const revealRevision = usePlanRevealRevision(sessionId)\n const { current, updating } = useMemo(() => getPlanUpdateDisplayState(messages), [messages])\n const hasPlanUpdate = current !== null || updating\n const revealBaselinesRef = useRef(new Map([[sessionId, revealRevision]]))\n if (!revealBaselinesRef.current.has(sessionId)) revealBaselinesRef.current.set(sessionId, revealRevision)\n const autoReveal = (revealBaselinesRef.current.get(sessionId) ?? 0) !== revealRevision\n useEffect(() => {\n if (!current) return\n revealBaselinesRef.current.set(sessionId, revealRevision)\n }, [current, revealRevision, sessionId])\n const renderPlan = useChatCustomization()?.renderers?.planUpdate\n const parsedPlan = useMemo(\n () => (renderPlan && current ? parsePlanUpdate(current.arguments) : null),\n [current, renderPlan],\n )\n const customPlan = parsedPlan ? renderPlan?.({ plan: parsedPlan, running: isStreaming, sessionId }) : null\n\n if (hideTodo || !hasPlanUpdate) return null\n if (customPlan != null) return <>{customPlan}</>\n\n return (\n <div part=\"plan\" className={cn(\"blade-chat-plan\", className)}>\n <CurrentPlanPanelContent\n messages={messages}\n running={isStreaming}\n autoReveal={autoReveal}\n sessionId={sessionId}\n hideTodo={hideTodo}\n />\n </div>\n )\n}\n","import { createContext, createElement, type ComponentType, type ReactNode, useContext } from \"react\"\nimport type { ChatMessage, MessageContent, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport type { ContentBlock } from \"@blade-hq/agent-client/internal\"\nimport type { AskUserAnswerData, AskUserQuestionData } from \"./AskUserQuestionBlock\"\nimport type { PlanUpdateData } from \"../components/PlanUpdateBlock\"\nimport type { ChatSendExtras } from \"./runtime/actions\"\nimport type { ErrorChatMessage, UserChatMessage } from \"./UserMessageBubble\"\n\nexport type ChatViewClassNames = Partial<{\n root: string\n viewerBanner: string\n messageListRoot: string\n messageListViewport: string\n messageListContent: string\n messageListInner: string\n emptyState: string\n userMessage: string\n errorMessage: string\n assistantTurn: string\n assistantText: string\n toolCall: string\n chatInputRoot: string\n chatInputInner: string\n /**\n * 队列面板根节点。软件工厂把输入框根节点的左右内边距改成了 px-10! / px-2!,\n * 面板必须跟着同一个值,否则两者相接的那条缝上会一边宽一边窄。在这里重设\n * `--blade-chat-queue-gutter` 即可(面板默认值对应 px-5)。\n */\n queuePanelRoot: string\n skillStatusBarRoot: string\n skillStatusBarInner: string\n}>\n\n/** 输入框提交时的附加项(模型、推理档位、知识库等由富输入给出)。 */\nexport interface ChatSendOptions\n extends Pick<ChatSendExtras, \"thinkingOverride\" | \"reasoningLevel\" | \"refs\" | \"contextAttachments\" | \"topicAssetRefs\" | \"queueWhenRunning\"> {\n /** 附件实际上传到的会话(首页新建会话时由输入框给出)。 */\n targetSessionId?: string\n /** 本条消息用的模型;null 表示沿用会话已保存的模型。 */\n model?: string | null\n}\n\n/**\n * 输入框(Composer)的 props 契约:聊天面板传给输入框的全部内容。\n * 轻输入(SDK 默认)只用其中一部分;富输入(`@blade-hq/agent-react/rich-input`)用全部。\n * 自定义实现只需取用其中关心的字段,其余忽略即可。\n */\nexport interface ComposerProps {\n /** 当前会话;轻输入据此接住 `AgentSession.insertText` / `attach`。 */\n sessionId?: string\n onSend: (message: MessageContent, options?: ChatSendOptions) => boolean | Promise<boolean>\n onStop: () => void | Promise<void>\n isStreaming: boolean\n /** 宿主是否渲染了队列面板;没有面板时不给\"运行中提交\"入口。 */\n queueWhileRunning?: boolean\n isCompacting?: boolean\n isStopping?: boolean\n mode?: \"planning\" | \"executing\"\n onToggleMode?: () => void\n renderAttachments?: () => ReactNode\n onBeforeSend?: (content: MessageContent) => MessageContent | Promise<MessageContent>\n onCommand?: (commandId: string) => void | Promise<void>\n canCreateBoardTask?: boolean\n canShareSession?: boolean\n /** 输入框顶部的任务进度面板(与输入框共用边框)。 */\n planPanel?: ReactNode\n /** 内层最大宽度的 Tailwind 类,默认 `max-w-3xl`。 */\n maxWidthClassName?: string\n /** 上方紧贴着队列面板时置 true:上两角改成直角。 */\n mergesWithPanelAbove?: boolean\n className?: string\n innerClassName?: string\n SkillStatusBarComponent?: ComponentType<SkillStatusBarComponentProps>\n skillStatusBarClassName?: string\n skillStatusBarInnerClassName?: string\n onOpenSkills?: () => void\n inputLabel?: string\n placeholderText?: string\n onDoubleEscape?: (anchorRect: DOMRect | null) => void\n composerHint?: ReactNode\n statusBarAddon?: ReactNode\n slotBelowActions?: ReactNode\n initialDraft?: string\n initialDraftKey?: string\n /** 精简附加控件(精简渲染模式)。 */\n lite?: boolean\n}\n\nexport interface ChatViewComponents {\n EmptyState?: ComponentType\n UserMessage?: ComponentType<{ message: UserChatMessage; className?: string }>\n ErrorMessage?: ComponentType<{ message: ErrorChatMessage; className?: string }>\n AssistantTurn?: ComponentType<AssistantTurnComponentProps>\n ToolCall?: ComponentType<ToolCallComponentProps>\n SkillStatusBar?: ComponentType<SkillStatusBarComponentProps>\n /** 自定义输入框;不传时使用默认的 ChatInput。 */\n Composer?: ComponentType<ComposerProps>\n}\n\n/** 工具调用渲染器:返回 null 走默认渲染。 */\nexport type ToolCallRenderer = (info: ToolCallInfo) => ReactNode | null\n\n/** 用户消息渲染器:`message` 是投影层给出的用户消息。 */\nexport interface UserMessageRendererProps {\n message: ChatMessage\n}\n\n/** 助手正文渲染器:`compact` 为真时正文在执行过程里,字号更小。 */\nexport interface AssistantTextRendererProps {\n message: ChatMessage\n streaming: boolean\n compact: boolean\n sessionId?: string\n}\n\n/** 提问卡渲染器:字段与 `AskUserQuestionBlock` 的 props 一致。 */\nexport interface AskUserQuestionRendererProps {\n data: AskUserQuestionData\n answered: boolean\n toolCallId: string\n sessionStatus: string\n answerData?: AskUserAnswerData\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n}\n\n/** 计划面板渲染器:`plan` 是最近一次成功的 update_plan 解析结果。 */\nexport interface PlanUpdateRendererProps {\n plan: PlanUpdateData\n running: boolean\n sessionId?: string\n}\n\n/**\n * 区块级渲染器:每个都返回 `ReactNode`,返回 `null` 走默认渲染。`tool` 按工具名替换工具卡的展开详情。\n */\nexport interface ChatViewRenderers {\n /** 按工具名替换展开后的详情(内置 Web 的专用工具渲染器用它)。 */\n tool?: Record<string, ComponentType<ToolRendererProps>>\n /** 自定义工具调用渲染;返回 null 走默认渲染。 */\n toolCall?: ToolCallRenderer\n /** 自定义用户消息渲染;返回 null 走默认渲染。 */\n userMessage?: (props: UserMessageRendererProps) => ReactNode | null\n /** 自定义助手正文渲染;返回 null 走默认渲染。 */\n assistantText?: (props: AssistantTextRendererProps) => ReactNode | null\n /** 自定义提问卡渲染;返回 null 走默认渲染。 */\n askUserQuestion?: (props: AskUserQuestionRendererProps) => ReactNode | null\n /** 自定义计划面板渲染;返回 null 走默认渲染。 */\n planUpdate?: (props: PlanUpdateRendererProps) => ReactNode | null\n}\n\nexport interface ChatViewCustomization {\n classNames?: ChatViewClassNames\n components?: ChatViewComponents\n renderers?: ChatViewRenderers\n}\n\nexport interface AssistantTurnComponentProps {\n turnKey: string\n sessionId: string\n messages: ChatMessage[]\n isStreaming?: boolean\n /** 打字机式显示节流下思考过程自己的追平状态,跟 isStreaming 不是一回事。 */\n isReasoningRevealing?: boolean\n isLastTurn?: boolean\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n sessionStatus?: string\n level?: 1 | 2\n forceExpanded?: boolean\n customization?: ChatViewCustomization\n}\n\nexport interface ToolCallComponentProps {\n toolCall: ToolCallInfo\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n answered?: boolean\n answerData?: AskUserAnswerData\n sessionId?: string\n sessionStatus?: string\n level?: 1 | 2\n turnBlocks?: ContentBlock[]\n reasoning?: string\n customization?: ChatViewCustomization\n}\n\nexport interface ToolRendererProps {\n toolCall: ToolCallInfo\n sessionId?: string\n}\n\nexport interface SkillStatusBarComponentProps {\n sessionId: string\n vertical?: boolean\n className?: string\n innerClassName?: string\n /** 打开技能页;只作用于「已安装 N 个技能」这一条。 */\n onOpenSkills?: () => void\n}\n\nexport function renderOptionalComponent<TProps extends object>(\n Component: ComponentType<TProps> | undefined,\n props: TProps,\n): ReactNode {\n return Component ? createElement(Component, props) : null\n}\n\nconst ChatCustomizationContext = createContext<ChatViewCustomization | undefined>(undefined)\n\n/** 聊天面板的定制(classNames / components / renderers),叶子组件不用逐层透传。 */\nexport const ChatCustomizationProvider = ChatCustomizationContext.Provider\n\nexport function useChatCustomization(): ChatViewCustomization | undefined {\n return useContext(ChatCustomizationContext)\n}\n\n/** 聊天区的自定义区域。 */\nexport interface ChatViewSlots {\n /** 消息列表上方的自定义区域。 */\n header?: ReactNode\n /** 无消息时的空状态。 */\n emptyState?: ReactNode\n /** 输入框下方的自定义区域。 */\n footer?: ReactNode\n}\n\n/** 智能体模式与纯 LLM 模式共用的外观属性。 */\nexport interface ChatPresentationProps {\n classNames?: ChatViewClassNames\n renderers?: ChatViewRenderers\n slots?: ChatViewSlots\n placeholder?: string\n /** 配色主题,默认浅色。宿主已经在祖先元素上写了 data-theme 时不用传。 */\n theme?: \"light\" | \"dark\"\n}\n","import type { FinalArtifact, ResultFeedbackReason } from \"@blade-hq/agent-client/internal\"\nimport { createContext, useCallback, useContext } from \"react\"\n\n/** 跟进建议、成果与结果评分的交互事件(宿主用来做埋点;SDK 不绑定任何分析厂商)。 */\nexport type FollowupInteractionEvent =\n | {\n type: \"suggestions_shown\"\n sessionId?: string\n assistantEntryId: string\n count: number\n }\n | {\n type: \"suggestion_adopted\"\n sessionId?: string\n assistantEntryId: string\n suggestionIndex: number\n }\n | {\n type: \"artifact_shown\"\n sessionId?: string\n assistantEntryId: string\n artifactIndex: number\n artifactKind: FinalArtifact[\"kind\"]\n }\n | {\n type: \"artifact_opened\"\n sessionId?: string\n assistantEntryId: string\n artifactIndex: number\n artifactKind: FinalArtifact[\"kind\"]\n }\n | {\n type: \"artifact_download_started\"\n sessionId?: string\n assistantEntryId: string\n artifactIndex: number\n artifactKind: \"file\"\n }\n | {\n type: \"artifact_download_succeeded\"\n sessionId?: string\n assistantEntryId: string\n artifactIndex: number\n artifactKind: \"file\"\n }\n | {\n type: \"result_feedback_shown\"\n sessionId?: string\n assistantEntryId: string\n }\n | {\n type: \"result_feedback_submitted\"\n sessionId?: string\n assistantEntryId: string\n helpful: boolean\n reason: ResultFeedbackReason | null\n updatedAt: string\n }\n\nconst FollowupInteractionContext = createContext<((event: FollowupInteractionEvent) => void) | undefined>(\n undefined,\n)\n\nexport const FollowupInteractionProvider = FollowupInteractionContext.Provider\n\n/** 发出交互事件;宿主回调抛错不影响用户的点击或下载。 */\nexport function useFollowupInteraction(): (event: FollowupInteractionEvent) => void {\n const callback = useContext(FollowupInteractionContext)\n return useCallback(\n (event: FollowupInteractionEvent) => {\n try {\n callback?.(event)\n } catch {\n }\n },\n [callback],\n )\n}\n","import { useEffect, useRef, useState } from \"react\"\nimport { normalizePluginRefs, type PluginRef } from \"@blade-hq/agent-client\"\nimport { useBladeClient } from \"../context\"\nimport { getPluginSuggestionItems, pluginRefsForSend } from \"../rich-input/lib/plugin-suggestions\"\nimport type { PluginSuggestionItem, PluginSuggestionError } from \"../rich-input/extensions/plugin-mention\"\nimport { ChatInput } from \"../components/ChatInput\"\nimport type { ComposerProps } from \"./customization\"\nimport { useSessionHandle } from \"./runtime/session-source\"\n\n/**\n * 轻输入(SDK 与 `<blade-chat>` 的默认输入框):textarea 和通用插件条目选择,不带富文本编辑、`/` 菜单、\n * 语音与模型选择。`AgentSession.attach()` / `insertText()`(页面协作、跟进建议、MCP 应用消息)\n * 都落进这里的文本。\n */\nexport function LightComposer({\n sessionId,\n onSend,\n onStop,\n isStreaming,\n isStopping,\n queueWhileRunning,\n mergesWithPanelAbove,\n planPanel,\n placeholderText,\n className,\n innerClassName,\n maxWidthClassName,\n initialDraft,\n initialDraftKey,\n}: ComposerProps) {\n const session = useSessionHandle(sessionId)\n const client = useBladeClient()\n const [refs, setRefs] = useState<PluginRef[]>([])\n const [items, setItems] = useState<Array<PluginSuggestionItem | PluginSuggestionError>>([])\n const [selectedIndex, setSelectedIndex] = useState(0)\n const restored = useRef<string | null>(null)\n\n const [value, setValue] = useState(initialDraft ?? \"\")\n const [draftKey, setDraftKey] = useState(initialDraftKey)\n if (draftKey !== initialDraftKey) {\n setDraftKey(initialDraftKey)\n if (initialDraft) setValue(initialDraft)\n }\n\n const [dismissed, setDismissed] = useState<string | null>(null)\n const match = value.match(/(?:^|\\s)@([^@\\s]*)$/)\n const query = match && value !== dismissed ? match[1] : null\n const candidates = items.filter((item): item is PluginSuggestionItem => item.kind === \"plugin\")\n useEffect(() => {\n setItems([])\n setSelectedIndex(0)\n if (query === null) return\n let current = true\n const timer = setTimeout(() => {\n void getPluginSuggestionItems(client, sessionId, query).then((result) => { if (current) setItems(result) })\n }, 150)\n return () => { current = false; clearTimeout(timer) }\n }, [client, client.token, sessionId, query])\n useEffect(() => {\n setRefs([])\n if (!session) return\n const restore = () => {\n if (restored.current === sessionId) return\n const latest = [...session.getState().turns].reverse().find((turn) => turn.role === \"user\")\n if (!latest || latest.turn_id.startsWith(\"local-user-\")) return\n restored.current = sessionId ?? null\n setRefs(normalizePluginRefs(latest.refs))\n }\n restore()\n return session.subscribe(restore)\n }, [session, sessionId])\n const select = (item: PluginSuggestionItem) => {\n const next = normalizePluginRefs([...refs, item])\n if (next.length > 20) return\n setRefs(next)\n setValue((prev) => prev.replace(/@[^@\\s]*$/, `@${item.label} `))\n setItems([])\n }\n\n useEffect(() => {\n if (!session) return\n const offAttach = session.on(\"attachRequested\", ({ label, content }) => {\n setValue((prev) => `${prev ? `${prev}\\n\\n` : \"\"}[${label}]\\n${content}`)\n })\n const offInsert = session.on(\"insertTextRequested\", ({ text }) => {\n setValue((prev) => (prev ? prev + text : text.replace(/^\\n+/, \"\")))\n })\n return () => {\n offAttach()\n offInsert()\n }\n }, [session])\n\n return (\n <>\n {planPanel ? <div className={maxWidthClassName ? `mx-auto w-full ${maxWidthClassName}` : undefined}>{planPanel}</div> : null}\n {refs.length ? <div aria-label=\"选择的插件条目\" className=\"flex flex-wrap gap-2 px-3 pt-2\">{refs.map((ref) => <span key={JSON.stringify([ref.plugin, ref.server, ref.id])} className=\"rounded bg-[hsl(var(--muted))] px-2 py-1 text-xs\">{ref.label}<button type=\"button\" aria-label={`移除${ref.label}`} onClick={() => setRefs((prev) => prev.filter((item) => item !== ref))}> ×</button></span>)}</div> : null}\n {query !== null && items.length ? <fieldset aria-label=\"插件条目候选\" className=\"m-0 min-w-0 border-0 px-3 py-2\">{items.map((item, index) => item.kind === \"plugin\" ? <button type=\"button\" aria-pressed={candidates[selectedIndex] === item} key={JSON.stringify([item.plugin, item.server, item.id])} onMouseDown={(event) => event.preventDefault()} onClick={() => select(item)} className={`flex w-full items-center gap-2 rounded px-2 py-1 text-sm hover:bg-[hsl(var(--muted))] ${candidates[selectedIndex] === item ? \"bg-[hsl(var(--muted))]\" : \"\"}`}>{item.icon ? <img src={item.icon} alt=\"\" width={16} height={16} /> : null}{item.label}<span className=\"ml-auto text-xs text-[hsl(var(--muted-foreground))]\">{item.display_name}</span></button> : <div key={index} className=\"text-xs\">{item.message}</div>)}</fieldset> : null}\n <ChatInput\n value={value}\n onValueChange={setValue}\n onSend={(text, queueWhenRunning) => onSend(text || refs.map((ref) => `@${ref.label}`).join(\" \"), { queueWhenRunning, refs: pluginRefsForSend(refs, session?.getState().turns) })}\n hasAttachments={refs.length > 0}\n onKeyDown={(event) => {\n if (query === null || event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return\n if (event.key === \"Escape\") { event.preventDefault(); setDismissed(value) }\n if (!candidates.length) return\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") { event.preventDefault(); setSelectedIndex((prev) => (prev + (event.key === \"ArrowDown\" ? 1 : candidates.length - 1)) % candidates.length) }\n if (event.key === \"Enter\" && !event.shiftKey) { event.preventDefault(); select(candidates[selectedIndex]!) }\n }}\n onStop={() => void onStop()}\n isStreaming={isStreaming}\n isStopping={isStopping}\n queueWhileRunning={queueWhileRunning}\n mergesWithPanelAbove={mergesWithPanelAbove}\n placeholder={placeholderText}\n className={className}\n innerClassName={innerClassName}\n queueKey={sessionId}\n />\n </>\n )\n}\n","import { ArrowUp, Loader2, Square } from \"lucide-react\"\nimport { useRef, useState, type CSSProperties, type KeyboardEvent } from \"react\"\nimport { isQueueShortcut, queueShortcutLabel } from \"../lib/message-shortcuts\"\nimport { cn } from \"../lib/utils\"\n\ninterface Props {\n value: string\n onValueChange: (value: string) => void\n onSend: (text: string, queueWhenRunning?: boolean) => boolean | Promise<boolean>\n onStop: () => void\n isStreaming: boolean\n isStopping?: boolean\n queueWhileRunning?: boolean\n mergesWithPanelAbove?: boolean\n placeholder?: string\n className?: string\n innerClassName?: string\n textareaClassName?: string\n toolbarClassName?: string\n queueKey?: string\n hasAttachments?: boolean\n onKeyDown?: (event: KeyboardEvent<HTMLTextAreaElement>) => void\n}\n\ninterface ChatInputKeyboardEvent {\n key: string\n shiftKey: boolean\n isComposing: boolean\n keyCode?: number\n}\n\nfunction isImeCompositionKey(event: ChatInputKeyboardEvent): boolean {\n return event.isComposing || event.keyCode === 229\n}\n\nfunction shouldSubmitChatInput(\n event: ChatInputKeyboardEvent,\n menuOpen: boolean,\n): boolean {\n return event.key === \"Enter\" && !event.shiftKey && !menuOpen && !isImeCompositionKey(event)\n}\n\n/**\n * 轻量聊天输入框:textarea(Enter 发送 / Shift+Enter 换行)+ 发送/停止按钮。\n * 不含第一方版本的富文本编辑、@ 补全、技能菜单、语音输入与模型选择。\n * 内容受控,session.attach() / insertText() 通过 ChatView 注入到这里。\n */\nexport function ChatInput({\n value,\n onValueChange,\n onSend,\n onStop,\n isStreaming,\n isStopping = false,\n queueWhileRunning = false,\n mergesWithPanelAbove = false,\n placeholder = \"输入消息…\",\n className,\n innerClassName,\n textareaClassName,\n toolbarClassName,\n queueKey,\n hasAttachments = false,\n onKeyDown,\n}: Props) {\n const trimmed = value.trim()\n const latestValue = useRef(value)\n latestValue.current = value\n const sending = useRef(false)\n const [isSending, setIsSending] = useState(false)\n void queueKey\n const canSend =\n !isSending &&\n (trimmed.length > 0 || hasAttachments) &&\n (!isStreaming || (queueWhileRunning && !hasAttachments && !isStopping))\n\n const handleSend = async (queueWhenRunning = false) => {\n if (!canSend || sending.current) return\n sending.current = true\n setIsSending(true)\n const submitted = value\n try {\n const accepted = await onSend(trimmed, queueWhenRunning)\n if (accepted === false) return\n if (latestValue.current === submitted) onValueChange(\"\")\n } finally {\n sending.current = false\n setIsSending(false)\n }\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n if (shouldSubmitChatInput({\n key: event.key,\n shiftKey: event.shiftKey,\n isComposing: event.nativeEvent.isComposing,\n keyCode: event.nativeEvent.keyCode,\n }, false)) {\n event.preventDefault()\n void handleSend(isQueueShortcut(event))\n }\n }\n\n return (\n <div\n style={\n mergesWithPanelAbove\n ? ({ \"--blade-chat-input-top-border\": \"0\" } as CSSProperties)\n : undefined\n }\n part=\"input\"\n className={cn(\n \"blade-chat-input py-3\",\n // 上留白没有这个问题:它是 Tailwind 的 `py-3`,与 `pt-0` 同在 utilities 层,\n // 按源码顺序后者胜。\n mergesWithPanelAbove && \"pt-0\",\n className,\n )}\n >\n <div\n part=\"input-inner\"\n className={cn(\n \"blade-chat-input-inner mx-auto flex max-w-[748px] items-end gap-2 border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2\",\n mergesWithPanelAbove ? \"rounded-b-[22px]\" : \"rounded-2xl\",\n innerClassName,\n )}\n >\n <textarea\n value={value}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={handleKeyDown}\n onInput={(event) => {\n const el = event.currentTarget\n el.style.height = \"auto\"\n el.style.height = `${Math.min(el.scrollHeight, 192)}px`\n }}\n rows={1}\n placeholder={placeholder}\n aria-label=\"聊天输入\"\n part=\"textarea\"\n className={cn(\n \"blade-chat-textarea max-h-48 min-h-[28px] flex-1 resize-none bg-transparent py-1 text-sm leading-6 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.6)]\",\n textareaClassName,\n )}\n />\n <div part=\"input-toolbar\" className={cn(\"blade-chat-input-toolbar flex shrink-0 items-center gap-2\", toolbarClassName)}>\n {isStreaming ? (\n <>\n {queueWhileRunning ? (\n <button type=\"button\" onClick={() => void handleSend()} disabled={!canSend} aria-label=\"发送引导消息\" title=\"发送引导消息\" className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] disabled:opacity-40\"><ArrowUp size={15} /></button>\n ) : null}\n <button type=\"button\" onClick={onStop} disabled={isStopping} aria-label={isStopping ? \"正在停止\" : \"停止回复\"} title={isStopping ? \"正在停止\" : \"停止回复\"} className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] transition-opacity hover:opacity-90 disabled:opacity-60\">{isStopping ? <Loader2 size={14} className=\"animate-spin\" /> : <Square size={12} fill=\"currentColor\" />}</button>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={() => void handleSend()}\n disabled={!canSend}\n aria-label=\"发送引导消息\"\n title=\"发送引导消息\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <ArrowUp size={15} />\n </button>\n )}\n </div>\n </div>\n {trimmed && canSend && !hasAttachments && <div className=\"mx-auto mt-1 max-w-[748px] text-right text-[11px] text-[hsl(var(--muted-foreground))]\">{queueShortcutLabel()} · 排队消息</div>}\n </div>\n )\n}\n","import { Loader2 } from \"lucide-react\"\n\nexport function isPreparingReply(messages: readonly { role: string; kind?: string }[]): boolean {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index]\n if (message.kind === \"context\") continue\n if (message.role === \"assistant\") return false\n if (message.role === \"user\") return true\n }\n return true\n}\n\nexport function ChatLoadingIndicator({ preparing = false }: { preparing?: boolean }) {\n return (\n <output className=\"flex h-[38px] items-center gap-2 px-1 text-xs text-[hsl(var(--muted-foreground))]\" aria-live=\"polite\">\n <Loader2 size={14} className=\"animate-spin\" aria-hidden=\"true\" />\n <span>{preparing ? \"正在准备可用工具…\" : \"正在生成中…\"}</span>\n </output>\n )\n}\n","import { ChatLoadingIndicator, isPreparingReply } from \"./ChatLoadingIndicator\"\nimport { useChatVirtualizer } from \"./runtime/environment\"\nimport { ArrowRight, BookOpen, Download, ExternalLink, FilePenLine, FileText, Search, Terminal, Wrench } from \"lucide-react\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport {\n extractTextAttachments,\n getTextContent,\n normalizeMessageContent,\n} from \"@blade-hq/agent-client/internal\"\nimport { buildCitationsFromToolCalls, type CitationEntry } from \"./lib/citations\"\nimport { useBladeClient } from \"../context\"\nimport type { ChatMessage, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport type { PostChatFollowup } from \"@blade-hq/agent-client/internal\"\nimport type { ResultFeedback as SavedResultFeedback } from \"@blade-hq/agent-client/internal\"\nimport { chatErrorForDisplay, isBackgroundWakeMessage } from \"@blade-hq/agent-client/internal\"\nimport { BackgroundWakeNotice } from \"../components/BackgroundWakeNotice\"\nimport { collectMemoryRefs, MemoryRefsHint } from \"./AssistantTurnBlock\"\nimport { useMessagePin } from \"../hooks/use-message-pin\"\nimport { useSessionState } from \"./runtime/session-source\"\nimport { useComposerBridge } from \"./runtime/environment\"\nimport type { AskUserAnswerData } from \"./AskUserQuestionBlock\"\nimport { isErrorMessage, isUserMessage } from \"./UserMessageBubble\"\nimport {\n collectTurnMessages,\n getPersistentAskUserQuestions,\n toolCallAnswered,\n} from \"./assistant-turn-questions\"\nimport { buildMessageListBlocks } from \"./message-list-blocks\"\nimport { ContextGroupCard } from \"../components/ContextCard\"\nimport { getToolDescription, getToolTone } from \"./display-utils\"\nimport { HistoricalResultFeedback, ResultFeedback } from \"./ResultFeedback\"\nimport { ToolCallBlock as QuestionBlock } from \"./ToolCallBlock\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\n\n\ntype TextRow = {\n type: \"text\"\n key: string\n role: \"user\" | \"assistant\" | \"error\"\n text: string\n entryIds: string[]\n failed?: boolean\n sending?: boolean\n citations?: Record<number, CitationEntry>\n}\ntype MemoryRefsRow = { type: \"memory-refs\"; key: string; refs: NonNullable<ChatMessage[\"memory_refs\"]> }\n\ntype FollowupRow = {\n type: \"followup\"\n key: string\n followup: PostChatFollowup\n}\n\ntype HistoricalFeedbackRow = {\n type: \"historical-feedback\"\n key: string\n feedback: SavedResultFeedback\n}\n\ntype QuestionRow = {\n type: \"question\"\n key: string\n toolCall: ToolCallInfo\n turnBlocks: ChatMessage[\"blocks\"]\n}\ntype ToolDescriptionRow = {\n type: \"tool-description\"\n key: string\n description: string\n running: boolean\n}\n\ntype ContextGroupRow = {\n type: \"context-group\"\n key: string\n contexts: NonNullable<ChatMessage[\"context\"]>[]\n}\ntype ContextDividerRow = { type: \"context-divider\"; key: string }\n\ntype LiteRow =\n | { type: \"background-wakeup\"; key: string }\n | TextRow\n | MemoryRefsRow\n | FollowupRow\n | HistoricalFeedbackRow\n | QuestionRow\n | ToolDescriptionRow\n | ContextGroupRow\n | ContextDividerRow\n\nconst LITE_LOADING_INDICATOR_HEIGHT = 38\n\nfunction messageText(message: ChatMessage) {\n return getTextContent(normalizeMessageContent(message.content)).trim()\n}\n\nfunction userMessageText(message: ChatMessage) {\n const { cleanText, attachments } = extractTextAttachments(\n normalizeMessageContent(message.content),\n )\n const text = cleanText.trim()\n if (text) return text\n return attachments.length > 0 ? \"(已上传文件)\" : \"\"\n}\n\nexport function buildLiteRows({\n messages,\n followup,\n sessionMessages = messages,\n agentLoops = {},\n resultFeedbackByEntry = new Map(),\n showContexts = false,\n}: {\n messages: ChatMessage[]\n followup: PostChatFollowup | null\n sessionMessages?: ChatMessage[]\n agentLoops?: Record<string, { toolCallId: string }>\n resultFeedbackByEntry?: ReadonlyMap<string, SavedResultFeedback>\n showContexts?: boolean\n}) {\n const blocks = buildMessageListBlocks({\n messages,\n agentLoopNames: new Set(),\n sessionIsStreaming: false,\n showContexts,\n })\n const rows: LiteRow[] = []\n for (const block of blocks) {\n let row: TextRow | null = null\n let turnMessages: ChatMessage[] = []\n const followupMatchesBlock =\n block.type === \"assistant_turn\" &&\n followup != null &&\n block.messages.some((message) => message.entry_id === followup.assistant_entry_id)\n if (block.type === \"message\") {\n if (isBackgroundWakeMessage(block.message)) {\n rows.push({ type: \"background-wakeup\", key: block.message.render_id ?? block.key })\n continue\n }\n const role = isUserMessage(block.message)\n ? \"user\"\n : isErrorMessage(block.message)\n ? \"error\"\n : null\n if (role) {\n const text = role === \"user\"\n ? userMessageText(block.message)\n : role === \"error\"\n ? chatErrorForDisplay(messageText(block.message))\n : messageText(block.message)\n if (text) {\n row = {\n type: \"text\",\n key: block.message.render_id ?? block.key,\n role,\n sending: role === \"user\" && block.message.status === \"streaming\",\n text,\n entryIds: block.message.entry_id ? [block.message.entry_id] : [],\n }\n }\n }\n } else if (block.type === \"context_group\") {\n const contexts = block.messages\n .map((message) => message.context)\n .filter((context) => Boolean(context)) as NonNullable<ChatMessage[\"context\"]>[]\n if (contexts.length > 0) {\n rows.push({ type: \"context-group\", key: block.key, contexts })\n }\n } else if (block.type === \"context_divider\") {\n rows.push({ type: \"context-divider\", key: block.key })\n } else if (block.type === \"assistant_turn\") {\n turnMessages = collectTurnMessages({\n rootMessages: block.messages,\n sessionMessages,\n agentLoops,\n })\n const turnToolCalls = turnMessages\n .filter((m) => m.role === \"assistant\")\n .flatMap((m) => m.tool_calls ?? [])\n const citations = buildCitationsFromToolCalls(turnToolCalls)\n const hasCitations = Object.keys(citations).length > 0\n block.messages.forEach((message, index) => {\n if (\n message.status === \"completed\" ||\n message.status === \"paused\" ||\n message.status === \"failed\" ||\n message.status === \"interrupted\"\n ) {\n const text = messageText(message)\n if (text || message.status === \"failed\") {\n rows.push({\n type: \"text\",\n key: message.entry_id ?? `${block.key}-assistant-${index}`,\n role: \"assistant\",\n text,\n entryIds: message.entry_id ? [message.entry_id] : [],\n ...(message.status === \"failed\" ? { failed: true } : {}),\n ...(hasCitations ? { citations } : {}),\n })\n }\n }\n for (const toolCall of message.tool_calls ?? []) {\n const description = getToolDescription(toolCall)\n const running = getToolTone(toolCall.status) === \"running\"\n if (!description || !running) continue\n rows.push({\n type: \"tool-description\",\n key: `tool-description-${toolCall.id}`,\n description,\n running,\n })\n }\n })\n const memoryRefs = collectMemoryRefs(block.messages)\n if (memoryRefs.length > 0) {\n rows.push({ type: \"memory-refs\", key: `memory-refs-${block.key}`, refs: memoryRefs })\n }\n }\n\n if (row) rows.push(row)\n if (block.type === \"assistant_turn\") {\n for (const question of getPersistentAskUserQuestions(turnMessages)) {\n rows.push({\n type: \"question\",\n key: `question-${question.toolCall.id}`,\n toolCall: question.toolCall,\n turnBlocks: question.turnBlocks,\n })\n }\n }\n if (followupMatchesBlock) {\n rows.push({\n type: \"followup\",\n key: `followup-${followup.assistant_entry_id}`,\n followup,\n })\n } else if (block.type === \"assistant_turn\") {\n const feedback = block.messages\n .map((message) => message.entry_id && resultFeedbackByEntry.get(message.entry_id))\n .find((item): item is SavedResultFeedback => item != null)\n if (feedback) {\n rows.push({\n type: \"historical-feedback\",\n key: `historical-feedback-${feedback.assistant_entry_id}`,\n feedback,\n })\n }\n }\n }\n\n return rows\n}\n\nexport function LiteMessageList({\n sessionId,\n messages,\n followup,\n isViewer,\n isLoadingHistory,\n sessionStatus,\n isStreaming = false,\n resultFeedbackByEntry = new Map(),\n onResultFeedbackSaved,\n onAnswer,\n onLoadOlder,\n historyLoadRevision = 0,\n}: {\n sessionId: string\n messages: ChatMessage[]\n followup: PostChatFollowup | null\n isViewer: boolean\n isLoadingHistory: boolean\n sessionStatus?: string\n isStreaming?: boolean\n resultFeedbackByEntry?: ReadonlyMap<string, SavedResultFeedback>\n onResultFeedbackSaved?: (feedback: SavedResultFeedback) => void\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n onLoadOlder?: (beforeCommit?: () => void) => Promise<boolean>\n historyLoadRevision?: number\n}) {\n const scrollRef = useRef<HTMLDivElement>(null)\n const trailingSpacerRef = useRef<HTMLDivElement>(null)\n const stickToBottomRef = useRef(true)\n const scrollFrameRef = useRef<number | null>(null)\n const loadingOlderRef = useRef(false)\n useEffect(() => {\n void historyLoadRevision\n const element = scrollRef.current\n if (!element || !onLoadOlder) return\n const sentinel = document.createElement(\"div\")\n sentinel.dataset.historySentinel = \"\"\n element.prepend(sentinel)\n let disposed = false\n const loadOlder = async () => {\n if (loadingOlderRef.current) return\n loadingOlderRef.current = true\n let anchorKey: string | undefined\n let anchorOffset = 0\n let height = element.scrollHeight\n const advanced = await onLoadOlder(() => {\n const top = element.getBoundingClientRect().top\n const row = Array.from(element.querySelectorAll<HTMLElement>(\"[data-lite-row-key]\"))\n .find((item) => item.getBoundingClientRect().bottom >= top)\n anchorKey = row?.dataset.liteRowKey\n anchorOffset = row ? row.getBoundingClientRect().top - top : 0\n height = element.scrollHeight\n }).catch(() => false)\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))\n if (disposed) return\n const anchored = anchorKey\n ? Array.from(element.querySelectorAll<HTMLElement>(\"[data-lite-row-key]\"))\n .find((item) => item.dataset.liteRowKey === anchorKey)\n : null\n element.scrollTop += anchored\n ? anchored.getBoundingClientRect().top - element.getBoundingClientRect().top - anchorOffset\n : element.scrollHeight - height\n loadingOlderRef.current = false\n if (advanced && element.scrollHeight <= element.clientHeight) void loadOlder()\n }\n const observer = new IntersectionObserver(([entry]) => {\n if (!entry?.isIntersecting) return\n void loadOlder()\n }, { root: element, rootMargin: \"160px 0px 0px\" })\n observer.observe(sentinel)\n return () => {\n disposed = true\n loadingOlderRef.current = false\n observer.disconnect()\n sentinel.remove()\n }\n }, [onLoadOlder, historyLoadRevision])\n const showContexts = false\n const agentLoops = useSessionState(sessionId, (state) => state.agentLoops)\n const askAnswers = useSessionState(sessionId, (state) => state.askAnswers)\n const rows = useMemo(\n () =>\n buildLiteRows({\n messages,\n followup,\n sessionMessages: messages,\n agentLoops,\n resultFeedbackByEntry,\n showContexts,\n }),\n [agentLoops, followup, messages, resultFeedbackByEntry],\n )\n const latestUserRow = useMemo(() => {\n for (let index = rows.length - 1; index >= 0; index -= 1) {\n const row = rows[index]\n if (row?.type === \"text\" && row.role === \"user\") return { row, index }\n }\n return null\n }, [rows])\n const latestUserEntryId = latestUserRow?.row.entryIds.at(-1)\n const activeQuestionId = useMemo(\n () => rows\n .filter((row): row is QuestionRow => row.type === \"question\" && row.toolCall.status === \"pending\")\n .at(-1)?.toolCall.id,\n [rows],\n )\n const scrollToLatest = useCallback(() => {\n if (scrollFrameRef.current != null) cancelAnimationFrame(scrollFrameRef.current)\n scrollFrameRef.current = requestAnimationFrame(() => {\n scrollFrameRef.current = null\n const element = scrollRef.current\n if (element) element.scrollTop = element.scrollHeight\n })\n }, [])\n const { virtualizer } = useChatVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollRef.current,\n estimateSize: (index) =>\n rows[index]?.type === \"question\"\n ? 280\n : rows[index]?.type === \"followup\"\n ? 150\n : rows[index]?.type === \"historical-feedback\"\n ? 48\n : rows[index]?.type === \"tool-description\"\n ? 42\n : 96,\n getItemKey: (index) => rows[index]?.key ?? index,\n overscan: 4,\n onChange: (_instance, sync) => {\n if (!sync && stickToBottomRef.current) scrollToLatest()\n },\n })\n const totalSize = virtualizer.getTotalSize()\n const latestSignature = rows\n .map((row) =>\n row.type === \"text\"\n ? `${row.key}:${row.text.length}`\n : row.type === \"question\"\n ? `${row.key}:${row.toolCall.status ?? \"\"}`\n : row.type === \"tool-description\"\n ? `${row.key}:${row.running ? 1 : 0}`\n : row.type === \"context-group\"\n ? `${row.key}:${row.contexts.length}:${row.contexts.at(-1)?.context_revision ?? \"\"}`\n : row.type === \"context-divider\" || row.type === \"background-wakeup\"\n ? row.key\n : row.type === \"historical-feedback\"\n ? `${row.key}:${row.feedback.updated_at}`\n : row.type === \"memory-refs\"\n ? `${row.key}:${row.refs.length}`\n : `${row.key}:${row.followup.suggestions.length}:${row.followup.final_artifacts?.length ?? 0}`,\n )\n .join(\"|\")\n\n const getScrollElement = useCallback(() => scrollRef.current, [])\n const getTargetElement = useCallback(() => {\n const key = latestUserRow?.row.key\n if (!key) return null\n return (\n Array.from(\n scrollRef.current?.querySelectorAll<HTMLElement>(\"[data-lite-row-key]\") ?? [],\n ).find((candidate) => candidate.dataset.liteRowKey === key) ?? null\n )\n }, [latestUserRow])\n const getEstimatedTargetScrollTop = useCallback(\n () =>\n latestUserRow\n ? Math.max(0, (virtualizer.getOffsetForIndex(latestUserRow.index, \"start\")?.[0] ?? 0) - 24)\n : null,\n [latestUserRow, virtualizer],\n )\n const getSpacerHeight = useCallback(\n () => trailingSpacerRef.current?.getBoundingClientRect().height ?? 0,\n [],\n )\n const setSpacerHeight = useCallback((height: number) => {\n if (trailingSpacerRef.current) trailingSpacerRef.current.style.height = `${height}px`\n }, [])\n const stopAutoScroll = useCallback(() => {\n stickToBottomRef.current = false\n }, [])\n const followToBottom = useCallback(() => {\n stickToBottomRef.current = true\n scrollToLatest()\n }, [scrollToLatest])\n const { isActive: isMessagePinActive } = useMessagePin({\n targetKey: latestUserRow?.row.key ?? null,\n pinTarget: latestUserEntryId?.startsWith(\"local-user-\") ?? false,\n isStreaming,\n layoutKey: `${isStreaming}:${latestSignature}:${totalSize}`,\n getScrollElement,\n getTargetElement,\n getTargetScrollTop: getEstimatedTargetScrollTop,\n getSpacerHeight,\n setSpacerHeight,\n stopAutoScroll,\n scrollToBottom: followToBottom,\n })\n\n useEffect(() => {\n if (!isLoadingHistory && latestSignature && stickToBottomRef.current) scrollToLatest()\n }, [isLoadingHistory, latestSignature, scrollToLatest])\n\n useEffect(() => {\n if (!isStreaming || !stickToBottomRef.current) return\n scrollToLatest()\n }, [isStreaming, scrollToLatest])\n\n useEffect(\n () => () => {\n if (scrollFrameRef.current != null) cancelAnimationFrame(scrollFrameRef.current)\n },\n [],\n )\n\n return (\n <div\n ref={scrollRef}\n onScroll={(event) => {\n const element = event.currentTarget\n if (isMessagePinActive()) {\n stickToBottomRef.current = false\n return\n }\n stickToBottomRef.current =\n element.scrollHeight - element.scrollTop - element.clientHeight < 80\n }}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 sm:px-8\"\n >\n {rows.length === 0 ? (\n <div className=\"grid min-h-full place-items-center text-sm text-[hsl(var(--muted-foreground))]\">\n {isLoadingHistory ? \"正在加载消息…\" : \"开始新的对话吧\"}\n </div>\n ) : (\n <div\n className=\"relative mx-auto w-full max-w-3xl\"\n style={{\n height:\n totalSize + (isStreaming ? LITE_LOADING_INDICATOR_HEIGHT : 0),\n }}\n >\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index]\n if (!row) return null\n return (\n <div\n key={row.key}\n ref={virtualizer.measureElement}\n data-index={virtualRow.index}\n data-lite-row-key={row.key}\n className=\"absolute left-0 top-0 w-full pb-5\"\n style={{ transform: `translateY(${virtualRow.start}px)` }}\n >\n {row.type === \"text\" ? (\n <PlainTextMessage row={row} sessionId={sessionId} />\n ) : row.type === \"background-wakeup\" ? (\n <BackgroundWakeNotice />\n ) : row.type === \"memory-refs\" ? (\n <MemoryRefsHint refs={row.refs} />\n ) : row.type === \"question\" ? (\n <QuestionBlock\n toolCall={row.toolCall}\n answerData={askAnswers?.[row.toolCall.id]}\n onAnswer={isViewer ? undefined : onAnswer}\n answered={toolCallAnswered(\n row.toolCall,\n sessionStatus,\n askAnswers?.[row.toolCall.id],\n )}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n isActiveQuestion={row.toolCall.id === activeQuestionId}\n turnBlocks={row.turnBlocks}\n />\n ) : row.type === \"tool-description\" ? (\n <ToolDescription row={row} />\n ) : row.type === \"context-group\" ? (\n <ContextGroupCard contexts={row.contexts} />\n ) : row.type === \"context-divider\" ? (\n <div aria-hidden=\"true\" className=\"h-px w-full bg-[hsl(var(--border)/0.55)]\" />\n ) : row.type === \"historical-feedback\" ? (\n <HistoricalResultFeedback feedback={row.feedback} />\n ) : (\n <LiteFollowup\n sessionId={sessionId}\n followup={row.followup}\n isViewer={isViewer}\n savedFeedback={resultFeedbackByEntry.get(row.followup.assistant_entry_id)}\n onFeedbackSaved={onResultFeedbackSaved}\n />\n )}\n </div>\n )\n })}\n {isStreaming ? (\n <div\n className=\"absolute left-0 top-0 w-full\"\n style={{ transform: `translateY(${totalSize}px)` }}\n >\n <ChatLoadingIndicator preparing={isPreparingReply(messages)} />\n </div>\n ) : null}\n </div>\n )}\n {rows.length === 0 && isStreaming ? <ChatLoadingIndicator preparing={isPreparingReply(messages)} /> : null}\n <div ref={trailingSpacerRef} aria-hidden=\"true\" className=\"pointer-events-none w-full\" />\n </div>\n )\n}\n\nfunction ToolDescription({ row }: { row: ToolDescriptionRow }) {\n const description = row.description\n const Icon = description.includes(\"搜索\")\n ? Search\n : description.includes(\"执行\")\n ? Terminal\n : description.includes(\"读取\")\n ? BookOpen\n : description.includes(\"文件\")\n ? FilePenLine\n : Wrench\n return (\n <div className=\"flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]\" title={description}>\n <Icon size={14} className={row.running ? \"animate-pulse\" : \"opacity-55\"} aria-hidden=\"true\" />\n </div>\n )\n}\n\nfunction PlainTextMessage({\n row,\n sessionId,\n}: {\n row: TextRow\n sessionId: string\n}) {\n const markdown = (\n <MarkdownContent\n sessionId={sessionId}\n className=\"lite-chat-markdown [&_p]:whitespace-pre-wrap\"\n controls={{ code: true }}\n citations={row.citations}\n >\n {row.text}\n </MarkdownContent>\n )\n\n if (row.role === \"user\") {\n return (\n <div className=\"flex justify-end\">\n <div className={`max-w-[82%] rounded-[24px] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-base leading-[1.7] transition-colors duration-200 ${row.sending ? \"text-[hsl(var(--muted-foreground))]\" : \"text-[hsl(var(--user-msg-fg))]\"}`}>\n {markdown}\n </div>\n </div>\n )\n }\n\n return (\n <div\n className={`break-words text-sm leading-6 ${\n row.role === \"error\"\n ? \"text-[hsl(var(--destructive))]\"\n : \"text-[hsl(var(--foreground))]\"\n }`}\n >\n {row.failed ? (\n <div className=\"mb-1 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]\">\n 生成失败\n </div>\n ) : null}\n {markdown}\n </div>\n )\n}\n\nfunction LiteFollowup({\n sessionId,\n followup,\n isViewer,\n savedFeedback,\n onFeedbackSaved,\n}: {\n sessionId: string\n followup: PostChatFollowup\n isViewer: boolean\n savedFeedback?: SavedResultFeedback\n onFeedbackSaved?: (feedback: SavedResultFeedback) => void\n}) {\n const client = useBladeClient()\n const composer = useComposerBridge(sessionId)\n const [downloadingPath, setDownloadingPath] = useState<string | null>(null)\n const artifacts = followup.final_artifacts ?? []\n\n const downloadArtifact = async (target: string, label: string) => {\n if (downloadingPath) return\n setDownloadingPath(target)\n try {\n await client.sessions.downloadFile(sessionId, target, label)\n } catch {\n } finally {\n setDownloadingPath(null)\n }\n }\n\n return (\n <div className=\"flex flex-col items-start gap-3\">\n {artifacts.length > 0 ? (\n <div className=\"flex w-full flex-col items-start gap-1.5\">\n <div className=\"text-xs text-[hsl(var(--muted-foreground))]\">本轮成果</div>\n {artifacts.map((artifact, artifactIndex) =>\n artifact.kind === \"link\" ? (\n <a\n key={`${artifact.kind}:${artifactIndex}`}\n href={artifact.target}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex w-[320px] max-w-full items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2.5 text-sm hover:bg-[hsl(var(--muted)/0.5)]\"\n >\n <ExternalLink size={16} className=\"shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{artifact.label || artifact.target}</span>\n </a>\n ) : (\n <button\n key={`${artifact.kind}:${artifactIndex}`}\n type=\"button\"\n disabled={downloadingPath === artifact.target}\n onClick={() =>\n void downloadArtifact(\n artifact.target,\n artifact.label || artifact.target.split(\"/\").pop() || \"download\",\n )\n }\n className=\"flex w-[320px] max-w-full items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2.5 text-sm hover:bg-[hsl(var(--muted)/0.5)]\"\n >\n <FileText size={16} className=\"shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{artifact.label || artifact.target}</span>\n <Download size={14} className=\"shrink-0 text-[hsl(var(--muted-foreground))]\" />\n </button>\n ),\n )}\n </div>\n ) : null}\n {followup.suggestions.length > 0 ? (\n <div className=\"flex max-w-full flex-col items-start gap-1.5\">\n <div className=\"text-xs text-[hsl(var(--muted-foreground))]\">下一步可以</div>\n {followup.suggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n disabled={isViewer}\n onClick={() => {\n composer.appendText(suggestion, true)\n }}\n className=\"flex max-w-full items-center gap-2 rounded-xl bg-[hsl(var(--muted)/0.62)] px-3 py-2 text-left text-sm disabled:opacity-60\"\n >\n <span>{suggestion}</span>\n <ArrowRight size={14} className=\"shrink-0\" />\n </button>\n ))}\n </div>\n ) : null}\n <ResultFeedback\n sessionId={sessionId}\n followup={followup}\n isViewer={isViewer}\n savedFeedback={savedFeedback}\n onSaved={onFeedbackSaved}\n />\n </div>\n )\n}\n","import type { ToolCallInfo } from \"@blade-hq/agent-client/internal\"\n\n/** 一条可点击引用的原文,来自保存的插件快照。 */\nexport interface CitationEntry {\n n: number\n title: string\n text: string\n previewUrl: string | null\n snapshot?: boolean\n toolCallId?: string\n itemId?: string\n}\n\nfunction sameEvidence(a: CitationEntry, b: CitationEntry): boolean {\n return (\n a.title === b.title &&\n a.text === b.text &&\n a.toolCallId === b.toolCallId &&\n a.itemId === b.itemId\n )\n}\n\n/** Collect saved plugin sources; conflicting numbers remain unclickable. */\nexport function buildCitationsFromToolCalls(\n toolCalls: ToolCallInfo[] | null | undefined,\n): Record<number, CitationEntry> {\n // The runner has already filtered evidence from completed nested calls.\n const finishedCalls = (toolCalls ?? []).filter((call) => call.status === \"done\" || call.status === \"error\")\n const merged = new Map<number, CitationEntry>()\n const ambiguous = new Set<number>()\n for (const call of finishedCalls) {\n const hits = parsePluginEvidence(call)\n if (!hits) continue\n for (const hit of hits) {\n const existing = merged.get(hit.n)\n if (existing && !sameEvidence(existing, hit)) {\n ambiguous.add(hit.n)\n continue\n }\n merged.set(hit.n, hit)\n }\n }\n const map: Record<number, CitationEntry> = {}\n for (const [n, hit] of merged) {\n if (ambiguous.has(n)) continue\n map[n] = hit\n }\n return map\n}\n\nfunction parsePluginEvidence(call: ToolCallInfo): CitationEntry[] | undefined {\n const items = call.evidence\n if (!Array.isArray(items)) return undefined\n return items.flatMap((item: unknown): CitationEntry[] => {\n if (!item || typeof item !== \"object\") return []\n const entry = item as Record<string, unknown>\n if (!Number.isSafeInteger(entry.n) || Number(entry.n) < 1 || (entry.tool_call_id !== call.id && entry.parent_tool_call_id !== call.id) ||\n typeof entry.id !== \"string\" || typeof entry.title !== \"string\" || typeof entry.text !== \"string\") return []\n let url: string | null = null\n if (typeof entry.url === \"string\") {\n try {\n const parsed = new URL(entry.url)\n if ([\"https:\", \"http:\"].includes(parsed.protocol) && !parsed.username && !parsed.password) url = parsed.href\n } catch { }\n }\n return [{ n: Number(entry.n), title: entry.title, text: entry.text, snapshot: true,\n toolCallId: String(entry.tool_call_id), itemId: entry.id, previewUrl: url }]\n })\n}\n","import { BellRing } from \"lucide-react\"\n\n/** Shared by the SDK, built-in chat and developer message view. */\nexport function BackgroundWakeNotice() {\n return (\n <div\n data-background-wakeup\n className=\"my-3 flex items-start gap-2 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.35)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\"\n >\n <BellRing size={14} className=\"mt-0.5 shrink-0\" aria-hidden=\"true\" />\n <div>\n <p className=\"font-medium\">后台任务已结束</p>\n <p className=\"mt-0.5\">助手已自动继续处理结果</p>\n </div>\n </div>\n )\n}\n","import { useOptionalBladeClient } from \"../context\"\nimport { getServerTime } from \"@blade-hq/agent-client/internal\"\nimport { MessageImage } from \"../components/MessageImage\"\nimport {\n ArrowUpRight,\n BookOpen,\n Bot,\n ChevronRight,\n} from \"lucide-react\"\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { buildCitationsFromToolCalls } from \"./lib/citations\"\nimport { getFileParts, getImageParts, getTextContent, normalizeMessageContent } from \"@blade-hq/agent-client/internal\"\nimport { isUiMeta } from \"./lib/ui-meta\"\nimport {\n collectInlineToolUiCards,\n collectPreviewToolUiCards,\n isWorkflowRunToolName,\n} from \"@blade-hq/agent-client/internal\"\nimport { cn } from \"../lib/utils\"\nimport type { ChatMessage, MemoryRefInfo, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport { sendToSession } from \"./runtime/actions\"\nimport { useSessionHandle, useSessionState } from \"./runtime/session-source\"\nimport {\n Reasoning,\n ReasoningContent,\n ReasoningTrigger,\n ThinkingBadge,\n} from \"./ai-elements/reasoning\"\nimport { CardContext, type CardContextValue } from \"./card/CardContext\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\nimport type { AskUserAnswerData } from \"./AskUserQuestionBlock\"\nimport { FileDeliveryCards } from \"./FileDeliveryCards\"\nimport { MessageActions } from \"./MessageActions\"\nimport { MessageFileAttachmentList } from \"./MessageFileAttachmentList\"\nimport { isPlanUpdateTool } from \"../components/PlanUpdateBlock\"\nimport { ToolUiCard } from \"./ToolUiCard\"\nimport { ToolCallBlock, ToolFilePreviewAction, ToolPreviewAction } from \"./ToolCallBlock\"\nimport { WorkflowRunBlock } from \"./WorkflowRunBlock\"\nimport { type ChatViewCustomization, useChatCustomization } from \"./customization\"\nimport { findLatestReasoningMessageIndex } from \"./reasoning-visibility\"\nimport {\n extractToolFilePath,\n formatToolName,\n} from \"./display-utils\"\nimport {\n collectTurnMessages,\n getPersistentAskUserQuestions,\n toolCallAnswered,\n} from \"./assistant-turn-questions\"\nimport { useChatEnvironment, useChatRenderMode } from \"./runtime/environment\"\n\nexport { collectTurnMessages, getPersistentAskUserQuestions } from \"./assistant-turn-questions\"\n\ninterface Props {\n turnKey: string\n sessionId: string\n messages: ChatMessage[]\n isStreaming?: boolean\n isReasoningRevealing?: boolean\n isLastTurn?: boolean\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n sessionStatus?: string\n level?: 1 | 2\n forceExpanded?: boolean\n customization?: ChatViewCustomization\n}\n\nexport type TurnDisplayMode = \"compact\" | \"detail\"\n\nconst EMPTY_MESSAGES: ChatMessage[] = []\n\nconst EMPTY_AGENT_LOOPS: Record<string, { toolCallId: string; workflowRunId?: string }> = {}\n\n// The message list virtualizer may unmount old turns. Keep the user's choice\n// for the lifetime of this page without making it a global preference.\nconst turnDisplayModeMemory = new Map<string, TurnDisplayMode>()\n\nconst SHOW_FILE_DELIVERY_CARDS = false\n\nexport function defaultTurnDisplayMode({\n forceExpanded,\n hasActionableToolCall,\n isStreaming,\n}: {\n forceExpanded: boolean\n hasActionableToolCall: boolean\n isStreaming: boolean\n}): TurnDisplayMode {\n return forceExpanded || hasActionableToolCall || isStreaming ? \"detail\" : \"compact\"\n}\n\nexport function resolveTurnDisplayMode({\n isStreaming: _isStreaming,\n displayMode,\n}: {\n isStreaming: boolean\n displayMode: TurnDisplayMode\n}): TurnDisplayMode {\n return displayMode\n}\n\n// 与 packages/agent-react 的同名同签名函数保持一致,避免两套聊天界面显示不同耗时。\nexport function formatExecutionDuration(durationMs: number) {\n const totalSeconds = Math.max(0, Math.round(durationMs / 1000))\n const minutes = Math.floor(totalSeconds / 60)\n const seconds = totalSeconds % 60\n return minutes > 0 ? `${minutes}分${seconds}秒` : `${seconds}秒`\n}\n\nexport function getExecutionDurationMs({\n messages,\n isStreaming,\n now = null,\n}: {\n messages: ChatMessage[]\n isStreaming: boolean\n now?: number | null\n}) {\n const knownDuration = messages.reduce(\n (total, message) => {\n if (typeof message.duration_ms === \"number\" && message.duration_ms > 0) {\n return total + message.duration_ms\n }\n return (\n total +\n (message.tool_calls ?? []).reduce(\n (toolTotal, toolCall) =>\n toolTotal +\n (typeof toolCall.duration_ms === \"number\" && toolCall.duration_ms > 0\n ? toolCall.duration_ms\n : 0),\n 0,\n )\n )\n },\n 0,\n )\n if (!isStreaming || now === null) return knownDuration\n\n const startedAt = messages\n .map((message) => (message.timestamp ? Date.parse(message.timestamp) : Number.NaN))\n .filter((value) => Number.isFinite(value))\n .sort((a, b) => a - b)[0]\n if (startedAt === undefined) return knownDuration\n return Math.max(knownDuration, now - startedAt)\n}\n\nfunction findLastExceptionalEvent(messages: ChatMessage[]) {\n for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {\n const messageStatus = messages[messageIndex].status\n if (messageStatus === \"failed\") return { messageIndex, status: \"error\" as const }\n if (messageStatus === \"interrupted\") return { messageIndex, status: \"cancelled\" as const }\n const toolCalls = messages[messageIndex].tool_calls ?? []\n for (let toolIndex = toolCalls.length - 1; toolIndex >= 0; toolIndex -= 1) {\n const status = toolCalls[toolIndex].status\n if (status === \"error\" || status === \"cancelled\") {\n return { messageIndex, status }\n }\n }\n }\n return null\n}\n\nfunction executionSummaryLabel({\n messages,\n isStreaming,\n durationMs,\n sessionStatus,\n askAnswers,\n}: {\n messages: ChatMessage[]\n isStreaming: boolean\n durationMs: number\n sessionStatus?: string\n askAnswers?: Record<string, AskUserAnswerData>\n}) {\n if (isStreaming) {\n return durationMs > 0\n ? `正在执行 ${formatExecutionDuration(durationMs)}`\n : \"正在执行\"\n }\n if (\n sessionStatus === \"waiting_for_input\" &&\n messages.some((message) =>\n (message.tool_calls ?? []).some(\n (toolCall) =>\n formatToolName(toolCall.name) === \"AskUserQuestion\" &&\n toolCall.status === \"awaiting_answer\" &&\n !askAnswers?.[toolCall.id],\n ),\n )\n ) {\n return \"等待输入\"\n }\n const completedLabel = durationMs > 0\n ? `执行完成 ${formatExecutionDuration(durationMs)}`\n : \"执行完成\"\n const lastExceptionalEvent = findLastExceptionalEvent(messages)\n if (lastExceptionalEvent?.status === \"cancelled\") {\n const recovered = messages\n .slice(lastExceptionalEvent.messageIndex + 1)\n .some(hasRenderableMessageContent)\n return recovered ? `${completedLabel} · 部分步骤未完成` : \"执行已中断\"\n }\n return completedLabel\n}\n\nfunction getMessageText(message: ChatMessage) {\n return typeof message.content === \"string\"\n ? message.content.trim()\n : message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\")\n .trim()\n}\n\ntype OrderedMessagePart =\n | { type: \"text\"; key: string; content: ChatMessage[\"content\"] }\n | { type: \"tools\"; key: string; toolCalls: ToolCallInfo[] }\n\n// 与 packages/agent-react 的同名同签名函数保持一致:projection blocks 是\n// 单条消息内 part 顺序的唯一来源,不能把整条消息二分类成 text-first/tool-first。\nfunction getOrderedMessageParts(\n message: ChatMessage,\n toolCalls: ToolCallInfo[],\n): OrderedMessagePart[] {\n const blocks = message.blocks ?? []\n if (!blocks.some((block) => block.type === \"text\") ||\n !blocks.some((block) => block.type === \"tool_use\")) return []\n const toolsById = new Map(toolCalls.map((toolCall) => [toolCall.id, toolCall]))\n const seenToolIds = new Set<string>()\n const parts: OrderedMessagePart[] = []\n for (const [index, block] of blocks.entries()) {\n if (block.type === \"text\" && block.content != null && block.content !== \"\") {\n const content = Array.isArray(block.content)\n ? block.content as ChatMessage[\"content\"]\n : String(block.content)\n parts.push({ type: \"text\", key: `text-${index}`, content })\n }\n if (block.type !== \"tool_use\" || !block.tool_call_id) continue\n const toolCall = toolsById.get(block.tool_call_id)\n if (!toolCall) continue\n seenToolIds.add(toolCall.id)\n const previous = parts[parts.length - 1]\n if (previous?.type === \"tools\") previous.toolCalls.push(toolCall)\n else parts.push({ type: \"tools\", key: `tools-${index}`, toolCalls: [toolCall] })\n }\n const missingTools = toolCalls.filter((toolCall) => !seenToolIds.has(toolCall.id))\n if (seenToolIds.size === 0) return []\n if (missingTools.length > 0) {\n parts.push({ type: \"tools\", key: \"tools-missing\", toolCalls: missingTools })\n }\n return parts\n}\n\nfunction hasRenderableMessageContent(message: ChatMessage) {\n return (\n Boolean(getMessageText(message)) ||\n getImageParts(message.content).length > 0 ||\n getFileParts(message.content).length > 0\n )\n}\n\nfunction getLastContentMessage(messages: ChatMessage[]) {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (hasRenderableMessageContent(messages[index])) {\n return messages[index]\n }\n }\n return null\n}\n\nfunction getSuccessfulFileOutputToolCalls(toolCalls: ToolCallInfo[]) {\n const outputsByPath = new Map<string, ToolCallInfo>()\n for (const toolCall of toolCalls) {\n const toolName = formatToolName(toolCall.name)\n if (\n (toolName !== \"Write\" && toolName !== \"Edit\" && toolName !== \"MultiEdit\") ||\n toolCall.status !== \"done\"\n ) continue\n const filePath = extractToolFilePath(toolCall)\n if (filePath) outputsByPath.set(filePath, toolCall)\n }\n return [...outputsByPath.values()]\n}\n\ntype ToolRenderItem =\n | { key: string; kind: \"single\"; toolCall: ToolCallInfo }\n | { key: string; kind: \"read_group\"; toolCalls: ToolCallInfo[] }\n\nfunction groupDetailedToolCalls(toolCalls: ToolCallInfo[]): ToolRenderItem[] {\n const items: ToolRenderItem[] = []\n let index = 0\n\n while (index < toolCalls.length) {\n const toolCall = toolCalls[index]\n const normalizedName = formatToolName(toolCall.name)\n if (normalizedName !== \"Read\") {\n items.push({ key: toolCall.id, kind: \"single\", toolCall })\n index += 1\n continue\n }\n\n const group = [toolCall]\n index += 1\n while (index < toolCalls.length && formatToolName(toolCalls[index].name) === \"Read\") {\n group.push(toolCalls[index])\n index += 1\n }\n\n items.push(\n group.length === 1\n ? { key: group[0].id, kind: \"single\", toolCall: group[0] }\n : {\n key: `read_group-${group.map((item) => item.id).join(\"-\")}`,\n kind: \"read_group\",\n toolCalls: group,\n },\n )\n }\n\n return items\n}\n\nfunction AssistantTurnBlockBase({\n sessionId,\n messages: rawMessages,\n isStreaming = false,\n isReasoningRevealing = true,\n askAnswers,\n onAnswer,\n sessionStatus,\n level = 1,\n forceExpanded = false,\n customization,\n}: Props) {\n const isDeveloperMode = useChatRenderMode() === \"developer\"\n const messages = Array.isArray(rawMessages) ? rawMessages : []\n const allToolCalls = useMemo(() => messages.flatMap((m) => m.tool_calls ?? []), [messages])\n const detailToolCalls = useMemo(\n () =>\n allToolCalls.filter(\n (toolCall) =>\n formatToolName(toolCall.name) !== \"AskUserQuestion\" &&\n !isPlanUpdateTool(toolCall) &&\n !isWorkflowRunToolName(toolCall.name),\n ),\n [allToolCalls],\n )\n const workflowRunToolCallIds = useMemo(\n () =>\n allToolCalls.filter((toolCall) => isWorkflowRunToolName(toolCall.name)).map((tc) => tc.id),\n [allToolCalls],\n )\n const hasAgentToolCall = useMemo(\n () =>\n allToolCalls.some((toolCall) => formatToolName(toolCall.name) === \"Agent\") ||\n workflowRunToolCallIds.length > 0,\n [allToolCalls, workflowRunToolCallIds],\n )\n const firstEntryId = rawMessages[0]?.entry_id\n const displayModeMemoryKey = sessionId && firstEntryId ? `${sessionId}:${firstEntryId}` : null\n const sessionMessages = useSessionState(sessionId, (state) =>\n hasAgentToolCall ? state.messages : EMPTY_MESSAGES,\n )\n const agentLoops = useSessionState(sessionId, (state) =>\n hasAgentToolCall ? state.agentLoops : EMPTY_AGENT_LOOPS,\n )\n const turnMessages = useMemo(\n () =>\n hasAgentToolCall\n ? collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops })\n : messages,\n [agentLoops, hasAgentToolCall, messages, sessionMessages],\n )\n const assistantTurnMessages = useMemo(\n () => turnMessages.filter((message) => message.role === \"assistant\"),\n [turnMessages],\n )\n const hasActionableToolCall = useMemo(\n () =>\n assistantTurnMessages.some(\n (message) =>\n message.status === \"failed\" ||\n message.status === \"interrupted\" ||\n (message.tool_calls ?? []).some(\n (toolCall) => toolCall.status === \"error\" || toolCall.status === \"cancelled\",\n ),\n ),\n [assistantTurnMessages],\n )\n const [displayMode, setDisplayMode] = useState<TurnDisplayMode>(\n () =>\n forceExpanded\n ? \"detail\"\n : (displayModeMemoryKey ? turnDisplayModeMemory.get(displayModeMemoryKey) : undefined) ??\n defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall, isStreaming }),\n )\n const wasStreamingRef = useRef(isStreaming)\n useEffect(() => {\n if (\n wasStreamingRef.current &&\n !isStreaming &&\n !forceExpanded &&\n !(displayModeMemoryKey && turnDisplayModeMemory.has(displayModeMemoryKey))\n ) {\n setDisplayMode(\n defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall, isStreaming }),\n )\n }\n wasStreamingRef.current = isStreaming\n }, [displayModeMemoryKey, forceExpanded, hasActionableToolCall, isStreaming])\n const persistentAskUserQuestions = useMemo(\n () => getPersistentAskUserQuestions(assistantTurnMessages),\n [assistantTurnMessages],\n )\n const workflowChildToolCalls = useMemo(() => {\n if (workflowRunToolCallIds.length === 0) return []\n const loopNames = new Set(\n Object.entries(agentLoops)\n .filter(\n ([, info]) => info.workflowRunId && workflowRunToolCallIds.includes(info.workflowRunId),\n )\n .map(([loopName]) => loopName),\n )\n if (loopNames.size === 0) return []\n return sessionMessages\n .filter((message) => message.loop_name && loopNames.has(message.loop_name))\n .flatMap((message) => message.tool_calls ?? [])\n }, [agentLoops, sessionMessages, workflowRunToolCallIds])\n const turnToolCalls = useMemo(\n () => [...assistantTurnMessages.flatMap((m) => m.tool_calls ?? []), ...workflowChildToolCalls],\n [assistantTurnMessages, workflowChildToolCalls],\n )\n const fileToolCalls = useMemo(\n () => getSuccessfulFileOutputToolCalls(turnToolCalls),\n [turnToolCalls],\n )\n const resourceBlocks = useMemo(\n () => collectInlineToolUiCards(assistantTurnMessages),\n [assistantTurnMessages],\n )\n const previewToolCalls = useMemo(\n () => collectPreviewToolUiCards(assistantTurnMessages),\n [assistantTurnMessages],\n )\n const workflowRunToolCalls = useMemo(\n () =>\n messages\n .filter((message) => message.role === \"assistant\")\n .flatMap((message) => message.tool_calls ?? [])\n .filter((turnToolCall) => isWorkflowRunToolName(turnToolCall.name)),\n [messages],\n )\n const finalMessage = useMemo(\n () => getLastContentMessage(messages),\n [messages],\n )\n const finalOrderedParts = useMemo(\n () => finalMessage\n ? getOrderedMessageParts(\n finalMessage,\n (finalMessage.tool_calls ?? []).filter(\n (toolCall) =>\n !isPlanUpdateTool(toolCall) &&\n formatToolName(toolCall.name) !== \"AskUserQuestion\" &&\n !isWorkflowRunToolName(toolCall.name),\n ),\n )\n : [],\n [finalMessage],\n )\n const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode })\n const compactOrderedToolIds = useMemo(\n () => new Set(\n effectiveMode === \"compact\" && finalOrderedParts.length > 0\n ? finalOrderedParts.flatMap((part) => part.type === \"tools\" ? part.toolCalls.map((tool) => tool.id) : [])\n : [],\n ),\n [effectiveMode, finalOrderedParts],\n )\n const finalMessageText = useMemo(\n () =>\n finalMessage ? getTextContent(normalizeMessageContent(finalMessage.content)).trim() : \"\",\n [finalMessage],\n )\n const hasInterruptedState = messages.some((message) => message.status === \"interrupted\")\n const hasFailedWithoutContent = messages.some(\n (message) => message.status === \"failed\" && !hasRenderableMessageContent(message),\n )\n const hasExecutionProcess =\n detailToolCalls.length > 0 ||\n workflowRunToolCalls.length > 0 ||\n persistentAskUserQuestions.length > 0 ||\n messages.some((message) => Boolean(message.reasoning)) ||\n resourceBlocks.length > 0\n const client = useOptionalBladeClient()\n const executionDurationMs = getExecutionDurationMs({\n messages,\n isStreaming,\n })\n const [clock, setClock] = useState(() => performance.now())\n useEffect(() => {\n if (!isStreaming) return\n const timer = window.setInterval(() => setClock(performance.now()), 1000)\n return () => window.clearInterval(timer)\n }, [isStreaming])\n const liveExecutionDurationMs = isStreaming\n ? getExecutionDurationMs({\n messages, isStreaming,\n now: sessionId ? getServerTime(client, clock) : Date.now(),\n })\n : executionDurationMs\n\n const observedMemoryRefs = useMemo(() => collectMemoryRefs(messages), [messages])\n const [cachedMemoryRefs, setCachedMemoryRefs] = useState<MemoryRefInfo[]>([])\n useEffect(() => {\n if (observedMemoryRefs.length > 0) setCachedMemoryRefs(observedMemoryRefs)\n }, [observedMemoryRefs])\n const memoryRefs =\n observedMemoryRefs.length > 0 ? observedMemoryRefs : cachedMemoryRefs\n\n return (\n <div\n aria-busy={isStreaming || undefined}\n part=\"assistant-turn\"\n className={cn(\n \"blade-chat-assistant-turn flex flex-col gap-3\",\n level === 2 && \"gap-2.5\",\n customization?.classNames?.assistantTurn,\n )}\n >\n {memoryRefs.length > 0 && (\n <MemoryRefsHint refs={memoryRefs} />\n )}\n {hasInterruptedState && (\n <div className=\"ml-4 w-fit rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]\">\n 已中断\n </div>\n )}\n {hasFailedWithoutContent && (\n <div className=\"ml-4 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]\">\n 生成失败\n </div>\n )}\n {hasExecutionProcess && (\n <div className=\"flex w-full items-start gap-2.5\">\n <span\n className=\"grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]\"\n aria-hidden=\"true\"\n >\n <Bot size={16} />\n </span>\n <div className=\"min-w-0 flex-1 pt-0.5\">\n <button\n type=\"button\"\n onClick={() => {\n const nextMode = displayMode === \"detail\" ? \"compact\" : \"detail\"\n setDisplayMode(nextMode)\n if (displayModeMemoryKey) turnDisplayModeMemory.set(displayModeMemoryKey, nextMode)\n }}\n aria-expanded={effectiveMode === \"detail\"}\n aria-label={effectiveMode === \"detail\" ? \"收起执行过程\" : \"展开执行过程\"}\n data-testid=\"assistant-execution-summary\"\n className=\"inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <span className=\"min-w-0 truncate\">\n {executionSummaryLabel({\n messages: assistantTurnMessages,\n isStreaming,\n durationMs: liveExecutionDurationMs,\n sessionStatus,\n askAnswers,\n })}\n </span>\n <ChevronRight\n size={14}\n style={{\n transitionDuration: \"var(--motion-duration-base)\",\n transitionTimingFunction: \"var(--motion-ease-enter)\",\n }}\n className={cn(\n \"shrink-0 transition-transform\",\n effectiveMode === \"detail\" && \"rotate-90\",\n )}\n aria-hidden=\"true\"\n />\n </button>\n <div className=\"mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]\" />\n </div>\n </div>\n )}\n {hasExecutionProcess && effectiveMode === \"detail\" ? (\n <div className=\"ml-10 flex flex-col gap-1\">\n <AssistantMessages\n messages={assistantTurnMessages}\n isStreaming={isStreaming}\n isReasoningRevealing={isReasoningRevealing}\n sessionId={sessionId}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n sessionStatus={sessionStatus}\n level={level}\n turnToolCalls={turnToolCalls}\n showToolDetails\n hideAskUserQuestions\n hideMessageContentFor={finalMessage}\n customization={customization}\n />\n {workflowRunToolCalls.map((workflowToolCall) => (\n <WorkflowRunBlock\n key={workflowToolCall.id}\n toolCall={workflowToolCall}\n sessionId={sessionId}\n />\n ))}\n </div>\n ) : null}\n {resourceBlocks.some((block) => !compactOrderedToolIds.has(block.toolCallId)) ? (\n <div className=\"ml-10 flex flex-col gap-3\">\n {resourceBlocks.filter((block) => !compactOrderedToolIds.has(block.toolCallId)).map((block) => (\n <ToolUiCard key={block.key} card={block.card} sessionId={sessionId} />\n ))}\n </div>\n ) : null}\n {previewToolCalls.some(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)) ? (\n <div className=\"ml-10 flex flex-wrap gap-x-3 gap-y-1\">\n {previewToolCalls.filter(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)).map(({ key, toolCall, blocks }) => (\n <ToolPreviewAction\n key={key}\n toolCall={toolCall}\n sessionId={sessionId}\n turnBlocks={blocks}\n className=\"text-xs leading-[22px]\"\n />\n ))}\n </div>\n ) : null}\n {isDeveloperMode && fileToolCalls.some((toolCall) => !compactOrderedToolIds.has(toolCall.id)) ? (\n <div className=\"ml-10 flex flex-wrap gap-x-3 gap-y-1\">\n {fileToolCalls.filter((toolCall) => !compactOrderedToolIds.has(toolCall.id)).map((toolCall) => (\n <ToolFilePreviewAction\n key={toolCall.id}\n toolCall={toolCall}\n sessionId={sessionId}\n className=\"max-w-full text-xs leading-[22px] text-[hsl(var(--swf-link-text))]\"\n />\n ))}\n </div>\n ) : null}\n {effectiveMode === \"compact\" && finalMessage && finalOrderedParts.length > 0 ? (\n <div className=\"ml-10 flex flex-col gap-3\">\n {finalOrderedParts.map((part) => part.type === \"text\" ? (\n <AssistantMessageContent\n key={part.key}\n message={{ ...finalMessage, content: part.content }}\n isStreaming={isStreaming && finalMessage === messages[messages.length - 1]}\n sessionId={sessionId}\n reasoning={undefined}\n className={customization?.classNames?.assistantText}\n toolCalls={turnToolCalls}\n />\n ) : (\n <div key={part.key} className=\"flex flex-col gap-3\">\n {part.toolCalls.flatMap((toolCall) => [\n ...resourceBlocks.filter((block) => block.toolCallId === toolCall.id).map((block) => (\n <ToolUiCard key={block.key} card={block.card} sessionId={sessionId} />\n )),\n ...previewToolCalls.filter((item) => item.toolCall.id === toolCall.id).map(({ key, toolCall: previewToolCall, blocks }) => (\n <ToolPreviewAction key={key} toolCall={previewToolCall} sessionId={sessionId} turnBlocks={blocks} className=\"text-xs leading-[22px]\" />\n )),\n ...fileToolCalls.filter((fileToolCall) => fileToolCall.id === toolCall.id).map((fileToolCall) => (\n <ToolFilePreviewAction key={fileToolCall.id} toolCall={fileToolCall} sessionId={sessionId} className=\"max-w-full text-xs leading-[22px] text-[hsl(var(--swf-link-text))]\" />\n )),\n ])}\n </div>\n ))}\n </div>\n ) : null}\n {finalMessage && finalOrderedParts.length === 0 ? (\n <div className=\"ml-10\">\n <AssistantMessageContent\n message={finalMessage}\n isStreaming={isStreaming && finalMessage === messages[messages.length - 1]}\n sessionId={sessionId}\n reasoning={undefined}\n className={customization?.classNames?.assistantText}\n toolCalls={turnToolCalls}\n />\n </div>\n ) : null}\n <PersistentAskUserQuestions\n questions={persistentAskUserQuestions}\n sessionId={sessionId}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n sessionStatus={sessionStatus}\n level={level}\n customization={customization}\n />\n {SHOW_FILE_DELIVERY_CARDS && level === 1 && (\n <FileDeliveryCards toolCalls={turnToolCalls} sessionId={sessionId} />\n )}\n {level === 1 && !isStreaming && finalMessageText ? (\n <MessageActions content={finalMessageText} className=\"-mt-1.5\" />\n ) : null}\n </div>\n )\n}\n\nfunction areAssistantTurnBlockPropsEqual(prev: Props, next: Props) {\n return (\n prev.turnKey === next.turnKey &&\n prev.sessionId === next.sessionId &&\n prev.messages === next.messages &&\n prev.isStreaming === next.isStreaming &&\n prev.isReasoningRevealing === next.isReasoningRevealing &&\n prev.isLastTurn === next.isLastTurn &&\n prev.askAnswers === next.askAnswers &&\n prev.onAnswer === next.onAnswer &&\n prev.sessionStatus === next.sessionStatus &&\n prev.level === next.level &&\n prev.forceExpanded === next.forceExpanded &&\n prev.customization === next.customization\n )\n}\n\nexport const AssistantTurnBlock = memo(AssistantTurnBlockBase, areAssistantTurnBlockPropsEqual)\n\nfunction PersistentAskUserQuestions({\n questions,\n sessionId,\n askAnswers,\n onAnswer,\n sessionStatus,\n level,\n customization,\n}: {\n questions: ReturnType<typeof getPersistentAskUserQuestions>\n sessionId: string\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n sessionStatus?: string\n level: 1 | 2\n customization?: ChatViewCustomization\n}) {\n const activeQuestionId = questions\n .filter(({ toolCall }) => toolCall.status === \"pending\")\n .at(-1)?.toolCall.id\n return questions.map(({ toolCall, turnBlocks }) =>\n customization?.components?.ToolCall ? (\n <customization.components.ToolCall\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n level={level}\n turnBlocks={turnBlocks}\n customization={customization}\n />\n ) : (\n <ToolCallBlock\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n isActiveQuestion={toolCall.id === activeQuestionId}\n level={level}\n turnBlocks={turnBlocks}\n customization={customization}\n />\n ),\n )\n}\n\nfunction DetailedToolCallList({\n toolCalls,\n message,\n sessionId,\n sessionStatus,\n askAnswers,\n onAnswer,\n level,\n customization,\n}: {\n toolCalls: ToolCallInfo[]\n message: ChatMessage\n sessionId: string\n sessionStatus?: string\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n level: 1 | 2\n customization?: ChatViewCustomization\n}) {\n return (\n <div className=\"flex flex-col gap-1\">\n {groupDetailedToolCalls(toolCalls).map((item) => {\n if (item.kind === \"read_group\") {\n return (\n <CompactToolGroupBlock\n key={item.key}\n toolCalls={item.toolCalls}\n reasoning={undefined}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n turnBlocks={message.blocks}\n level={level}\n customization={customization}\n />\n )\n }\n const { toolCall } = item\n if (isWorkflowRunToolName(toolCall.name)) return null\n return customization?.components?.ToolCall ? (\n <customization.components.ToolCall\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n level={level}\n turnBlocks={message.blocks}\n reasoning={undefined}\n customization={customization}\n />\n ) : (\n <ToolCallBlock\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n level={level}\n turnBlocks={message.blocks}\n customization={customization}\n />\n )\n })}\n </div>\n )\n}\n\nfunction AssistantMessages({\n messages,\n isStreaming,\n isReasoningRevealing = true,\n sessionId,\n askAnswers,\n onAnswer,\n sessionStatus,\n level,\n showToolDetails,\n hideAskUserQuestions,\n hideMessageContentFor,\n customization,\n turnToolCalls,\n}: {\n messages: ChatMessage[]\n isStreaming: boolean\n isReasoningRevealing?: boolean\n sessionId: string\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n sessionStatus?: string\n level: 1 | 2\n showToolDetails: boolean\n hideAskUserQuestions?: boolean\n hideMessageContentFor?: ChatMessage | null\n customization?: ChatViewCustomization\n turnToolCalls?: ToolCallInfo[]\n}) {\n const isDeveloperMode = useChatRenderMode() === \"developer\"\n const latestReasoningIndex = isStreaming\n ? findLatestReasoningMessageIndex(messages)\n : -1\n\n return messages.map((message, index) =>\n isRenderableAssistantMessage(message, isStreaming && index === messages.length - 1)\n ? (() => {\n const isStreamingLastMessage = isStreaming && index === messages.length - 1\n const isReasoningStreamingLastMessage = isStreamingLastMessage && isReasoningRevealing\n const reasoning = message.reasoning\n const showReasoning =\n !!reasoning && (isDeveloperMode || (isStreaming && index === latestReasoningIndex))\n const toolCalls = (message.tool_calls ?? []).filter(\n (toolCall) =>\n !isPlanUpdateTool(toolCall) &&\n (!hideAskUserQuestions || formatToolName(toolCall.name) !== \"AskUserQuestion\"),\n )\n const hasToolCalls = toolCalls.length > 0\n const orderedParts = getOrderedMessageParts(message, toolCalls)\n\n return (\n <div\n key={message.entry_id ?? `${message.timestamp ?? \"assistant\"}-${index}`}\n className=\"flex flex-col gap-1\"\n >\n {showReasoning && (\n <Reasoning\n isStreaming={isReasoningStreamingLastMessage}\n part=\"thinking\"\n className=\"blade-chat-thinking\"\n >\n <ReasoningTrigger\n wordCount={reasoning.length}\n className=\"gap-1 rounded-none p-0 text-xs leading-[22px]\"\n >\n <span>{isReasoningStreamingLastMessage ? \"正在思考\" : \"已思考\"}</span>\n </ReasoningTrigger>\n <ReasoningContent className=\"mt-1.5 rounded-none border-0 bg-transparent px-0 py-0 text-xs leading-[22px]\">\n {reasoning}\n </ReasoningContent>\n </Reasoning>\n )}\n {orderedParts.length > 0 ? orderedParts.map((part) =>\n part.type === \"text\" ? (\n <AssistantMessageContent\n key={part.key}\n message={{ ...message, content: part.content }}\n isStreaming={isStreamingLastMessage}\n sessionId={sessionId}\n reasoning={undefined}\n toolCalls={turnToolCalls}\n compact\n className={cn(\n \"text-xs leading-[22px]\",\n customization?.classNames?.assistantText,\n )}\n />\n ) : showToolDetails ? (\n <DetailedToolCallList\n key={part.key}\n toolCalls={part.toolCalls}\n message={message}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n level={level}\n customization={customization}\n />\n ) : null,\n ) : message !== hideMessageContentFor ? (\n <AssistantMessageContent\n message={message}\n isStreaming={isStreamingLastMessage}\n sessionId={sessionId}\n reasoning={undefined}\n className={cn(\n \"text-xs leading-[22px]\",\n customization?.classNames?.assistantText,\n )}\n toolCalls={turnToolCalls}\n compact\n />\n ) : null}\n\n {orderedParts.length === 0 && hasToolCalls && showToolDetails ? (\n <DetailedToolCallList\n toolCalls={toolCalls}\n message={message}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n level={level}\n customization={customization}\n />\n ) : null}\n </div>\n )\n })()\n : null,\n )\n}\n\nfunction isRenderableAssistantMessage(message: ChatMessage, isStreaming: boolean) {\n if (message.reasoning || (message.tool_calls?.length ?? 0) > 0) {\n return true\n }\n\n const fileParts = getFileParts(message.content)\n const imageParts = getImageParts(message.content)\n const text = getMessageText(message)\n\n if (text || imageParts.length > 0 || fileParts.length > 0 || isStreaming) {\n return true\n }\n\n return (\n message.blocks?.some(\n (block) =>\n block.type === \"tool_ui\" &&\n block.tool_call_id &&\n isUiMeta(block.content) &&\n block.content.target === \"inline\",\n ) ?? false\n )\n}\n\nfunction CompactToolGroupBlock({\n toolCalls,\n reasoning,\n sessionId,\n sessionStatus,\n askAnswers,\n onAnswer,\n turnBlocks,\n level,\n customization,\n}: {\n toolCalls: ToolCallInfo[]\n reasoning?: string\n sessionId: string\n sessionStatus?: string\n askAnswers?: Record<string, AskUserAnswerData>\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n turnBlocks?: NonNullable<ChatMessage[\"blocks\"]>\n level: 1 | 2\n customization?: ChatViewCustomization\n}) {\n return (\n <div className=\"flex flex-col gap-1\">\n {toolCalls.map((toolCall) => {\n if (isWorkflowRunToolName(toolCall.name)) return null\n const CustomToolCall = customization?.components?.ToolCall\n return CustomToolCall ? (\n <CustomToolCall\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n level={level}\n turnBlocks={turnBlocks}\n customization={customization}\n />\n ) : (\n <ToolCallBlock\n key={toolCall.id}\n toolCall={toolCall}\n answerData={askAnswers?.[toolCall.id]}\n onAnswer={onAnswer}\n answered={toolCallAnswered(toolCall, sessionStatus, askAnswers?.[toolCall.id])}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n level={level}\n turnBlocks={turnBlocks}\n reasoning={undefined}\n customization={customization}\n />\n )\n })}\n {reasoning ? <ThinkingBadge reasoning={reasoning} variant=\"block\" /> : null}\n </div>\n )\n}\n\nfunction AssistantMessageContent({\n message,\n isStreaming,\n sessionId,\n reasoning,\n className,\n toolCalls,\n compact = false,\n}: {\n message: ChatMessage\n isStreaming: boolean\n sessionId: string\n reasoning?: string\n className?: string\n compact?: boolean\n toolCalls?: ToolCallInfo[]\n}) {\n const renderAssistantText = useChatCustomization()?.renderers?.assistantText\n const effectiveToolCalls = toolCalls ?? message.tool_calls\n const citations = useMemo(\n () => buildCitationsFromToolCalls(effectiveToolCalls),\n [effectiveToolCalls],\n )\n const fileParts = getFileParts(message.content)\n const imageParts = getImageParts(message.content)\n const text =\n typeof message.content === \"string\"\n ? message.content.trim()\n : message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\")\n .trim()\n\n const failed = message.status === \"failed\"\n const customText = text\n ? renderAssistantText?.({ message, streaming: isStreaming, compact, sessionId })\n : undefined\n if (\n !text &&\n imageParts.length === 0 &&\n fileParts.length === 0 &&\n !reasoning &&\n !failed\n ) {\n return null\n }\n\n return (\n <div className=\"flex flex-col gap-3\">\n {failed ? (\n <div className=\"w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]\">\n 生成失败\n </div>\n ) : null}\n {imageParts.length > 0 && (\n <div className=\"grid gap-2\">\n {imageParts.map((part) => (\n <MessageImage\n key={part.image_url.url}\n src={part.image_url.url}\n width={part.image_url.width}\n height={part.image_url.height}\n alt=\"消息附件\"\n className=\"max-h-72 rounded-xl border border-[hsl(var(--border))] object-cover\"\n />\n ))}\n </div>\n )}\n <MessageFileAttachmentList files={fileParts} />\n {text && customText != null ? (\n customText\n ) : text ? (\n <AssistantText\n text={text}\n isStreaming={isStreaming}\n sessionId={sessionId}\n messageId={message.entry_id}\n reasoning={reasoning}\n className={className}\n citations={citations}\n />\n ) : null}\n {!text && reasoning ? <ThinkingBadge reasoning={reasoning} variant=\"block\" /> : null}\n </div>\n )\n}\n\nfunction AssistantText({\n text,\n isStreaming,\n sessionId,\n messageId,\n reasoning,\n className,\n citations,\n}: {\n text: string\n isStreaming: boolean\n sessionId: string\n messageId?: string\n reasoning?: string\n className?: string\n citations?: ReturnType<typeof buildCitationsFromToolCalls>\n}) {\n const session = useSessionHandle(sessionId)\n const sendMessage = useCallback(\n async (content: string) => {\n if (session) void sendToSession(session, content)\n },\n [session],\n )\n\n const cardCtx = useMemo<CardContextValue>(\n () => ({ sessionId, messageId, sendMessage }),\n [sessionId, messageId, sendMessage],\n )\n\n return (\n <div\n part=\"assistant-text\"\n className={cn(\"blade-chat-assistant-text text-[15px] leading-8 text-[hsl(var(--foreground))]\", className)}\n >\n <CardContext.Provider value={cardCtx}>\n <MarkdownContent\n mode={isStreaming ? \"streaming\" : \"static\"}\n sessionId={sessionId}\n className=\"prose prose-invert chat-prose inline max-w-none [&_li>p]:inline [&_p:last-child]:inline\"\n controls={{ code: true }}\n citations={citations}\n >\n {text}\n </MarkdownContent>\n </CardContext.Provider>\n {reasoning ? <ThinkingBadge reasoning={reasoning} /> : null}\n </div>\n )\n}\n\n/** 一轮消息里引用到的记忆(按 id 去重,保持首次出现的顺序)。 */\nexport function collectMemoryRefs(messages: ChatMessage[]): MemoryRefInfo[] {\n const refs = new Map<number, MemoryRefInfo>()\n for (const message of messages) {\n for (const ref of message.memory_refs ?? []) if (!refs.has(ref.id)) refs.set(ref.id, ref)\n }\n return [...refs.values()]\n}\n\nexport function MemoryRefsHint({ refs: rawRefs, className }: { refs: MemoryRefInfo[]; className?: string }) {\n const refs = Array.isArray(rawRefs) ? rawRefs : []\n const [expanded, setExpanded] = useState(false)\n const memoriesHref = useChatEnvironment().memoriesHref\n const hasSkill = refs.some((r) => r.skill_name)\n const label = hasSkill ? \"参考了该技能的历史经验\" : \"参考了历史经验\"\n\n return (\n <div\n part=\"memory-refs\"\n className={cn(\"blade-chat-memory-refs relative z-[1] ml-1 w-[calc(100%-0.25rem)] max-w-[680px] self-start\", className)}\n >\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-lg border border-[hsl(var(--primary)/0.22)] bg-[hsl(var(--primary)/0.07)] px-3 text-xs font-medium text-[hsl(var(--primary))] transition-colors hover:bg-[hsl(var(--primary)/0.12)]\"\n >\n <BookOpen size={12} />\n <span>{label}({refs.length})</span>\n <ChevronRight\n size={10}\n className={cn(\"transition-transform\", expanded && \"rotate-90\")}\n />\n </button>\n {expanded && (\n <div className=\"mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5\">\n {refs.map((ref) => (\n <div\n key={ref.id}\n className=\"rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5\"\n >\n <p className=\"line-clamp-2 break-words text-xs leading-5 text-[hsl(var(--foreground)/0.86)]\">\n {ref.content_preview}\n </p>\n {ref.skill_name && (\n <span className=\"mt-1.5 inline-flex rounded-md bg-[hsl(var(--primary)/0.09)] px-2 py-0.5 text-[10px] font-medium text-[hsl(var(--primary))]\">\n {ref.skill_name}\n </span>\n )}\n </div>\n ))}\n {memoriesHref ? <a\n href={memoriesHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex h-7 self-start items-center gap-1 rounded-lg px-2 text-[11px] font-medium text-[hsl(var(--primary))] transition-colors hover:bg-[hsl(var(--primary)/0.08)]\"\n >\n 查看全部经验\n <ArrowUpRight size={12} aria-hidden=\"true\" />\n </a> : null}\n </div>\n )}\n </div>\n )\n}\n","import { isToolUiCard, type ToolUiCard } from \"@blade-hq/agent-client/internal\"\nimport { LOOPBACK_HOSTS } from \"./loopback\"\n\n// 卡片判定(实例、守卫、可见性、身份、终态)统一由 @blade-hq/agent-client 的\n// shared/tool-ui-card 提供,这里只保留浏览器特有的地址改写。判定逻辑不许各写一份。\nexport type UiMeta = ToolUiCard\n\nexport const isUiMeta: (value: unknown) => value is UiMeta = isToolUiCard\n\n/** 工具界面给的本机地址换成当前页面的主机名(沙盒端口经同一主机访问)。 */\nexport function resolveBrowserResourceUri(\n value: string,\n browserHostname = typeof window === \"undefined\" ? \"\" : window.location.hostname,\n): string {\n if (!browserHostname) return value\n try {\n const url = new URL(value)\n if (!LOOPBACK_HOSTS.has(url.hostname)) return value\n url.hostname = browserHostname\n return url.toString()\n } catch {\n return value\n }\n}\n","/** 本机地址(沙盒里的服务在浏览器看来是 localhost)。 */\nexport const LOOPBACK_HOSTS: ReadonlySet<string> = new Set([\"127.0.0.1\", \"localhost\", \"[::1]\"])\n\nexport function isLoopbackUrl(rawUrl: string): boolean {\n try {\n return LOOPBACK_HOSTS.has(new URL(rawUrl).hostname)\n } catch {\n return false\n }\n}\n\nconst BLADE_OS_DEPLOY_PORT_START = 25001\nconst BLADE_OS_DEPLOY_PORT_END = 27000\n\nexport function rewriteForSandboxBrowser(rawUrl: string): string {\n try {\n const url = new URL(rawUrl)\n const port = Number(url.port)\n if (LOOPBACK_HOSTS.has(url.hostname) && port >= BLADE_OS_DEPLOY_PORT_START && port <= BLADE_OS_DEPLOY_PORT_END) {\n url.hostname = \"host.docker.internal\"\n }\n return url.toString()\n } catch {\n return rawUrl\n }\n}\n\n/** 在会话的沙盒浏览器里新开一个标签打开本机地址(沙盒里的服务只有沙盒浏览器访问得到)。 */\nexport async function openInSessionSandboxBrowser(\n client: { json: (method: \"POST\", path: string, body: unknown) => Promise<unknown> },\n sessionId: string,\n url: string,\n): Promise<void> {\n await client.json(\"POST\", `/api/sessions/${encodeURIComponent(sessionId)}/browser/tabs`, {\n url: rewriteForSandboxBrowser(url),\n })\n}\n","import { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-trigger\"\n {...props}\n />\n )\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return (\n <CollapsiblePrimitive.CollapsibleContent\n data-slot=\"collapsible-content\"\n {...props}\n />\n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n","\"use client\"\n\nimport type * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@blade-hq/ui/components/collapsible\"\nimport { cn } from \"../../lib/utils\"\nimport { BrainIcon, ChevronDownIcon, XIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport { Shimmer } from \"./shimmer\"\nimport { MarkdownContent } from \"../markdown/MarkdownContent\"\nimport { useChatEnvironment } from \"../runtime/environment\"\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from \"@blade-hq/ui/composites/dialog\"\n\ninterface ReasoningContextValue {\n isStreaming: boolean\n isOpen: boolean\n setIsOpen: (open: boolean) => void\n duration: number | undefined\n}\n\nconst ReasoningContext = createContext<ReasoningContextValue | null>(null)\n\nexport const useReasoning = () => {\n const context = useContext(ReasoningContext)\n if (!context) {\n throw new Error(\"Reasoning components must be used within Reasoning\")\n }\n return context\n}\n\nexport type ReasoningProps = ComponentProps<typeof CollapsiblePrimitive.Root> & {\n isStreaming?: boolean\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n duration?: number\n}\n\nconst MS_IN_S = 1000\n\nexport const Reasoning = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n onOpenChange,\n duration: durationProp,\n children,\n ...props\n }: ReasoningProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n prop: open,\n })\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: undefined,\n prop: durationProp,\n })\n\n const startTimeRef = useRef<number | null>(null)\n\n useEffect(() => {\n if (isStreaming) {\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now()\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S))\n startTimeRef.current = null\n }\n }, [isStreaming, setDuration])\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen)\n },\n [setIsOpen],\n )\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n )\n\n return (\n <ReasoningContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ReasoningContext.Provider>\n )\n },\n)\n\nexport type ReasoningTriggerProps = ComponentProps<\n typeof CollapsiblePrimitive.Trigger\n> & {\n wordCount: number\n}\n\nconst wordCountFormatter = new Intl.NumberFormat(\"zh-CN\")\n\nfunction formatWordCount(value: number) {\n return wordCountFormatter.format(value)\n}\n\nexport const ReasoningTrigger = memo(\n ({\n className,\n children,\n wordCount,\n ...props\n }: ReasoningTriggerProps) => {\n const { isStreaming, isOpen, duration } = useReasoning()\n const status = isStreaming || duration === 0 ? \"正在思考\" : \"已思考\"\n const detail = `${formatWordCount(wordCount)} 字`\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-fit items-center gap-2 rounded-full px-1 py-0.5 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n <BrainIcon className=\"size-4\" />\n <span className=\"inline-flex items-center gap-1.5\">\n {isStreaming || duration === 0 ? (\n <Shimmer duration={1}>{status}</Shimmer>\n ) : (\n <span>{status}</span>\n )}\n <span className=\"whitespace-nowrap tabular-nums text-[hsl(var(--muted-foreground))]/70\">\n · {detail}\n </span>\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-4 transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\",\n )}\n />\n </>\n )}\n </CollapsibleTrigger>\n )\n },\n)\n\nexport type ReasoningContentProps = ComponentProps<\n typeof CollapsiblePrimitive.Content\n> & {\n children: string\n}\n\nfunction ReasoningMarkdown({ children }: { children: string }) {\n const Injected = useChatEnvironment().ReasoningMarkdown\n if (Injected) return <Injected>{children}</Injected>\n return <MarkdownContent>{children}</MarkdownContent>\n}\n\nexport const ReasoningContent = memo(\n ({ className, children, ...props }: ReasoningContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-2 max-h-60 overflow-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2 text-sm\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n >\n <ReasoningMarkdown>{children}</ReasoningMarkdown>\n </CollapsibleContent>\n ),\n)\n\nexport type ThinkingBadgeProps = {\n reasoning: string\n variant?: \"inline\" | \"block\"\n onClick?: ComponentProps<\"button\">[\"onClick\"]\n}\n\nfunction compactReasoningText(text: string): string {\n return text\n .split(\"\\n\")\n .map((line) => line.trim())\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim()\n}\n\nexport function ThinkingBadge({ reasoning, variant = \"inline\", onClick }: ThinkingBadgeProps) {\n const compactReasoning = compactReasoningText(reasoning)\n const [open, setOpen] = useState(false)\n\n return (\n <span\n className={cn(\n \"relative inline-flex align-baseline\",\n variant === \"inline\" ? \"ml-1\" : \"ml-1 shrink-0\",\n )}\n >\n <button\n type=\"button\"\n onClick={(event) => {\n onClick?.(event)\n setOpen(true)\n }}\n className=\"inline-flex items-center rounded-full bg-[hsl(var(--muted))]/40 px-2 py-0.5 text-[10px] leading-none text-[hsl(var(--muted-foreground))]/70 transition-colors hover:bg-[hsl(var(--muted))]/60 hover:text-[hsl(var(--muted-foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n aria-label=\"查看深度思考\"\n aria-expanded={open}\n >\n 思考详情\n </button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent\n showCloseButton={false}\n className=\"m-0 flex max-h-[min(520px,calc(100vh-48px))] w-[min(760px,calc(100vw-48px))] flex-col gap-0 overflow-hidden p-0 text-left text-[13px] leading-6\"\n >\n <div className=\"flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2\">\n <DialogTitle className=\"text-xs font-medium text-[hsl(var(--muted-foreground))]\">\n 思考详情\n </DialogTitle>\n <DialogClose\n className=\"inline-flex h-6 w-6 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n aria-label=\"关闭思考详情\"\n >\n <XIcon size={14} aria-hidden=\"true\" />\n </DialogClose>\n </div>\n <div className=\"overflow-auto px-4 py-3 whitespace-normal [&_*]:whitespace-normal [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_ul]:my-1.5 [&_ol]:my-1.5\">\n <ReasoningMarkdown>{compactReasoning}</ReasoningMarkdown>\n </div>\n </DialogContent>\n </Dialog>\n </span>\n )\n}\n\nReasoning.displayName = \"Reasoning\"\nReasoningTrigger.displayName = \"ReasoningTrigger\"\nReasoningContent.displayName = \"ReasoningContent\"\n","import type { CSSProperties, ElementType } from \"react\"\nimport { memo, useMemo } from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface TextShimmerProps {\n children: string\n as?: ElementType\n className?: string\n duration?: number\n spread?: number\n}\n\nconst ShimmerComponent = ({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n}: TextShimmerProps) => {\n const dynamicSpread = useMemo(() => (children?.length ?? 0) * spread, [children, spread])\n\n return (\n <Component\n className={cn(\n \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n \"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]\",\n className,\n )}\n style={\n {\n \"--spread\": `${dynamicSpread}px`,\n backgroundImage:\n \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n backgroundPosition: \"100% center\",\n animation: `blade-shimmer-sweep ${duration}s linear infinite`,\n } as CSSProperties\n }\n >\n {children}\n </Component>\n )\n}\n\nexport const Shimmer = memo(ShimmerComponent)\n","import { createContext, useContext } from \"react\"\n\nexport interface CardContextValue {\n sendMessage?: (content: string) => Promise<void>\n sessionId?: string\n messageId?: string\n}\n\nexport const CardContext = createContext<CardContextValue>({})\n\nexport const useCardContext = () => useContext(CardContext)\n","import { Download, Film, Loader2 } from \"lucide-react\"\nimport { useMemo, useState } from \"react\"\nimport { useBladeClient, useBladeHost } from \"../context\"\nimport type { ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport { extractToolFilePath, formatToolName } from \"./display-utils\"\n\nconst AGENT_WORKSPACE_DIR_NAME = \"智能助手工作空间\"\n\nconst EXT_LABELS: Record<string, string> = {\n py: \"Python\",\n js: \"JavaScript\",\n ts: \"TypeScript\",\n tsx: \"TypeScript\",\n jsx: \"JavaScript\",\n md: \"Markdown\",\n html: \"HTML\",\n css: \"CSS\",\n json: \"JSON\",\n csv: \"CSV\",\n xlsx: \"Excel\",\n docx: \"Word\",\n pptx: \"PPT\",\n pdf: \"PDF\",\n sh: \"Shell\",\n sql: \"SQL\",\n}\n\nfunction toWorkspaceRelPath(rawPath: string, sessionId: string): string | null {\n const sessionRoot = `/root/${AGENT_WORKSPACE_DIR_NAME}/${sessionId}`\n let relPath: string\n if (rawPath.startsWith(`${sessionRoot}/`)) {\n relPath = rawPath.slice(sessionRoot.length + 1)\n } else if (!rawPath.startsWith(\"/\")) {\n relPath = rawPath.replace(/^\\.\\//, \"\")\n } else {\n return null\n }\n if (!relPath || relPath.startsWith(\"../\") || relPath.includes(\"/../\")) return null\n if (relPath.split(\"/\").some((segment) => segment.startsWith(\".\"))) return null\n return relPath\n}\n\nfunction basename(path: string): string {\n return path.split(\"/\").filter(Boolean).pop() || path\n}\n\nfunction getExtLabel(name: string): string {\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\"\n if (!ext || ext === name.toLowerCase()) return \"文件\"\n return EXT_LABELS[ext] ?? ext.toUpperCase()\n}\n\nconst VIDEO_EXTS = new Set([\"mp4\", \"webm\", \"mov\", \"mkv\", \"avi\"])\n\nfunction isVideoFile(name: string): boolean {\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\"\n return VIDEO_EXTS.has(ext)\n}\n\n/** 从该轮工具调用中提取智能体写入的工作区文件(去重、按出现顺序)。 */\nexport function collectDeliveredFiles(\n toolCalls: ToolCallInfo[],\n sessionId: string,\n): Array<{ relPath: string; name: string }> {\n const seen = new Set<string>()\n const files: Array<{ relPath: string; name: string }> = []\n for (const toolCall of toolCalls) {\n if (toolCall.status !== \"done\") continue\n const toolName = formatToolName(toolCall.name)\n if (toolName !== \"Write\" && toolName !== \"Edit\") continue\n const rawPath = extractToolFilePath(toolCall)\n if (!rawPath) continue\n const relPath = toWorkspaceRelPath(rawPath, sessionId)\n if (!relPath || seen.has(relPath)) continue\n seen.add(relPath)\n files.push({ relPath, name: basename(relPath) })\n }\n return files\n}\n\nexport function DeliveryCard({\n path,\n name,\n sessionId,\n description,\n displayName,\n compact = false,\n onOpen,\n onDownloadStarted,\n onDownloadSucceeded,\n}: {\n path: string\n name: string\n sessionId: string\n description?: string\n displayName?: string\n compact?: boolean\n onOpen?: () => void\n onDownloadStarted?: () => void\n onDownloadSucceeded?: () => void\n}) {\n const client = useBladeClient()\n const host = useBladeHost()\n const [opening, setOpening] = useState(false)\n const [downloading, setDownloading] = useState(false)\n\n const handleOpen = async () => {\n if (opening) return\n if (!host.openWorkspaceFile) {\n await handleDownload()\n return\n }\n setOpening(true)\n try {\n await host.openWorkspaceFile({ sessionId, path, name })\n onOpen?.()\n } finally {\n setOpening(false)\n }\n }\n\n const handleDownload = async () => {\n if (downloading) return\n setDownloading(true)\n onDownloadStarted?.()\n try {\n await client.sessions.downloadFile(sessionId, path, name)\n onDownloadSucceeded?.()\n } catch {\n } finally {\n setDownloading(false)\n }\n }\n\n return (\n <div\n data-artifact-kind={isVideoFile(name) ? \"video\" : \"file\"}\n className={compact\n ? \"file-delivery-card group/delivery relative flex w-full max-w-full items-stretch self-start overflow-hidden rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-sm transition-colors hover:bg-[hsl(var(--accent)/0.45)] focus-within:ring-1 focus-within:ring-[hsl(var(--ring))]\"\n : \"file-delivery-card group/delivery relative flex w-[320px] max-w-full items-center self-start rounded-[14px] border border-[hsl(var(--border))] bg-[hsl(var(--card))] transition-colors duration-150 hover:border-[hsl(var(--primary)/0.3)] hover:bg-[hsl(var(--muted)/0.6)] focus-within:ring-1 focus-within:ring-[hsl(var(--ring))]\"\n }\n >\n <button\n type=\"button\"\n onClick={() => void handleOpen()}\n disabled={opening}\n className={compact\n ? \"flex min-w-0 flex-1 items-center gap-1.5 bg-transparent py-1.5 pl-2 pr-8 text-left text-[hsl(var(--card-foreground))] focus:outline-none disabled:cursor-wait\"\n : \"flex min-w-0 flex-1 items-center gap-3 rounded-[14px] px-[15px] py-[13px] text-left focus:outline-none disabled:cursor-wait\"\n }\n aria-label={`打开文件:${displayName || name}`}\n title={displayName ? `${displayName}\\n${name}` : name}\n >\n <span className={compact\n ? \"flex h-5 w-5 shrink-0 items-center justify-center text-[hsl(var(--primary))]\"\n : \"flex h-[42px] w-[42px] shrink-0 items-center justify-center rounded-[11px] bg-gradient-to-br from-[hsl(var(--primary))/0.1] to-[hsl(var(--primary))/0.2] text-[hsl(var(--primary))]\"\n }>\n {opening ? (\n <Loader2 size={compact ? 15 : 22} className=\"animate-spin\" aria-hidden=\"true\" />\n ) : isVideoFile(name) ? (\n <Film size={compact ? 15 : 22} aria-hidden=\"true\" />\n ) : (\n <FileGlyph />\n )}\n </span>\n <span className={compact ? \"min-w-0\" : \"flex min-w-0 flex-1 flex-col gap-0.5\"}>\n <span className={compact ? \"block truncate text-xs font-medium leading-5\" : \"truncate text-[15px] font-semibold text-[hsl(var(--foreground))]\"}>{displayName || name}</span>\n {!compact ? (\n <span className=\"flex items-center gap-1.5 truncate text-[12.5px] text-[hsl(var(--muted-foreground))]\">\n {description ? (\n <span className=\"truncate\">{description}</span>\n ) : (\n <>\n <span className=\"font-mono\">{getExtLabel(name)}</span>\n <span aria-hidden=\"true\">·</span>\n <span className=\"text-[hsl(var(--primary))]\">AI 生成</span>\n </>\n )}\n </span>\n ) : null}\n </span>\n </button>\n <button\n type=\"button\"\n disabled={downloading}\n onClick={(event) => {\n event.stopPropagation()\n void handleDownload()\n }}\n className={compact\n ? \"absolute inset-y-0 right-0 flex w-7 items-center justify-center bg-transparent text-[hsl(var(--muted-foreground))] opacity-0 [@media(hover:none)]:opacity-100 transition-[opacity,color] hover:text-[hsl(var(--foreground))] focus:opacity-100 focus:outline-none group-hover/delivery:opacity-100 group-focus-within/delivery:opacity-100\"\n : \"absolute right-3 top-1/2 grid h-8 w-8 -translate-y-1/2 place-items-center rounded-lg text-[hsl(var(--muted-foreground))] opacity-0 [@media(hover:none)]:opacity-100 transition-opacity hover:bg-[hsl(var(--background))] hover:text-[hsl(var(--foreground))] focus:opacity-100 focus:outline-none group-hover/delivery:opacity-100\"\n }\n title=\"下载文件\"\n aria-label={`下载文件:${displayName || name}`}\n >\n {downloading ? (\n <Loader2 size={compact ? 13 : 16} className=\"animate-spin\" aria-hidden=\"true\" />\n ) : (\n <Download size={compact ? 13 : 16} aria-hidden=\"true\" />\n )}\n </button>\n </div>\n )\n}\n\nfunction FileGlyph() {\n return (\n <svg\n width=\"21\"\n height=\"21\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.9\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"m10 13-2 2 2 2\" />\n <path d=\"m14 17 2-2-2-2\" />\n </svg>\n )\n}\n\n/** 文件交付卡片组(需求 10):助手在本轮写入的工作区文件,以卡片形式内联展示。 */\nexport function FileDeliveryCards({\n toolCalls,\n sessionId,\n}: {\n toolCalls: ToolCallInfo[]\n sessionId: string\n}) {\n const files = useMemo(() => collectDeliveredFiles(toolCalls, sessionId), [toolCalls, sessionId])\n if (files.length === 0) return null\n\n return (\n <div className=\"flex flex-col gap-2\">\n {files.map((file) => (\n <DeliveryCard key={file.relPath} path={file.relPath} name={file.name} sessionId={sessionId} />\n ))}\n </div>\n )\n}\n","import { Check, Copy } from \"lucide-react\"\nimport { useState } from \"react\"\nimport { cn, copyToClipboard } from \"../lib/utils\"\n\ninterface Props {\n content: string\n className?: string\n}\n\nexport function MessageActions({ content, className }: Props) {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = async () => {\n const ok = await copyToClipboard(content)\n if (ok) {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n }\n\n return (\n <div className={cn(\"flex items-center gap-1 mt-1.5\", className)}>\n <button\n type=\"button\"\n onClick={handleCopy}\n className={cn(\n \"flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] transition-colors\",\n copied\n ? \"text-[hsl(var(--primary))]\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]\",\n )}\n >\n {copied ? <Check size={12} /> : <Copy size={12} />}\n <span>{copied ? \"已复制\" : \"复制\"}</span>\n </button>\n </div>\n )\n}\n","import { Archive, File, FileCode2, FileText, Film, Music } from \"lucide-react\"\nimport type { FileContentPart } from \"@blade-hq/agent-client/internal\"\nimport { cn } from \"../lib/utils\"\n\nfunction getFileIcon(fileName: string) {\n const lowerName = fileName.toLowerCase()\n\n if (/\\.(zip|rar|7z|tar|gz|bz2|xz)$/.test(lowerName)) {\n return Archive\n }\n if (/\\.(ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift|c|cc|cpp|h|hpp|css|scss|html|json|yaml|yml|toml|md)$/.test(lowerName)) {\n return FileCode2\n }\n if (/\\.(mp3|wav|flac|m4a|aac|ogg)$/.test(lowerName)) {\n return Music\n }\n if (/\\.(mp4|mov|mkv|avi|webm|wmv)$/.test(lowerName)) {\n return Film\n }\n if (/\\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {\n return FileText\n }\n return File\n}\n\ninterface MessageFileAttachmentListProps {\n files: FileContentPart[]\n className?: string\n onPreview?: (file: FileContentPart) => void\n}\n\nexport function MessageFileAttachmentList({\n files,\n className,\n onPreview,\n}: MessageFileAttachmentListProps) {\n if (files.length === 0) {\n return null\n }\n\n const pillClass =\n \"blade-chat-file-card flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]\"\n\n return (\n <div className={cn(\"flex flex-wrap gap-1.5\", className)}>\n {files.map((file) => {\n const Icon = getFileIcon(file.name)\n const key = `${file.name}-${file.data.slice(0, 32)}`\n const content = (\n <>\n <Icon size={12} className=\"shrink-0 text-[hsl(var(--muted-foreground))]\" />\n <span className=\"max-w-32 truncate\">{file.name}</span>\n </>\n )\n if (onPreview) {\n return (\n <button\n key={key}\n type=\"button\"\n part=\"file-card\"\n onClick={() => onPreview(file)}\n className={cn(pillClass, \"cursor-pointer transition-colors hover:border-[hsl(var(--ring)/0.5)]\")}\n title={`预览 ${file.name}`}\n >\n {content}\n </button>\n )\n }\n return (\n <div key={key} part=\"file-card\" className={pillClass} title={file.name}>\n {content}\n </div>\n )\n })}\n </div>\n )\n}\n","import type { ToolUiCard as ToolUiCardData } from \"@blade-hq/agent-client/internal\"\nimport { ToolUiCardView } from \"../components/ToolUiCardView\"\nimport { useChatEnvironment } from \"./runtime/environment\"\n\n/** 消息里的 tool_ui 卡片:宿主注入了渲染器就用宿主的(内置 Web 的资源桥接),否则用 SDK 的。 */\nexport function ToolUiCard({ card, sessionId }: { card: ToolUiCardData; sessionId: string }) {\n const Injected = useChatEnvironment().ToolUiCard\n if (Injected) return <Injected card={card} sessionId={sessionId} />\n return <ToolUiCardView card={card} sessionId={sessionId} />\n}\n","import { Check, ChevronRight, Loader2, MessageSquareMore, PanelRightOpen, X } from \"lucide-react\"\nimport { useEffect, useMemo, useState } from \"react\"\nimport {\n isInternalStatusToolUiCard,\n isWorkflowRunToolName,\n} from \"@blade-hq/agent-client/internal\"\nimport { isUiMeta } from \"./lib/ui-meta\"\nimport { useBladeHost } from \"../context\"\nimport { sendToSession } from \"./runtime/actions\"\nimport { useChatEnvironment } from \"./runtime/environment\"\nimport { cn } from \"../lib/utils\"\nimport type { ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport type { ContentBlock } from \"@blade-hq/agent-client/internal\"\nimport { useCurrentChatSessionId, useSessionHandle, useSessionState } from \"./runtime/session-source\"\nimport {\n ThinkingBadge,\n} from \"./ai-elements/reasoning\"\nimport {\n AskUserQuestionBlock,\n type AskUserAnswerData,\n parseAskUserQuestion,\n} from \"./AskUserQuestionBlock\"\nimport {\n extractToolFilePath,\n formatToolFileName,\n formatToolName,\n getToolDisplayLabel,\n getToolStatusLabel,\n getToolTone,\n} from \"./display-utils\"\nimport { getRenderer } from \"./tool-renderers/registry\"\nimport type { ChatViewCustomization } from \"./customization\"\n\nexport function getFilePreviewName(filePath: string): string {\n return filePath.split(/[\\\\/]/).pop() ?? filePath\n}\n\nfunction FilePathLink({ filePath, sessionId }: { filePath: string; sessionId?: string }) {\n const currentSessionId = useCurrentChatSessionId()\n const openWorkspaceFile = useBladeHost().openWorkspaceFile\n const resolvedSessionId = sessionId ?? currentSessionId\n\n const fileName = getFilePreviewName(filePath)\n const displayLabel = formatToolFileName(filePath)\n\n const handleClick = async () => {\n if (!resolvedSessionId || !openWorkspaceFile) return\n try {\n await openWorkspaceFile({ sessionId: resolvedSessionId, path: filePath, name: fileName })\n } catch {\n }\n }\n\n if (!openWorkspaceFile) {\n return <span className=\"min-w-0 truncate font-mono text-[hsl(var(--muted-foreground))]\">{displayLabel}</span>\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className=\"flex min-w-0 cursor-pointer items-center gap-1 font-mono text-[hsl(var(--swf-link-text))] hover:underline\"\n title={`预览 ${displayLabel}`}\n >\n <span className=\"truncate\">{displayLabel}</span>\n </button>\n )\n}\n\nexport function ToolFilePreviewAction({\n toolCall,\n sessionId,\n className,\n}: {\n toolCall: ToolCallInfo\n sessionId?: string\n className?: string\n}) {\n const filePath = extractToolFilePath(toolCall)\n if (!filePath) return null\n return (\n <span className={cn(\"flex min-w-0\", className)}>\n <FilePathLink filePath={filePath} sessionId={sessionId} />\n </span>\n )\n}\n\nfunction isLivePreviewTool(toolName: string): boolean {\n return toolName === \"Write\" || toolName === \"Edit\" || toolName === \"MultiEdit\"\n}\n\ninterface Props {\n toolCall: ToolCallInfo\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n answered?: boolean\n answerData?: AskUserAnswerData\n sessionId?: string\n sessionStatus?: string\n isActiveQuestion?: boolean\n level?: 1 | 2\n turnBlocks?: ContentBlock[]\n reasoning?: string\n customization?: ChatViewCustomization\n}\n\nexport function ToolPreviewAction({\n toolCall,\n sessionId: providedSessionId,\n turnBlocks,\n className,\n}: {\n toolCall: ToolCallInfo\n sessionId?: string\n turnBlocks?: ContentBlock[]\n className?: string\n}) {\n const currentSessionId = useCurrentChatSessionId()\n const openToolPreview = useChatEnvironment().openToolPreview\n const resolvedSessionId = providedSessionId ?? currentSessionId ?? undefined\n const uiMeta = useMemo(() => {\n const block = turnBlocks?.find(\n (item) => item.type === \"tool_ui\" && item.tool_call_id === toolCall.id && isUiMeta(item.content),\n )\n return block && isUiMeta(block.content) ? block.content : null\n }, [toolCall.id, turnBlocks])\n const displayName = getToolDisplayLabel(toolCall)\n\n if (\n !openToolPreview ||\n !uiMeta ||\n uiMeta.target !== \"preview\" ||\n !resolvedSessionId ||\n isInternalStatusToolUiCard(uiMeta)\n ) {\n return null\n }\n\n const label = uiMeta.title ?? displayName\n return (\n <button\n type=\"button\"\n onClick={() => openToolPreview({ sessionId: resolvedSessionId, toolCall, card: uiMeta, title: label })}\n className={cn(\n \"inline-flex shrink-0 cursor-pointer items-center gap-1 text-[hsl(var(--swf-link-text))] hover:underline\",\n className,\n )}\n title={`打开 ${label}`}\n >\n <PanelRightOpen size={12} />\n <span>{label}</span>\n </button>\n )\n}\n\n/**\n * 只认工具状态。改这里必须同步 packages/agent-react/src/components/ToolCallBlock.tsx\n * 的同名函数,否则同一份会话在内置页面能点、在 SDK 里点不动。\n *\n * 不要再拿 sessionStatus 兜底。历史投影算错时用 waiting_for_input 补救,\n * 会同时把已经回答过的旧提问重新变成可作答(历史加载不会带回 answerData),\n * 而且会盖住投影层的错误——PR #1597 的 bug 就是这么藏住的。\n */\nexport function resolveAskQuestionState({\n toolStatus,\n hasAnswerData,\n fallbackAnswered,\n fallbackAwaiting,\n}: {\n toolStatus: ToolCallInfo[\"status\"]\n hasAnswerData: boolean\n fallbackAnswered?: boolean\n fallbackAwaiting?: boolean\n}) {\n const awaitingAnswer = !hasAnswerData && (\n toolStatus === \"awaiting_answer\" ||\n (toolStatus === \"pending\" && fallbackAwaiting === true)\n )\n return {\n awaitingAnswer,\n answered:\n hasAnswerData ||\n (!awaitingAnswer &&\n (Boolean(fallbackAnswered) ||\n toolStatus === \"done\" ||\n toolStatus === \"cancelled\" ||\n toolStatus === \"error\")),\n }\n}\n\nexport function ToolCallBlock({\n toolCall,\n onAnswer,\n answered,\n answerData,\n sessionId: providedSessionId,\n sessionStatus,\n isActiveQuestion,\n level = 1,\n turnBlocks,\n reasoning,\n customization,\n}: Props) {\n const normalizedName = formatToolName(toolCall.name)\n const shouldAutoExpandWhileStreaming =\n toolCall.status === \"pending\" && isLivePreviewTool(normalizedName)\n const [expanded, setExpanded] = useState(shouldAutoExpandWhileStreaming)\n const currentSessionId = useCurrentChatSessionId()\n const resolvedSessionId = providedSessionId ?? currentSessionId ?? undefined\n const storedAnswerData = useSessionState(resolvedSessionId, (s) => s.askAnswers[toolCall.id])\n const liveSessionStatus = useSessionState(resolvedSessionId, (s) => s.status)\n const session = useSessionHandle(resolvedSessionId)\n const isViewer = useSessionState(resolvedSessionId, (s) => s.viewerRole === \"viewer\")\n const answerCallback = useMemo(\n () =>\n session && !isViewer\n ? (answer: string, toolCallId: string, data: AskUserAnswerData) => {\n void sendToSession(session, answer, session.getState().mode ?? undefined, {\n tool_call_id: toolCallId,\n ...data,\n })\n }\n : undefined,\n [isViewer, session],\n )\n useEffect(() => {\n if (shouldAutoExpandWhileStreaming) {\n setExpanded(true)\n }\n }, [shouldAutoExpandWhileStreaming])\n\n const resolvedSessionStatus = sessionStatus ?? liveSessionStatus ?? undefined\n const resolvedAnswerData = answerData ?? storedAnswerData\n const resolvedAnswered =\n toolCall.status === \"awaiting_answer\"\n ? false\n : (answered ?? (!!resolvedAnswerData && resolvedSessionStatus !== \"waiting_for_input\"))\n const resolvedOnAnswer = onAnswer ?? answerCallback\n if (isWorkflowRunToolName(toolCall.name)) {\n return null\n }\n if (normalizedName === \"AskUserQuestion\") {\n const askData =\n parseAskUserQuestion(typeof toolCall.result === \"string\" ? toolCall.result : null) ??\n parseAskUserQuestion(buildAskUserPayload(toolCall.arguments))\n const questionState = resolveAskQuestionState({\n toolStatus: toolCall.status,\n hasAnswerData: Boolean(resolvedAnswerData),\n fallbackAnswered: resolvedAnswered,\n fallbackAwaiting:\n isActiveQuestion === true &&\n (resolvedSessionStatus === \"paused\" || resolvedSessionStatus === \"waiting_for_input\"),\n })\n const canAnswer = questionState.awaitingAnswer && Boolean(resolvedOnAnswer)\n const customQuestion = askData\n ? customization?.renderers?.askUserQuestion?.({\n data: askData,\n answered: questionState.answered,\n toolCallId: toolCall.id,\n sessionStatus: resolvedSessionStatus ?? \"\",\n answerData: resolvedAnswerData,\n onAnswer: canAnswer ? resolvedOnAnswer : undefined,\n })\n : null\n const customToolCall =\n customQuestion == null && !customization?.renderers?.askUserQuestion\n ? customization?.renderers?.toolCall?.(toolCall)\n : null\n if (customQuestion != null) return <>{customQuestion}</>\n if (customToolCall != null) return <>{customToolCall}</>\n if (toolCall.status === \"error\") return null\n if (askData) {\n const questionBlock = (\n <AskUserQuestionBlock\n data={askData}\n answered={questionState.answered}\n toolCallId={toolCall.id}\n sessionStatus={resolvedSessionStatus ?? \"\"}\n answerData={resolvedAnswerData}\n onAnswer={canAnswer ? resolvedOnAnswer : undefined}\n />\n )\n if (!reasoning) {\n return questionBlock\n }\n return (\n <div className=\"flex flex-col gap-1\">\n {questionBlock}\n <div className=\"ml-4\">\n <ThinkingBadge reasoning={reasoning} variant=\"block\" />\n </div>\n </div>\n )\n }\n if (toolCall.status === \"pending\") {\n return (\n <div part=\"ask-card\" className=\"blade-chat-ask-card ml-4 flex max-w-lg items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={14} className=\"animate-spin\" />\n <span>正在准备问题…</span>\n </div>\n )\n }\n return (\n <div part=\"ask-card\" className=\"blade-chat-ask-card ml-4 max-w-lg rounded-xl border border-[hsl(var(--swf-warning)/0.35)] bg-[hsl(var(--swf-warning-soft))] p-4 text-sm text-[hsl(var(--foreground))]\">\n <div className=\"font-semibold\">选择题内容暂时无法显示</div>\n <div className=\"mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]\">\n 收到的交互数据不完整或版本不兼容。请重试;若问题持续,请提供交互编号\n <span className=\"ml-1 font-mono\">{toolCall.id}</span>。\n </div>\n </div>\n )\n }\n\n const customToolCall = customization?.renderers?.toolCall?.(toolCall)\n if (customToolCall != null) return <>{customToolCall}</>\n\n const tone = getToolTone(toolCall.status)\n const displayName = getToolDisplayLabel(toolCall)\n const Renderer = customization?.renderers?.tool?.[normalizedName] ?? getRenderer(normalizedName)\n const indentClass = level === 2 ? \"ml-3\" : \"\"\n\n const statusIcon =\n toolCall.status === \"pending\" ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : toolCall.status === \"awaiting_answer\" ? (\n <MessageSquareMore size={12} />\n ) : toolCall.status === \"cancelled\" || toolCall.status === \"error\" ? (\n <X size={12} />\n ) : (\n <Check size={12} />\n )\n\n const statusTextClass =\n tone === \"failed\"\n ? \"text-[hsl(var(--swf-danger))]\"\n : tone === \"awaiting\"\n ? \"text-[hsl(var(--swf-warning))]\"\n : tone === \"running\"\n ? \"text-[hsl(var(--muted-foreground))]\"\n : \"text-[hsl(var(--primary))]\"\n\n return (\n <div\n part={normalizedName === \"Agent\" ? \"agent-loop\" : \"tool-row\"}\n className={cn(\n normalizedName === \"Agent\" ? \"blade-chat-agent-loop\" : \"blade-chat-tool-row\",\n indentClass,\n \"text-xs\",\n customization?.classNames?.toolCall,\n )}\n >\n <div className=\"flex items-center gap-2 min-h-7 pr-3 leading-5\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"flex min-h-7 min-w-0 flex-1 items-center gap-2 text-left transition-colors hover:bg-[hsl(var(--swf-fill-light))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n aria-expanded={expanded}\n >\n <ChevronRight\n size={12}\n className={cn(\n \"shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n expanded && \"rotate-90\",\n )}\n />\n <span className={cn(\"flex shrink-0 items-center gap-1 text-[10px]\", statusTextClass)}>\n {statusIcon}\n <span>{getToolStatusLabel(toolCall.status)}</span>\n </span>\n <span className=\"min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]\">\n {displayName}\n {toolCall.status === \"error\" ? \"(待重试)\" : \"\"}\n </span>\n </button>\n {reasoning ? <ThinkingBadge reasoning={reasoning} variant=\"block\" /> : null}\n {typeof toolCall.duration_ms === \"number\" && toolCall.duration_ms > 0 && (\n <span className=\"shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]\">\n {formatToolDuration(toolCall.duration_ms)}\n </span>\n )}\n <ToolPreviewAction\n toolCall={toolCall}\n sessionId={resolvedSessionId}\n turnBlocks={turnBlocks}\n />\n </div>\n {expanded && (\n <div className=\"ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3\">\n {Renderer ? (\n <Renderer toolCall={toolCall} sessionId={resolvedSessionId} />\n ) : (\n <>\n <div className=\"mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]\">\n 工具\n </div>\n <div className=\"mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]\">\n {normalizedName}\n </div>\n <div className=\"mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]\">\n 参数\n </div>\n <pre className=\"overflow-x-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]\">\n {formatArgs(toolCall.arguments)}\n </pre>\n {toolCall.result != null && (\n <>\n <div className=\"mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]\">\n 结果\n </div>\n <pre\n className={cn(\n \"max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md p-2 font-mono text-[11px]\",\n \"bg-[hsl(var(--muted))] text-[hsl(var(--foreground))]\",\n )}\n >\n {typeof toolCall.result === \"string\"\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2)}\n </pre>\n </>\n )}\n </>\n )}\n </div>\n )}\n </div>\n )\n}\n\n\n\n\nfunction formatToolDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`\n const seconds = ms / 1000\n if (seconds < 60) return `${seconds.toFixed(1)}s`\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = Math.round(seconds % 60)\n return remainingSeconds > 0 ? `${minutes}m${remainingSeconds}s` : `${minutes}m`\n}\n\nfunction formatArgs(args: string): string {\n try {\n return JSON.stringify(JSON.parse(args), null, 2)\n } catch {\n return args\n }\n}\n\nfunction buildAskUserPayload(argumentsJson: string): string | null {\n try {\n const parsed = JSON.parse(argumentsJson)\n if (parsed && typeof parsed === \"object\" && Array.isArray((parsed as { questions?: unknown }).questions)) {\n return JSON.stringify({ questions: (parsed as { questions: unknown[] }).questions })\n }\n } catch {\n return null\n }\n return null\n}\n","import { formatAskUserAnswer } from \"@blade-hq/agent-client\"\nimport type { AskUserAnswerData, AskUserQuestionData, AskUserQuestionItem } from \"@blade-hq/agent-client\"\nimport { Check, Loader2, MessageSquareMore } from \"lucide-react\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\n\nexport { parseAskUserQuestion } from \"@blade-hq/agent-client\"\nexport type { AskUserAnswerData, AskUserQuestionData }\n\nconst CUSTOM_TEXTAREA_MAX_HEIGHT = 160\n\nfunction resizeCustomTextarea(textarea: HTMLTextAreaElement) {\n textarea.style.height = \"auto\"\n textarea.style.height = `${Math.min(textarea.scrollHeight, CUSTOM_TEXTAREA_MAX_HEIGHT)}px`\n textarea.style.overflowY =\n textarea.scrollHeight > CUSTOM_TEXTAREA_MAX_HEIGHT ? \"auto\" : \"hidden\"\n}\n\nfunction useAutoResizeTextarea(value: string) {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n useEffect(() => {\n const textarea = textareaRef.current\n if (textarea?.value === value) resizeCustomTextarea(textarea)\n }, [value])\n\n useEffect(() => {\n const textarea = textareaRef.current\n if (!textarea || typeof ResizeObserver === \"undefined\") return\n\n let previousWidth = textarea.clientWidth\n const observer = new ResizeObserver(([entry]) => {\n if (!entry || entry.contentRect.width === previousWidth) return\n previousWidth = entry.contentRect.width\n resizeCustomTextarea(textarea)\n })\n observer.observe(textarea)\n return () => observer.disconnect()\n }, [])\n\n return textareaRef\n}\n\ninterface Props {\n data: AskUserQuestionData\n answered: boolean\n toolCallId: string\n sessionStatus: string\n answerData?: AskUserAnswerData | undefined\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n}\n\nexport function AskUserQuestionBlock({\n data,\n answered,\n toolCallId,\n sessionStatus,\n answerData,\n onAnswer,\n}: Props) {\n const [selections, setSelections] = useState<Map<number, Set<number>>>(new Map())\n const [customTexts, setCustomTexts] = useState<Map<number, string>>(new Map())\n const [usingCustom, setUsingCustom] = useState<Set<number>>(new Set())\n const [note, setNote] = useState(\"\")\n const [submitted, setSubmitted] = useState(false)\n\n useEffect(() => {\n if (sessionStatus === \"failed\" || sessionStatus === \"interrupted\") {\n setSubmitted(false)\n }\n }, [sessionStatus])\n\n const displayAnswerState = useMemo(() => {\n if (!(answered && answerData)) {\n return {\n selections,\n customTexts,\n usingCustom,\n note,\n }\n }\n\n const nextSelections = new Map<number, Set<number>>()\n const nextCustomTexts = new Map<number, string>()\n const nextUsingCustom = new Set<number>()\n\n for (const [questionKey, optionIndexes] of Object.entries(answerData.selections)) {\n nextSelections.set(Number(questionKey), new Set(optionIndexes))\n }\n\n for (const [questionKey, text] of Object.entries(answerData.custom)) {\n const qIdx = Number(questionKey)\n nextCustomTexts.set(qIdx, text)\n nextUsingCustom.add(qIdx)\n }\n\n return {\n selections: nextSelections,\n customTexts: nextCustomTexts,\n usingCustom: nextUsingCustom,\n note: answerData.note ?? \"\",\n }\n }, [answerData, answered, customTexts, note, selections, usingCustom])\n\n const displaySelections = displayAnswerState.selections\n const displayCustomTexts = displayAnswerState.customTexts\n const displayUsingCustom = displayAnswerState.usingCustom\n const displayNote = displayAnswerState.note\n\n const toggleOption = (qIdx: number, optIdx: number, multi: boolean) => {\n if (answered || submitted) return\n setSelections((prev) => {\n const next = new Map(prev)\n const current = new Set(next.get(qIdx) ?? [])\n if (multi) {\n if (current.has(optIdx)) current.delete(optIdx)\n else current.add(optIdx)\n } else {\n current.clear()\n current.add(optIdx)\n }\n next.set(qIdx, current)\n return next\n })\n setUsingCustom((prev) => {\n const next = new Set(prev)\n next.delete(qIdx)\n return next\n })\n }\n\n const handleCustomFocus = (qIdx: number) => {\n if (answered || submitted) return\n setSelections((prev) => {\n const next = new Map(prev)\n next.delete(qIdx)\n return next\n })\n setUsingCustom((prev) => new Set(prev).add(qIdx))\n }\n\n const setCustomText = (qIdx: number, text: string) => {\n if (answered || submitted) return\n setCustomTexts((prev) => new Map(prev).set(qIdx, text))\n }\n\n const getAnswer = (qIdx: number): string | null => {\n const q = data.questions[qIdx]\n if (usingCustom.has(qIdx)) {\n const text = (customTexts.get(qIdx) ?? \"\").trim()\n return text || null\n }\n const sel = selections.get(qIdx)\n if (!sel || sel.size === 0) return null\n return [...sel]\n .sort()\n .map((i) => q.options[i].label)\n .join(\", \")\n }\n\n const allAnswered = data.questions.every((_, i) => getAnswer(i) !== null)\n\n const handleSubmit = () => {\n if (answered || submitted || !allAnswered || !onAnswer) return\n\n const trimmedNote = note.trim()\n const nextAnswerData: AskUserAnswerData = {\n selections: Object.fromEntries(\n Array.from(selections.entries()).map(([qIdx, optionIndexes]) => [\n qIdx,\n Array.from(optionIndexes).sort((a, b) => a - b),\n ]),\n ) as Record<number, number[]>,\n custom: Object.fromEntries(\n Array.from(usingCustom)\n .map((qIdx) => [qIdx, (customTexts.get(qIdx) ?? \"\").trim()] as const)\n .filter(([, text]) => text.length > 0),\n ) as Record<number, string>,\n ...(trimmedNote ? { note: trimmedNote } : {}),\n }\n\n const text = formatAskUserAnswer(data, nextAnswerData)\n setSubmitted(true)\n onAnswer(text, toolCallId, nextAnswerData)\n }\n\n return (\n <div\n part=\"ask-card\"\n className={cn(\n \"ask-user-question blade-chat-ask-card ml-4 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))]\",\n answered\n ? \"max-w-2xl space-y-3 p-3 text-xs text-[hsl(var(--muted-foreground))] opacity-80\"\n : \"max-w-lg space-y-5 p-4 text-sm\",\n )}\n >\n {data.source_loop?.description && (\n <div className=\"rounded-lg bg-[hsl(var(--muted)/0.35)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\">\n 子智能体「{data.source_loop.description}」在等待你的回答\n </div>\n )}\n {data.questions.map((q, qIdx) => (\n <QuestionCard\n key={q.question}\n question={q}\n qIdx={qIdx}\n answered={answered}\n selected={displaySelections.get(qIdx) ?? new Set()}\n isCustom={displayUsingCustom.has(qIdx)}\n customText={displayCustomTexts.get(qIdx) ?? \"\"}\n onToggle={toggleOption}\n onCustomFocus={handleCustomFocus}\n onCustomChange={setCustomText}\n />\n ))}\n\n <NoteField\n answered={answered}\n submitted={submitted}\n note={displayNote}\n onChange={setNote}\n />\n\n {!answered && !submitted && onAnswer && (\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!allAnswered}\n className=\"w-full rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {allAnswered ? \"确认\" : \"请先选择一个选项\"}\n </button>\n )}\n\n {submitted && !answered && (\n <button\n type=\"button\"\n disabled\n className=\"flex w-full items-center justify-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] opacity-80\"\n >\n <Loader2 size={14} className=\"animate-spin\" />\n 确认中\n </button>\n )}\n </div>\n )\n}\n\nfunction QuestionCard({\n question,\n qIdx,\n answered,\n selected,\n isCustom,\n customText,\n onToggle,\n onCustomFocus,\n onCustomChange,\n}: {\n question: AskUserQuestionItem\n qIdx: number\n answered: boolean\n selected: Set<number>\n isCustom: boolean\n customText: string\n onToggle: (qIdx: number, optIdx: number, multi: boolean) => void\n onCustomFocus: (qIdx: number) => void\n onCustomChange: (qIdx: number, text: string) => void\n}) {\n const multi = question.multiSelect ?? false\n const customTextareaRef = useAutoResizeTextarea(customText)\n\n return (\n <div>\n <div className={cn(\"flex items-start gap-2\", answered ? \"mb-2\" : \"mb-3\")}>\n <MessageSquareMore\n size={answered ? 12 : 13}\n className=\"mt-0.5 shrink-0 text-[hsl(var(--primary))]\"\n />\n <div\n className={cn(\n \"min-w-0 flex-1 font-medium text-[hsl(var(--foreground))]\",\n answered ? \"text-xs\" : \"text-sm\",\n )}\n >\n <MarkdownContent\n className={cn(\n \"prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_ol]:my-1 [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_ul]:my-1\",\n answered ? \"text-xs\" : \"text-sm\",\n )}\n controls={{ code: true }}\n >\n {question.question}\n </MarkdownContent>\n </div>\n </div>\n\n <div className={cn(\"flex flex-col pl-5\", answered ? \"gap-1\" : \"gap-1.5\")}>\n {question.options.map((opt, optIdx) => {\n const isSel = selected.has(optIdx)\n return (\n <button\n key={opt.label}\n type=\"button\"\n disabled={answered}\n onClick={() => onToggle(qIdx, optIdx, multi)}\n part=\"ask-option\"\n className={cn(\n \"blade-chat-ask-option flex items-start gap-2.5 rounded-lg border text-left transition-colors\",\n answered ? \"px-2.5 py-1.5\" : \"px-3 py-2.5\",\n isSel && !answered\n ? \"border-[hsl(var(--primary)/0.8)] bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\"\n : isSel\n ? \"border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.08)] text-[hsl(var(--foreground))]\"\n : \"border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.2)]\",\n !answered && !isSel && \"hover:border-[hsl(var(--ring)/0.4)] hover:bg-[hsl(var(--accent))]\",\n answered && \"cursor-default\",\n answered && !isSel && \"text-[hsl(var(--muted-foreground))]\",\n )}\n >\n {multi && (\n <div\n className={cn(\n \"mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors\",\n isSel && !answered\n ? \"border-[hsl(var(--primary-foreground)/0.6)] bg-[hsl(var(--primary-foreground)/0.2)]\"\n : isSel\n ? \"border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.12)]\"\n : \"border-[hsl(var(--border))]\",\n )}\n >\n {isSel && (\n <Check\n size={10}\n className={\n answered\n ? \"text-[hsl(var(--primary))]\"\n : \"text-[hsl(var(--primary-foreground))]\"\n }\n />\n )}\n </div>\n )}\n <div className=\"min-w-0\">\n <div className={cn(\"font-medium\", answered ? \"text-xs\" : \"text-[13px]\")}>\n {opt.label}\n </div>\n {opt.description && (\n <div\n className={cn(\n \"mt-0.5\",\n answered ? \"text-[11px]\" : \"text-xs\",\n isSel && !answered ? \"opacity-80\" : \"text-[hsl(var(--muted-foreground))]\",\n )}\n >\n {opt.description}\n </div>\n )}\n </div>\n </button>\n )\n })}\n\n {answered && !isCustom ? null : (\n <div\n className={cn(\n \"flex items-start gap-2 rounded-lg border transition-colors focus-within:ring-2 focus-within:ring-[hsl(var(--ring)/0.35)]\",\n answered ? \"px-2.5 py-1.5\" : \"px-3 py-2.5\",\n isCustom\n ? \"border-[hsl(var(--ring)/0.6)] bg-[hsl(var(--accent))]\"\n : \"border-[hsl(var(--border))] hover:border-[hsl(var(--ring)/0.3)] hover:bg-[hsl(var(--accent))]\",\n answered && \"cursor-default\",\n )}\n >\n <span className=\"shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]\">\n 其他:\n </span>\n <textarea\n ref={customTextareaRef}\n rows={2}\n value={customText}\n readOnly={answered}\n onChange={(e) => onCustomChange(qIdx, e.target.value)}\n onFocus={() => onCustomFocus(qIdx)}\n aria-label=\"自定义回答\"\n placeholder=\"输入你的答案...\"\n className={cn(\n \"min-h-10 min-w-0 flex-1 resize-none bg-transparent leading-5 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.5)]\",\n answered ? \"text-xs\" : \"text-sm\",\n )}\n />\n </div>\n )}\n </div>\n </div>\n )\n}\n\nfunction NoteField({\n answered,\n submitted,\n note,\n onChange,\n}: {\n answered: boolean\n submitted: boolean\n note: string\n onChange: (text: string) => void\n}) {\n const textareaRef = useAutoResizeTextarea(note)\n const readOnly = answered || submitted\n if (answered && !note.trim()) return null\n\n return (\n <label\n className={cn(\n \"block rounded-lg border transition-colors focus-within:ring-2 focus-within:ring-[hsl(var(--ring)/0.35)]\",\n answered ? \"px-2.5 py-1.5\" : \"px-3 py-2.5\",\n note.trim()\n ? \"border-[hsl(var(--ring)/0.6)] bg-[hsl(var(--accent))]\"\n : \"border-[hsl(var(--border))] hover:border-[hsl(var(--ring)/0.3)] hover:bg-[hsl(var(--accent))]\",\n readOnly && \"cursor-default\",\n )}\n >\n <span className=\"mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]\">\n 补充说明(可选)\n </span>\n <textarea\n ref={textareaRef}\n rows={2}\n value={note}\n readOnly={readOnly}\n onChange={(event) => {\n if (readOnly) return\n onChange(event.target.value)\n }}\n aria-label=\"补充说明\"\n placeholder=\"选完还可以再讲两句,空着就当没有\"\n className={cn(\n \"min-h-10 w-full resize-none bg-transparent leading-5 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.5)]\",\n answered ? \"text-xs\" : \"text-sm\",\n )}\n />\n </label>\n )\n}\n\nexport interface AskUserQuestionError {\n message: string\n detail: string | null\n}\n\n/**\n * Keep this parser synchronized with agent-react/AskUserQuestionBlock.tsx.\n * The built-in Web cannot import agent-react, and this is not a public SDK protocol API.\n */\nexport function parseAskUserQuestionError(\n toolResult: string | null | undefined,\n): AskUserQuestionError | null {\n if (!toolResult) return null\n try {\n const parsed = JSON.parse(toolResult) as {\n error?: unknown\n error_code?: unknown\n message?: unknown\n }\n let detail: string | null = null\n if (typeof parsed.error === \"string\") detail = parsed.error\n if (parsed.error && typeof parsed.error === \"object\") {\n const message = (parsed.error as { message?: unknown }).message\n if (typeof message === \"string\") detail = message\n }\n if (!detail && typeof parsed.message === \"string\") detail = parsed.message\n if (!detail) return null\n return {\n message:\n parsed.error_code === \"invalid_questions\"\n ? \"提问内容不完整,当前没有等待你回答。请让智能体重新提问。\"\n : \"这次提问没有成功,当前没有等待你回答。请让智能体重新提问。\",\n detail,\n }\n } catch {\n return null\n }\n}\n","import { Check, ChevronRight, CircleSlash, Loader2, X, Zap } from \"lucide-react\"\nimport { useMemo, useState, type ReactNode } from \"react\"\nimport { cn } from \"../lib/utils\"\nimport type { AgentLoopInfo, WorkflowRunEntry } from \"@blade-hq/agent-client\"\nimport { useSessionState } from \"./runtime/session-source\"\nimport type { ChatMessage, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport { AgentLoopBlock } from \"./AgentLoopBlock\"\nimport { useSessionSkills } from \"../rich-input/services\"\nimport type { InputSessionSkill } from \"./runtime/input-services\"\n\ninterface Props {\n toolCall: ToolCallInfo\n sessionId: string\n}\n\nconst EMPTY_ENTRIES: WorkflowRunEntry[] = []\nconst NO_SKILLS: InputSessionSkill[] = []\n\n/** 标题里的技能 id 换成会话技能列表里的中文名;查不到(未加载/已卸载)就保留 id。 */\nexport function workflowTitle(name: string, argumentsJson: string, skills: readonly Pick<InputSessionSkill, \"skill_id\" | \"display_name\">[]): string {\n let skillId = \"\"\n try {\n const raw = JSON.parse(argumentsJson)?.skill_id\n skillId = typeof raw === \"string\" ? raw.trim() : \"\"\n } catch {\n }\n const displayName = skillId ? skills.find((skill) => skill.skill_id === skillId)?.display_name?.trim() : \"\"\n return displayName ? name.replace(`「${skillId}」`, () => `「${displayName}」`) : name\n}\n\nfunction synthToolCall(loopName: string, info: AgentLoopInfo, desc?: string): ToolCallInfo {\n return {\n id: loopName,\n name: \"Agent\",\n arguments: JSON.stringify({ description: desc || info.description }),\n status:\n info.status === \"running\"\n ? \"pending\"\n : info.status === \"error\" || info.status === \"cancelled\" || info.status === \"awaiting_answer\"\n ? info.status\n : \"done\",\n }\n}\n\nfunction resultText(result: unknown): string {\n return typeof result === \"string\" ? result.trim() : \"\"\n}\n\ntype StepGroup = {\n key: string\n desc: string\n stepId: string\n stepKind: string\n status?: string\n logs: string[]\n}\n\nconst LOG_PREFIX = \"[workflow] \"\n\n/** 事件流 → 步骤分组:每个 step 事件开一张卡。log 行带所属步骤 id 时归到那一步\n * (并行分支的输出不按宣告顺序到达,按位置归会挂错卡);旧记录没有 id 才归到上一步。 */\nexport function groupWorkflowEntries(entries: readonly WorkflowRunEntry[]): {\n prelude: string[]\n groups: StepGroup[]\n} {\n const prelude: string[] = []\n const groups: StepGroup[] = []\n const byStep = new Map<string, StepGroup>()\n entries.forEach((entry, index) => {\n if (entry.kind === \"log\") {\n const target = (entry.stepId && byStep.get(entry.stepId)) || groups[groups.length - 1]\n if (target) target.logs.push(entry.text)\n else prelude.push(entry.text)\n return\n }\n const group: StepGroup = {\n key: `step-${index}`,\n desc: entry.desc,\n stepId: entry.stepId,\n stepKind: entry.stepKind,\n status: entry.status,\n logs: [],\n }\n groups.push(group)\n if (entry.stepId) byStep.set(entry.stepId, group)\n })\n return { prelude, groups }\n}\n\nfunction stepStatus(group: StepGroup, runStatus: string): string | undefined {\n if (group.status) return group.status\n if (runStatus === \"running\") return group.stepKind === \"step\" && group.logs.length > 0 ? \"done\" : \"running\"\n return runStatus === \"done\" ? \"done\" : undefined\n}\n\nfunction StatusIcon({ status }: { status?: string }) {\n if (status === \"done\") return <Check size={13} className=\"shrink-0 text-emerald-600\" aria-label=\"完成\" />\n if (status === \"running\") return <Loader2 size={13} className=\"shrink-0 animate-spin text-[hsl(var(--muted-foreground))]\" aria-label=\"进行中\" />\n if (status === \"error\") return <X size={13} className=\"shrink-0 text-red-600\" aria-label=\"失败\" />\n if (status === \"cancelled\") return <CircleSlash size={13} className=\"shrink-0 text-[hsl(var(--muted-foreground))]\" aria-label=\"已取消\" />\n return null\n}\n\nconst CONTAINER_LABEL: Record<string, string> = { parallel: \"并行\", choice: \"条件\", end: \"结束\" }\n\nconst EMPTY_OUTPUT_LOG_RE = /输出[::]\\s*[((]空[))]\\s*$/\nconst TERMINATOR_LOG_RE = /^(?:结束流程|条件不满足[,,]结束流程\\([^)]*\\))$/\n\nfunction meaningfulLogs(logs: string[]): string[] {\n return logs.filter(\n (log) =>\n log.trim() && !EMPTY_OUTPUT_LOG_RE.test(log.trim()) && !TERMINATOR_LOG_RE.test(log.trim()),\n )\n}\n\nfunction LogLines({ logs }: { logs: string[] }) {\n if (logs.length === 0) return null\n return (\n <div className=\"flex flex-col gap-0.5\">\n {logs.map((log, index) => (\n <div\n key={index}\n className=\"whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]\"\n >\n {log}\n </div>\n ))}\n </div>\n )\n}\n\nconst REF_TOKEN_RE = /\\{\\{([a-z][a-z0-9_]{0,31})\\}\\}/g\n\ntype RefInfo = { label: string; value: string }\n\nfunction lastAssistantText(messages: ChatMessage[], loopName: string): string {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index]\n if ((message.loop_name ?? \"root\") !== loopName || message.role !== \"assistant\") continue\n const content = message.content\n const text =\n typeof content === \"string\"\n ? content\n : content\n .map((part) => (\"text\" in part && typeof part.text === \"string\" ? part.text : \"\"))\n .join(\"\")\n if (text.trim()) return text.trim()\n }\n return \"\"\n}\n\nfunction RefTokenText({ text, refs }: { text: string; refs: Map<string, RefInfo> }) {\n const parts: ReactNode[] = []\n let cursor = 0\n const re = new RegExp(REF_TOKEN_RE.source, \"g\")\n for (;;) {\n const match = re.exec(text)\n if (!match) break\n if (match.index > cursor) parts.push(text.slice(cursor, match.index))\n const id = match[1]\n const info = refs.get(id)\n parts.push(\n <span\n key={`${id}-${match.index}`}\n title={info?.value ? info.value.slice(0, 300) : \"尚无输出\"}\n className=\"mx-0.5 inline-flex max-w-[160px] items-center gap-0.5 truncate rounded-full border border-teal-500/40 bg-teal-500/10 px-1.5 py-px align-middle text-[11px] font-medium text-teal-500\"\n >\n ▶ {info?.label || id}\n </span>,\n )\n cursor = match.index + match[0].length\n }\n if (cursor < text.length) parts.push(text.slice(cursor))\n return <>{parts}</>\n}\n\n/**\n * 「固定流程」块:一次 workflow:run(跑某个技能的 flows/*.yaml)的执行呈现——每个步骤\n * 一张卡顺序铺开(agent 步骤=完整子智能体卡,命令/条件步骤=描述+输出的小卡),头部可整体折叠。\n * 渲染在触发它的回合的「执行过程」折叠区里,和普通技能的工具调用同一个位置。\n */\nexport function WorkflowRunBlock({ toolCall, sessionId }: Props) {\n const run = useSessionState(sessionId, (state) => state.workflowRuns[toolCall.id])\n const agentLoops = useSessionState(sessionId, (state) => state.agentLoops)\n const sessionMessages = useSessionState(sessionId, (state) => state.messages)\n const [collapsed, setCollapsed] = useState(false)\n\n const stepLoops = useMemo(\n () =>\n Object.entries(agentLoops)\n .filter(([, info]) => info.workflowRunId === toolCall.id)\n .map(([loopName, info]) => ({ loopName, info })),\n [agentLoops, toolCall.id],\n )\n\n const output = resultText(toolCall.result)\n const { prelude, groups } = useMemo(() => groupWorkflowEntries(run?.entries ?? EMPTY_ENTRIES), [run?.entries])\n\n const { groupLoops, leftoverLoops } = useMemo(() => {\n const remaining = [...stepLoops]\n const assigned = groups.map((group) => {\n if (group.stepKind !== \"agent\") return null\n const index = remaining.findIndex(\n (candidate) => candidate.info.description === (group.desc || group.stepId),\n )\n return index >= 0 ? remaining.splice(index, 1)[0] : null\n })\n groups.forEach((group, i) => {\n if (assigned[i] || group.stepKind !== \"agent\" || remaining.length === 0) return\n assigned[i] = remaining.shift() ?? null\n })\n return { groupLoops: assigned, leftoverLoops: remaining }\n }, [groups, stepLoops])\n\n const refInfos = useMemo(() => {\n const map = new Map<string, RefInfo>()\n try {\n const parsed = JSON.parse(toolCall.arguments)?.inputs\n if (parsed && typeof parsed === \"object\") {\n for (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n map.set(key, { label: key, value: value == null ? \"\" : String(value) })\n }\n }\n } catch {\n }\n groups.forEach((group, index) => {\n if (!group.stepId) return\n const label = group.desc.replace(new RegExp(REF_TOKEN_RE.source, \"g\"), \"…\").trim().slice(0, 12)\n const loop = groupLoops[index]\n const value = loop\n ? lastAssistantText(sessionMessages, loop.loopName)\n : meaningfulLogs(group.logs).join(\"\\n\")\n map.set(group.stepId, { label: label || group.stepId, value })\n })\n return map\n }, [toolCall.arguments, groups, groupLoops, sessionMessages])\n const renderRefText = (text: string) => <RefTokenText text={text} refs={refInfos} />\n\n const finalOutput = useMemo(\n () =>\n output\n .split(\"\\n\")\n .filter((line) => !line.startsWith(LOG_PREFIX))\n .join(\"\\n\")\n .trim(),\n [output],\n )\n\n const status = run?.status ?? \"running\"\n const running = status === \"running\"\n const stepCount = groups.length || stepLoops.length\n // 技能列表接口只对会话主人开放:分享页(share:<token>)和只读查看者不查,标题保留 id\n const viewerRole = useSessionState(sessionId, (state) => state.viewerRole)\n const canListSkills = !sessionId.startsWith(\"share:\") && viewerRole !== \"viewer\"\n const { data: sessionSkills = NO_SKILLS } = useSessionSkills(canListSkills ? sessionId : null)\n const title = workflowTitle(run?.name || \"技能\", toolCall.arguments, sessionSkills)\n\n const statusSummary = running\n ? `进行中 · ${stepCount} 步`\n : status === \"error\"\n ? `失败 · ${stepCount} 步`\n : status === \"cancelled\"\n ? `已取消 · ${stepCount} 步`\n : `已完成 · ${stepCount} 步`\n\n const hasStepContent = groups.length > 0 || stepLoops.length > 0\n\n return (\n <div className=\"msg-animate overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))]/50\">\n <button\n type=\"button\"\n onClick={() => setCollapsed((value) => !value)}\n aria-expanded={!collapsed}\n className=\"flex w-full items-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--primary)/0.06)] px-4 py-2.5 text-left transition-colors hover:bg-[hsl(var(--primary)/0.1)] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <Zap size={15} className=\"shrink-0 text-violet-600\" />\n <span className=\"min-w-0 truncate text-sm font-semibold text-[hsl(var(--foreground))]\">\n 固定流程 · {title}\n </span>\n <span className=\"ml-auto flex shrink-0 items-center gap-1.5 text-xs text-[hsl(var(--muted-foreground))]\">\n {running ? <Loader2 size={12} className=\"animate-spin\" /> : null}\n {statusSummary}\n </span>\n <ChevronRight\n size={15}\n className={cn(\n \"shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n !collapsed && \"rotate-90\",\n )}\n />\n </button>\n {!collapsed && (\n <div className=\"flex flex-col gap-2 p-3\">\n <LogLines logs={meaningfulLogs(prelude)} />\n {groups.map((group, index) => {\n const loop = groupLoops[index]\n const logs = meaningfulLogs(group.logs)\n if (loop) {\n return (\n <div key={group.key} className=\"flex flex-col gap-1\">\n <AgentLoopBlock\n toolCall={synthToolCall(loop.loopName, loop.info, group.desc)}\n sessionId={sessionId}\n defaultExpanded\n renderDescription={renderRefText}\n />\n <LogLines logs={logs} />\n </div>\n )\n }\n const container = CONTAINER_LABEL[group.stepKind]\n return (\n <div\n key={group.key}\n className={cn(\n \"rounded-lg px-3 py-2\",\n container\n ? \"border border-dashed border-violet-400/50 bg-violet-500/5\"\n : \"border border-[hsl(var(--border))] bg-[hsl(var(--card))]\",\n )}\n >\n <div className=\"flex items-center gap-1.5 text-sm text-[hsl(var(--foreground))]\">\n <StatusIcon status={stepStatus(group, status)} />\n {container ? (\n <span className=\"text-[11px] font-semibold text-violet-600\">{container}</span>\n ) : null}\n <span className=\"min-w-0 truncate\">{renderRefText(group.desc || group.stepId)}</span>\n </div>\n <LogLines logs={logs} />\n </div>\n )\n })}\n {leftoverLoops.map((step) => (\n <AgentLoopBlock\n key={step.loopName}\n toolCall={synthToolCall(step.loopName, step.info)}\n sessionId={sessionId}\n defaultExpanded\n renderDescription={renderRefText}\n />\n ))}\n {((!hasStepContent && output) || (status === \"error\" && output)) && (\n <pre className=\"max-h-48 overflow-y-auto whitespace-pre-wrap break-words rounded-lg border border-[hsl(var(--border))] px-3 py-2 font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]\">\n {output}\n </pre>\n )}\n {status === \"done\" && hasStepContent && finalOutput && (\n <details className=\"rounded-lg border border-[hsl(var(--border))] px-3 py-2\">\n <summary className=\"cursor-pointer select-none text-xs text-[hsl(var(--muted-foreground))]\">\n 最终输出\n </summary>\n <pre className=\"mt-1.5 max-h-48 overflow-y-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]\">\n {finalOutput}\n </pre>\n </details>\n )}\n {status === \"done\" && hasStepContent && (\n <div className=\"py-0.5 text-center text-[11px] text-[hsl(var(--muted-foreground))]\">\n ⏹ 流程到此结束\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n","import { Ban, Bot, Check, ChevronRight, FileText, Loader2, MessageSquareMore, X } from \"lucide-react\"\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\"\nimport { collectInlineToolUiCards } from \"@blade-hq/agent-client/internal\"\nimport { isUiMeta } from \"./lib/ui-meta\"\nimport { cn } from \"../lib/utils\"\nimport type { ChatMessage, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport { useSessionState } from \"./runtime/session-source\"\nimport {\n Reasoning,\n ReasoningContent,\n ReasoningTrigger,\n ThinkingBadge,\n} from \"./ai-elements/reasoning\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\nimport { chatTone, type ChatTone } from \"./chat-theme\"\nimport { ToolUiCard } from \"./ToolUiCard\"\nimport { ToolCallBlock } from \"./ToolCallBlock\"\nimport { type UserChatMessage, UserMessageBubble } from \"./UserMessageBubble\"\nimport { formatToolName, getToolDisplayLabel, getToolOutputTag } from \"./display-utils\"\nimport { findLatestReasoningMessageIndex } from \"./reasoning-visibility\"\n\ninterface Props {\n toolCall: ToolCallInfo\n sessionId: string\n reasoning?: string\n hideAskUserQuestions?: boolean\n defaultExpanded?: boolean\n renderDescription?: (description: string) => ReactNode\n}\n\ntype LoopStatus = \"running\" | \"done\" | \"error\" | \"cancelled\" | \"awaiting_answer\"\n\nconst COLLAPSED_SUMMARY_HIDDEN_TOOLS = new Set([\"ReadSkill\", \"Read\"])\n\ntype CompletedToolLabel = {\n key: string\n label: string\n kind: \"file\" | \"tool\"\n}\n\nfunction safeParseDescription(argsStr: string): string {\n try {\n return JSON.parse(argsStr)?.description ?? \"子智能体\"\n } catch {\n return \"子智能体\"\n }\n}\n\nfunction safeParsePrompt(argsStr: string): string {\n try {\n const prompt = JSON.parse(argsStr)?.prompt ?? \"\"\n const marker = \"# 你的任务\"\n const idx = prompt.indexOf(marker)\n if (idx >= 0) {\n return prompt.slice(idx + marker.length).trim()\n }\n return prompt\n } catch {\n return \"\"\n }\n}\n\nfunction stripFileExtension(fileName: string): string {\n return fileName.replace(/\\.[^.]+$/, \"\")\n}\n\nexport function AgentLoopBlock({\n toolCall,\n sessionId,\n reasoning,\n hideAskUserQuestions = false,\n defaultExpanded = false,\n renderDescription,\n}: Props) {\n const agentLoops = useSessionState(sessionId, (state) => state.agentLoops)\n const messages = useSessionState(sessionId, (state) => state.messages)\n const askAnswers = useSessionState(sessionId, (state) => state.askAnswers)\n\n const loopEntry = useMemo(() => {\n for (const [loopName, info] of Object.entries(agentLoops)) {\n if (info.toolCallId === toolCall.id) {\n return { loopName, info }\n }\n }\n return null\n }, [agentLoops, toolCall.id])\n\n const childMessages = useMemo(() => {\n if (!loopEntry) return []\n return messages.filter((message) => (message.loop_name ?? \"root\") === loopEntry.loopName)\n }, [loopEntry, messages])\n\n const loopToolCalls = useMemo(\n () => childMessages.flatMap((message) => message.tool_calls ?? []),\n [childMessages],\n )\n const visibleLoopToolCalls = useMemo(\n () => loopToolCalls.filter((childToolCall) => formatToolName(childToolCall.name) !== \"Agent\"),\n [loopToolCalls],\n )\n const hasAwaitingAnswer = useMemo(\n () => visibleLoopToolCalls.some((childToolCall) =>\n childToolCall.status === \"awaiting_answer\" && !askAnswers?.[childToolCall.id]),\n [visibleLoopToolCalls, askAnswers],\n )\n const [expanded, setExpanded] = useState(defaultExpanded || hasAwaitingAnswer)\n const completedToolLabels = useMemo<CompletedToolLabel[]>(\n () =>\n visibleLoopToolCalls\n .flatMap((childToolCall): CompletedToolLabel[] => {\n const isCompleted =\n childToolCall.status === \"done\" ||\n (childToolCall.status !== \"pending\" &&\n childToolCall.status !== \"awaiting_answer\" &&\n childToolCall.status !== \"error\" &&\n childToolCall.status !== \"cancelled\")\n if (!isCompleted) return []\n\n const outputTag = getToolOutputTag(childToolCall)\n if (outputTag) {\n const fileName = outputTag.label.replace(/^[^\\s]+\\s+/, \"\")\n return [\n {\n key: `${childToolCall.id}-${fileName}`,\n label: stripFileExtension(fileName),\n kind: \"file\",\n },\n ]\n }\n if (COLLAPSED_SUMMARY_HIDDEN_TOOLS.has(formatToolName(childToolCall.name))) {\n return []\n }\n return [\n {\n key: childToolCall.id,\n label: getToolDisplayLabel(childToolCall),\n kind: \"tool\",\n },\n ]\n }),\n [visibleLoopToolCalls],\n )\n const inlineToolUiBlocks = useMemo(\n () => collectInlineToolUiCards(childMessages),\n [childMessages],\n )\n useEffect(() => {\n if (hasAwaitingAnswer) {\n setExpanded(true)\n }\n }, [hasAwaitingAnswer])\n const toggleExpanded = () => setExpanded((value) => !value)\n\n const description = safeParseDescription(toolCall.arguments)\n const status: LoopStatus =\n hasAwaitingAnswer || (toolCall.status === \"awaiting_answer\" && visibleLoopToolCalls.length === 0)\n ? \"awaiting_answer\"\n : toolCall.status === \"pending\" || loopEntry?.info.status === \"running\"\n ? \"running\"\n : toolCall.status === \"error\" || loopEntry?.info.status === \"error\"\n ? \"error\"\n : toolCall.status === \"cancelled\" || loopEntry?.info.status === \"cancelled\"\n ? \"cancelled\"\n : \"done\"\n const latestReasoningIndex =\n status === \"running\" ? findLatestReasoningMessageIndex(childMessages) : -1\n const cardStyles = getLoopCardStyles(status)\n return (\n <div\n part=\"agent-loop\"\n className={cn(\n \"blade-chat-agent-loop overflow-visible rounded-xl border border-[hsl(var(--border))] border-l-[3px] bg-[hsl(var(--card))]/50\",\n cardStyles.borderClass,\n )}\n >\n {status === \"running\" || status === \"awaiting_answer\" ? (\n <>\n <div\n className={cn(\n \"flex items-center gap-3 px-4 py-3 transition-colors\",\n cardStyles.headerClass,\n )}\n >\n <button\n type=\"button\"\n onClick={toggleExpanded}\n aria-expanded={expanded}\n className=\"flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <span className=\"min-w-0 flex items-center gap-2\">\n {status === \"awaiting_answer\" ? (\n <MessageSquareMore size={14} className=\"shrink-0 text-[hsl(var(--swf-warning))] motion-safe:animate-pulse\" />\n ) : (\n <Bot size={14} className=\"shrink-0 text-[hsl(var(--muted-foreground))]\" />\n )}\n <span className=\"truncate text-sm font-medium text-[hsl(var(--foreground))]\">\n {renderDescription ? renderDescription(description) : description}\n {status === \"awaiting_answer\" ? \" — 等待回答\" : \"\"}\n </span>\n </span>\n </button>\n {reasoning ? <ThinkingBadge reasoning={reasoning} variant=\"block\" /> : null}\n <Bot\n size={14}\n className=\"shrink-0 text-[hsl(var(--muted-foreground))]/70\"\n aria-label=\"子智能体\"\n />\n <button\n type=\"button\"\n onClick={toggleExpanded}\n aria-expanded={expanded}\n className=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <ChevronRight\n size={14}\n className={cn(\n \"shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n expanded && \"rotate-90\",\n )}\n />\n </button>\n </div>\n {!expanded ? (\n <div className=\"flex flex-col gap-1 py-2\">\n {visibleLoopToolCalls.length > 0 ? (\n visibleLoopToolCalls.slice(-1).map((childToolCall) => (\n <ToolCallBlock\n key={childToolCall.id}\n toolCall={childToolCall}\n sessionId={sessionId}\n level={2}\n />\n ))\n ) : (\n <div className=\"flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={12} className=\"shrink-0 animate-spin text-[hsl(var(--muted-foreground))]\" />\n <span>正在启动...</span>\n </div>\n )}\n </div>\n ) : status === \"awaiting_answer\" ? (\n <div className=\"flex flex-col gap-1 py-2\">\n <div className=\"px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n 请在下方子智能体对话中完成确认\n </div>\n </div>\n ) : null}\n </>\n ) : (\n <>\n <div\n className={cn(\n \"flex items-center gap-3 px-4 py-3 transition-colors\",\n cardStyles.headerClass,\n )}\n >\n <button\n type=\"button\"\n onClick={toggleExpanded}\n aria-expanded={expanded}\n className=\"flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <span className=\"min-w-0 flex items-center gap-2\">\n {status === \"error\" ? (\n <X size={14} className={cn(\"shrink-0\", cardStyles.iconClass)} />\n ) : status === \"cancelled\" ? (\n <Ban size={14} className={cn(\"shrink-0\", cardStyles.iconClass)} />\n ) : (\n <Check size={14} className=\"shrink-0 text-[hsl(var(--swf-success))]\" />\n )}\n <span className=\"truncate text-sm font-medium text-[hsl(var(--foreground))]\">\n {renderDescription ? renderDescription(description) : description}\n </span>\n </span>\n </button>\n {reasoning ? <ThinkingBadge reasoning={reasoning} variant=\"block\" /> : null}\n <Bot\n size={14}\n className=\"shrink-0 text-[hsl(var(--muted-foreground))]/70\"\n aria-label=\"子智能体\"\n />\n <button\n type=\"button\"\n onClick={toggleExpanded}\n aria-expanded={expanded}\n className=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n >\n <ChevronRight\n size={14}\n className={cn(\n \"shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n expanded && \"rotate-90\",\n )}\n />\n </button>\n </div>\n {!expanded ? (\n <>\n <div className=\"flex flex-wrap gap-1.5 px-4 py-2\">\n {completedToolLabels.length > 0 ? (\n completedToolLabels.map((item) =>\n item.kind === \"file\" ? (\n <span\n key={item.key}\n className=\"inline-flex min-w-0 items-center gap-1 rounded-[6px] bg-[hsl(var(--muted))] px-2 py-0.5 text-xs font-medium text-[hsl(var(--secondary-foreground))]\"\n title={item.label}\n >\n <FileText size={12} className=\"shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{item.label}</span>\n </span>\n ) : (\n <span\n key={item.key}\n className=\"inline-flex items-center rounded-[6px] bg-[hsl(var(--muted))] px-2 py-0.5 text-xs font-medium text-[hsl(var(--secondary-foreground))]\"\n >\n {item.label}\n </span>\n ),\n )\n ) : (\n <span className=\"text-xs text-[hsl(var(--muted-foreground))]\">暂无工具调用</span>\n )}\n </div>\n {inlineToolUiBlocks.length > 0 ? (\n <div className=\"flex flex-col gap-2 px-4 pb-3\">\n {inlineToolUiBlocks.map((block) => (\n <ToolUiCard key={block.key} card={block.card} sessionId={sessionId} />\n ))}\n </div>\n ) : null}\n </>\n ) : null}\n </>\n )}\n {expanded && (\n <div className=\"border-t border-[hsl(var(--border))] py-2\">\n {(() => {\n const taskPrompt = safeParsePrompt(toolCall.arguments)\n return taskPrompt ? (\n <details className=\"mx-3 mb-2 rounded-md bg-[hsl(var(--muted))]/40\">\n <summary className=\"cursor-pointer px-3 py-1.5 text-[11px] font-medium text-[hsl(var(--muted-foreground))]\">\n 任务\n </summary>\n <div className=\"px-3 pb-2\">\n <pre className=\"whitespace-pre-wrap text-[11px] leading-relaxed text-[hsl(var(--foreground))]\">\n {taskPrompt}\n </pre>\n </div>\n </details>\n ) : null\n })()}\n {childMessages.length > 0 ? (\n <div className=\"flex flex-col gap-3 px-3\">\n {childMessages.map((message, index) =>\n message.role === \"assistant\" ? (\n <ExpandedChildAssistantMessage\n key={message.entry_id ?? `${message.timestamp ?? \"child\"}-${index}`}\n message={message}\n sessionId={sessionId}\n isStreaming={message.status === \"streaming\"}\n showReasoning={status !== \"running\" || index === latestReasoningIndex}\n hideAskUserQuestions={hideAskUserQuestions}\n />\n ) : message.role === \"user\" ? (\n <ExpandedChildUserMessage\n key={message.entry_id ?? `${message.timestamp ?? \"user\"}-${index}`}\n message={message as UserChatMessage}\n />\n ) : message.role === \"error\" ? (\n <div\n key={message.entry_id ?? `${message.timestamp ?? \"error\"}-${index}`}\n className=\"border-l-[2px] border-l-[hsl(var(--border))] px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]\"\n >\n {typeof message.content === \"string\" ? message.content : \"子智能体执行出错\"}\n </div>\n ) : null,\n )}\n </div>\n ) : status === \"running\" ? (\n <div className=\"px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={12} className=\"mr-1.5 inline animate-spin\" />\n 正在启动...\n </div>\n ) : toolCall.result ? (\n <pre className=\"max-h-[400px] overflow-auto px-3 py-2 whitespace-pre-wrap text-[11px] text-[hsl(var(--muted-foreground))]\">\n {typeof toolCall.result === \"string\"\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2)}\n </pre>\n ) : null}\n </div>\n )}\n </div>\n )\n}\n\nfunction ExpandedChildUserMessage({ message }: { message: UserChatMessage }) {\n return (\n <div className=\"pl-8\">\n <UserMessageBubble message={message} />\n </div>\n )\n}\n\nfunction ExpandedChildAssistantMessage({\n message,\n sessionId,\n isStreaming,\n showReasoning,\n hideAskUserQuestions,\n}: {\n message: ChatMessage\n sessionId: string\n isStreaming: boolean\n showReasoning: boolean\n hideAskUserQuestions: boolean\n}) {\n const text =\n typeof message.content === \"string\"\n ? message.content.trim()\n : message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\")\n .trim()\n const toolCalls = hideAskUserQuestions\n ? (message.tool_calls ?? []).filter(\n (toolCall) => formatToolName(toolCall.name) !== \"AskUserQuestion\",\n )\n : message.tool_calls ?? []\n const hasToolCalls = toolCalls.length > 0\n // 子会话的上下文注入等条目也是 assistant 消息但没内容;渲染空壳会被外层 gap 撑出大片空白\n if (\n !text &&\n !hasToolCalls &&\n !(showReasoning && message.reasoning) &&\n !message.blocks?.some((block) => block.type === \"tool_ui\")\n ) {\n return null\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {showReasoning && message.reasoning && (\n <Reasoning isStreaming={isStreaming}>\n <ReasoningTrigger wordCount={message.reasoning.length} />\n <ReasoningContent>{message.reasoning}</ReasoningContent>\n </Reasoning>\n )}\n {text ? (\n <ChildText\n text={text}\n isStreaming={isStreaming}\n sessionId={sessionId}\n reasoning={undefined}\n />\n ) : null}\n {hasToolCalls && (\n <div className=\"flex flex-col gap-2\">\n {toolCalls.map((toolCall) =>\n formatToolName(toolCall.name) === \"Agent\" ? (\n <AgentLoopBlock\n key={toolCall.id}\n toolCall={toolCall}\n sessionId={sessionId}\n reasoning={undefined}\n hideAskUserQuestions={hideAskUserQuestions}\n />\n ) : (\n <ToolCallBlock\n key={toolCall.id}\n toolCall={toolCall}\n sessionId={sessionId}\n level={2}\n turnBlocks={message.blocks}\n reasoning={undefined}\n />\n ),\n )}\n </div>\n )}\n {message.blocks?.some((block) => block.type === \"tool_ui\") ? (\n <div className=\"flex flex-col gap-2\">\n {message.blocks.map((block, index) =>\n block.type === \"tool_ui\" &&\n block.tool_call_id &&\n isUiMeta(block.content) &&\n block.content.target === \"inline\" ? (\n <div key={`${block.tool_call_id}-${index}`} className=\"ml-4\">\n <ToolUiCard card={block.content} sessionId={sessionId} />\n </div>\n ) : null,\n )}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction ChildText({\n text,\n isStreaming,\n sessionId,\n reasoning,\n}: { text: string; isStreaming: boolean; sessionId: string; reasoning?: string }) {\n return (\n <div className=\"pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]\">\n <MarkdownContent\n mode={isStreaming ? \"streaming\" : \"static\"}\n sessionId={sessionId}\n className=\"prose prose-sm prose-invert inline max-w-none [&_li>p]:inline [&_p]:mb-2 [&_p:last-child]:mb-0 [&_p:last-child]:inline\"\n controls={{ code: true }}\n >\n {text}\n </MarkdownContent>\n {isStreaming && (\n <span className=\"ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60\" />\n )}\n {reasoning ? <ThinkingBadge reasoning={reasoning} /> : null}\n </div>\n )\n}\n\nfunction getLoopCardStyles(status: LoopStatus) {\n const toneOf = (tone: ChatTone) => {\n const style = chatTone(tone)\n return { borderClass: style.border, headerClass: style.surface, iconClass: style.text }\n }\n\n if (status === \"running\") {\n return toneOf(\"running\")\n }\n\n if (status === \"awaiting_answer\") {\n return toneOf(\"warning\")\n }\n\n if (status === \"cancelled\") {\n return toneOf(\"warning\")\n }\n\n if (status === \"error\") {\n return toneOf(\"danger\")\n }\n\n return {\n borderClass: \"border-l-[hsl(var(--primary))]\",\n headerClass: \"bg-[hsl(var(--primary)/0.05)]\",\n iconClass: \"text-[hsl(var(--primary))]\",\n }\n}\n","import { useEffect, useRef, useState } from \"react\"\nimport type { ContextAttachment } from \"@blade-hq/agent-client\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { AttachmentPreviewDialog } from \"./AttachmentPreviewDialog\"\nimport { dispatchPreview } from \"./lib/preview-dispatch\"\n\nexport function ContextAttachmentPills({ attachments }: { attachments?: ContextAttachment[] }) {\n const client = useOptionalBladeClient()\n const download = useRef<AbortController | null>(null)\n useEffect(() => () => download.current?.abort(), [])\n const [selected, setSelected] = useState<ContextAttachment | null>(null)\n const [preview, setPreview] = useState<{ name: string; url: string; mode: \"markdown\" | \"text\" | \"default\" } | null>(null)\n const [loading, setLoading] = useState<string | null>(null)\n const [unavailable, setUnavailable] = useState<string | null>(null)\n useEffect(() => () => { if (preview) URL.revokeObjectURL(preview.url) }, [preview])\n if (!attachments?.length) return null\n const openFile = async (file: NonNullable<ContextAttachment[\"files\"]>[number]) => {\n if (!client || !file.session_id || !file.path) { setUnavailable(file.name); return }\n const controller = new AbortController()\n download.current?.abort()\n download.current = controller\n setLoading(file.name)\n setUnavailable(null)\n try {\n const response = await client.fetch(\"GET\", `/api/sessions/${encodeURIComponent(file.session_id)}/files/${encodeURIComponent(file.path)}`, { signal: controller.signal })\n const blob = await response.blob()\n if (controller.signal.aborted) return\n const url = URL.createObjectURL(blob)\n const kind = dispatchPreview(file.name, url).kind\n setPreview({ name: file.name, url, mode: kind === \"text\" ? (file.name.endsWith(\".md\") ? \"markdown\" : \"text\") : \"default\" })\n } catch { if (!controller.signal.aborted) setUnavailable(file.name) }\n finally { if (!controller.signal.aborted) setLoading(null) }\n }\n return <>\n <div className=\"flex max-w-full flex-wrap justify-end gap-1.5\" aria-label=\"附加资料\">\n {attachments.map(item => <button type=\"button\" key={item.id} onClick={() => { setSelected(selected?.id === item.id ? null : item); setUnavailable(null) }} aria-expanded={selected?.id === item.id} className=\"max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground\">{item.label}</button>)}\n </div>\n {selected && <div className=\"max-w-full rounded-xl border border-border bg-muted p-3 text-sm text-foreground\">\n <div className=\"mb-2 font-medium\">{selected.label}</div>\n <div className=\"whitespace-pre-wrap break-words\">{selected.content}</div>\n {selected.files?.map((file, index) => <button key={index} type=\"button\" disabled={loading != null || !file.path || !file.session_id} onClick={() => void openFile(file)} className=\"mt-2 block max-w-full truncate text-left underline\">{file.name}{!file.path || !file.session_id ? ' · 文件不可用' : loading === file.name ? ' · 读取中' : ''}</button>)}\n {unavailable && <output className=\"mt-2 block text-xs text-muted-foreground\">{unavailable} · 文件不可用</output>}\n </div>}\n {preview && <AttachmentPreviewDialog open onOpenChange={open => { if (!open) setPreview(null) }} filename={preview.name} url={preview.url} mode={preview.mode} />}\n </>\n}\n","import { useEffect, useState } from \"react\"\n\n/**\n * 按 key 异步取一个值(聊天组件里零星的文件读取用,不引入请求缓存库)。\n * key 变化或卸载时中止在途请求;过期结果不写回。\n */\nexport function useAsyncValue<T>(\n key: string | null,\n load: (signal: AbortSignal) => Promise<T>,\n): { data: T | undefined; error: Error | null } {\n const [result, setResult] = useState<{ key: string; data?: T; error: Error | null } | null>(null)\n // biome-ignore lint/correctness/useExhaustiveDependencies: 只按 key 重取,load 每次渲染都是新闭包\n useEffect(() => {\n if (key === null) return\n const controller = new AbortController()\n load(controller.signal).then(\n (data) => {\n if (!controller.signal.aborted) setResult({ key, data, error: null })\n },\n (error: unknown) => {\n if (!controller.signal.aborted) {\n setResult({ key, error: error instanceof Error ? error : new Error(String(error)) })\n }\n },\n )\n return () => controller.abort()\n }, [key])\n const current = result && result.key === key ? result : null\n return { data: current?.data, error: current?.error ?? null }\n}\n","import { Download, X } from \"lucide-react\"\nimport { useAsyncValue } from \"./lib/use-async-value\"\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from \"@blade-hq/ui/composites/dialog\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\n\n/**\n * R6:用户上传的附件(文本 / 未知类型)预览弹窗。\n *\n * 图片走独立的 ImageLightbox;本组件处理:\n * - .md → markdown 渲染\n * - .json / .txt / .yaml / .yml / 其他文本 → 纯文本等宽展示\n * - 不可在浏览器内渲染的类型 → 下载链接兜底\n *\n * 无 URL 时兜底为只显示文件名 + 下载入口。\n */\n\ninterface Props {\n open: boolean\n onOpenChange: (open: boolean) => void\n filename: string\n /**\n * 由调用方用 `getAuthedUrl()` 构造的完整 URL(baseUrl + 路径 + ?token=…)。\n * 内部 fetch 直接用原串,**不**再走 `apiFetchText` —— 否则会二次拼 baseUrl,\n * 在独立前后端部署时会得到形如 `http://api.xxxhttp://api.xxx/…` 的非法 URL。\n * token 靠 query 字符串携带,因此也不需要再挂 Authorization header。\n */\n url: string | null\n mode: \"markdown\" | \"text\" | \"default\"\n}\n\nexport function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }: Props) {\n const enabled = open && url != null && (mode === \"markdown\" || mode === \"text\")\n const { data: content, error } = useAsyncValue(enabled ? `${mode}:${url}` : null, async (signal) => {\n if (!url) return null\n const res = await fetch(url, {\n signal,\n credentials: \"include\",\n })\n if (!res.ok) {\n const body = await res.text().catch(() => \"\")\n throw new Error(`加载失败(HTTP ${res.status})${body ? `:${body.slice(0, 200)}` : \"\"}`)\n }\n return res.text()\n })\n\n if (!open) return null\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n showCloseButton={false}\n className=\"flex max-h-[90vh] w-full max-w-3xl flex-col gap-0 overflow-hidden p-0\"\n >\n <div className=\"flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3\">\n <DialogTitle className=\"truncate text-sm font-semibold text-[hsl(var(--foreground))]\">\n {filename}\n </DialogTitle>\n <div className=\"flex items-center gap-1\">\n {url && (\n <a\n href={url}\n download={filename}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"下载\"\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n <Download size={14} />\n </a>\n )}\n <DialogClose\n title=\"关闭\"\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n <X size={14} />\n </DialogClose>\n </div>\n </div>\n <div className=\"max-h-[calc(90vh-56px)] overflow-auto px-4 py-3 text-sm text-[hsl(var(--foreground))]\">\n {renderContent({ mode, url, content, error })}\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction renderContent({\n mode,\n url,\n content,\n error,\n}: {\n mode: \"markdown\" | \"text\" | \"default\"\n url: string | null\n content: string | null | undefined\n error: unknown\n}) {\n if (!url) {\n return <p className=\"text-[hsl(var(--muted-foreground))]\">此附件暂无可用预览地址。</p>\n }\n if (mode === \"default\") {\n return (\n <p className=\"text-[hsl(var(--muted-foreground))]\">\n 此类型暂不支持内嵌预览。请点击右上角\n <span className=\"mx-1 font-medium text-[hsl(var(--foreground))]\">下载</span>\n 按钮查看。\n </p>\n )\n }\n if (error) {\n return <p className=\"text-[hsl(var(--destructive))]\">加载失败:{String((error as Error)?.message ?? error)}</p>\n }\n if (content == null) {\n return <p className=\"text-[hsl(var(--muted-foreground))]\">加载中…</p>\n }\n if (mode === \"markdown\") {\n return (\n <MarkdownContent className=\"prose prose-sm prose-invert max-w-none\">{content}</MarkdownContent>\n )\n }\n return (\n <pre className=\"whitespace-pre-wrap font-mono text-xs leading-relaxed\">{content}</pre>\n )\n}\n","/**\n * 按文件扩展名决定预览渲染方式(R6)。\n *\n * 为什么按扩展名不按 MIME:当前消息 schema 里 FileContentPart / TextAttachment\n * 都只存 `name` + `uploadedPath`,没有 mime_type(见 design.md §3.6)。\n * 改 schema 面太大,扩展名在实际数据里足够稳定(前端上传时就是文件名)。\n *\n * 动图(.gif/.webp/.apng/.avif)归为 image,因为浏览器 `<img>` 原生播放。\n * video 类扩展名本期不覆盖(见 design.md §3.6 决策:\"只动图,不视频\")。\n */\n\nconst IMAGE_EXTS = [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".bmp\",\n \".svg\",\n \".heic\",\n \".gif\",\n \".webp\",\n \".apng\",\n \".avif\",\n] as const\n\nconst TEXT_EXTS = [\".md\", \".json\", \".txt\", \".yaml\", \".yml\"] as const\n\nexport type PreviewKind = \"image\" | \"text\" | \"default\"\n\nexport interface PreviewDescriptor {\n kind: PreviewKind\n filename: string\n url: string\n}\n\nfunction lower(filename: string): string {\n return filename.toLowerCase()\n}\n\nfunction endsWithAny(name: string, exts: readonly string[]): boolean {\n const n = lower(name)\n for (const ext of exts) {\n if (n.endsWith(ext)) return true\n }\n return false\n}\n\n/**\n * 判断扩展名能不能用 `<img>` 预览(含动图)。\n * 独立导出是为了让调用方可以在不走完整 dispatchPreview 的场景(如 UserMessageBubble\n * 已经在 render 时把图片渲染成 <img>,不需要再走 kind 分派)直接查一次。\n */\nexport function isImageFilename(filename: string): boolean {\n return endsWithAny(filename, IMAGE_EXTS)\n}\n\nexport function isTextFilename(filename: string): boolean {\n return endsWithAny(filename, TEXT_EXTS)\n}\n\nexport function dispatchPreview(filename: string, url: string): PreviewDescriptor {\n if (isImageFilename(filename)) return { kind: \"image\", filename, url }\n if (isTextFilename(filename)) return { kind: \"text\", filename, url }\n return { kind: \"default\", filename, url }\n}\n","import { ContextAttachmentPills } from \"./ContextAttachmentPills\"\nimport { MessageImage } from \"../components/MessageImage\"\nimport { chatErrorForDisplay } from \"@blade-hq/agent-client\"\nimport { useEffect, useState } from \"react\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { extractTextAttachments, getFileParts, getImageParts, getTextContent } from \"@blade-hq/agent-client/internal\"\nimport { dispatchPreview, isImageFilename } from \"./lib/preview-dispatch\"\nimport { parseWhatIfPrompt } from \"../lib/whatif-prompt\"\nimport type { ChatMessage } from \"@blade-hq/agent-client/internal\"\nimport { useAsyncValue } from \"./lib/use-async-value\"\nimport { useCurrentChatSessionId } from \"./runtime/session-source\"\nimport { cn } from \"../lib/utils\"\nimport { useChatCustomization } from \"./customization\"\nimport { MarkdownContent } from \"./markdown/MarkdownContent\"\nimport { AttachmentPreviewDialog } from \"./AttachmentPreviewDialog\"\nimport { ImageLightbox } from \"./ImageLightbox\"\nimport { MessageContextPills } from \"./MessageContextPills\"\nimport { MessageFileAttachmentList } from \"./MessageFileAttachmentList\"\nimport { MessageActions } from \"./MessageActions\"\nimport { TextAttachmentPills } from \"./TextAttachmentPills\"\nimport { WhatIfUserBubble } from \"../components/WhatIfUserBubble\"\n\nexport type UserChatMessage = ChatMessage & { role: \"user\" }\nexport type ErrorChatMessage = ChatMessage & { role: \"error\" }\n\nexport function isUserMessage(message: ChatMessage): message is UserChatMessage {\n return message.role === \"user\"\n}\n\nexport function isErrorMessage(message: ChatMessage): message is ErrorChatMessage {\n return message.role === \"error\"\n}\n\ninterface UserMessageProps {\n message: UserChatMessage\n className?: string\n}\n\nexport const USER_MESSAGE_MARKDOWN_CLASS =\n \"prose prose-invert chat-prose max-w-none [&_li>p]:inline [&_li>p]:whitespace-pre-wrap [&_p]:whitespace-pre-wrap\"\n\nfunction isImageTextAttachment(name: string, uploadedPath?: string): boolean {\n return isImageFilename(name) || isImageFilename(uploadedPath ?? \"\")\n}\n\nfunction sessionFilePath(sessionId: string, filePath: string): string {\n return `/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(filePath)}`\n}\n\nfunction useAttachmentImageUrls(sessionId: string | null, filePaths: string[]): Array<string | null | undefined> {\n const client = useOptionalBladeClient()\n const key = sessionId && client && filePaths.length > 0 ? `${sessionId}\\n${filePaths.join(\"\\n\")}` : null\n const { data } = useAsyncValue(key, async (signal) => {\n if (!sessionId || !client) return []\n const results = await Promise.allSettled(\n filePaths.map(async (filePath) => {\n const response = await client.fetch(\"GET\", sessionFilePath(sessionId, filePath), { signal })\n return URL.createObjectURL(await response.blob())\n }),\n )\n return results.map((result) => (result.status === \"fulfilled\" ? result.value : null))\n })\n useEffect(\n () => () => {\n for (const url of data ?? []) if (url) URL.revokeObjectURL(url)\n },\n [data],\n )\n return filePaths.map((_, index) => data?.[index])\n}\n\nconst isSending = (message: ChatMessage) => message.status === \"streaming\"\n\nexport function UserMessageBubble({ message, className }: UserMessageProps) {\n const activeSessionId = useCurrentChatSessionId()\n const client = useOptionalBladeClient()\n const customBubble = useChatCustomization()?.renderers?.userMessage?.({ message })\n const _textContent = getTextContent(message.content)\n const fileParts = getFileParts(message.content)\n const imageParts = getImageParts(message.content)\n const {\n cleanText,\n attachments: textAttachments,\n contexts: textContexts,\n } = extractTextAttachments(message.content)\n const trimmedClean = cleanText.trim()\n const pluginPills = message.refs?.length ? <div className=\"flex flex-wrap justify-end gap-1.5\" aria-label=\"消息引用\">{message.refs.map((ref) => <span key={ref.provider === \"skill\" ? `skill:${ref.id}` : `${ref.plugin}:${ref.server}:${ref.id}`} className=\"max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs\">{ref.provider === \"skill\" ? `技能 · ${ref.label}` : ref.label}</span>)}</div> : null\n const topicAssetPills = message.topic_asset_refs?.length ? (\n <div className=\"flex max-w-full flex-wrap justify-end gap-1.5\" aria-label=\"引用的工作空间资产\">\n {message.topic_asset_refs.map((ref) => (\n <span key={`${ref.topic_id}:${ref.path}`} title={ref.path} className=\"max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground\">\n 工作空间资产 · {ref.path}\n </span>\n ))}\n </div>\n ) : null\n\n const whatifParsed =\n trimmedClean &&\n imageParts.length === 0 &&\n fileParts.length === 0 &&\n textAttachments.length === 0\n ? parseWhatIfPrompt(cleanText)\n : null\n if (whatifParsed && customBubble == null) {\n return (\n <div part=\"user-row\" className=\"blade-chat-user-row flex justify-end\">\n <div className=\"blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-2\">\n {pluginPills}\n {topicAssetPills}\n <ContextAttachmentPills attachments={message.context_attachments} />\n <WhatIfUserBubble parsed={whatifParsed} />\n {whatifParsed.userText && (\n <MessageActions\n content={whatifParsed.userText}\n className=\"opacity-0 [@media(hover:none)]:opacity-100 transition-opacity group-hover:opacity-100\"\n />\n )}\n </div>\n </div>\n )\n }\n const imageSourcePaths = new Set(imageParts.map((part) => part.image_url.source_path))\n const imageTextAttachmentMeta = activeSessionId\n ? textAttachments.flatMap((attachment) => {\n if (!isImageTextAttachment(attachment.name, attachment.uploadedPath)\n || imageSourcePaths.has(attachment.uploadedPath ?? attachment.name)) return []\n return [{ ...attachment, filePath: attachment.uploadedPath ?? attachment.name }]\n })\n : []\n const nonImageTextAttachments = textAttachments.filter(\n (attachment) => !isImageTextAttachment(attachment.name, attachment.uploadedPath),\n )\n\n const imageAttachmentUrls = useAttachmentImageUrls(\n activeSessionId,\n imageTextAttachmentMeta.map((attachment) => attachment.filePath),\n )\n\n const lightboxImages = [\n ...imageParts.map((part) => ({\n src: part.image_url.url,\n alt: \"用户上传的图片\",\n })),\n ...imageAttachmentUrls.map((url, i) => ({\n src: url ?? \"\",\n alt: imageTextAttachmentMeta[i]?.name || \"用户上传的图片\",\n })),\n ]\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null)\n\n const [preview, setPreview] = useState<{\n filename: string\n url: string\n mode: \"markdown\" | \"text\" | \"default\"\n } | null>(null)\n const handleTextAttachmentPreview = (\n attachment: { name: string; uploadedPath?: string },\n ) => {\n if (!activeSessionId || !client) return\n const pathForUrl = attachment.uploadedPath ?? attachment.name\n const url = client.buildAuthedUrl(sessionFilePath(activeSessionId, pathForUrl))\n const kind = dispatchPreview(attachment.name, url).kind\n if (kind === \"image\") {\n const existingIdx = lightboxImages.findIndex((img) => img.src === url)\n if (existingIdx >= 0) {\n setLightboxIndex(existingIdx)\n } else {\n setPreview({ filename: attachment.name, url, mode: \"default\" })\n }\n return\n }\n const lower = attachment.name.toLowerCase()\n const mode: \"markdown\" | \"text\" | \"default\" =\n kind === \"text\" ? (lower.endsWith(\".md\") ? \"markdown\" : \"text\") : \"default\"\n setPreview({ filename: attachment.name, url, mode })\n }\n\n return (\n <div part=\"user-row\" className={cn(\"blade-chat-user-row flex justify-end\", className)}>\n <div className=\"blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-3\">\n {(imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && (\n <div className=\"grid gap-2\">\n {imageParts.map((part, idx) => (\n <button\n type=\"button\"\n key={part.image_url.url}\n onClick={() => setLightboxIndex(idx)}\n className=\"cursor-zoom-in\"\n title=\"查看大图\"\n >\n <MessageImage\n src={part.image_url.url}\n width={part.image_url.width}\n height={part.image_url.height}\n alt=\"用户上传的图片\"\n className=\"max-h-64 rounded-xl border border-[hsl(var(--user-msg-border))] object-cover\"\n />\n </button>\n ))}\n {imageTextAttachmentMeta.map((att, idx) => {\n const blobUrl = imageAttachmentUrls[idx]\n return blobUrl ? (\n <button\n type=\"button\"\n key={`${att.uploadedPath}:${att.name}`}\n onClick={() => setLightboxIndex(imageParts.length + idx)}\n className=\"cursor-zoom-in\"\n title=\"查看大图\"\n >\n <img\n src={blobUrl}\n alt={att.name || \"用户上传的图片\"}\n className=\"max-h-64 rounded-xl border border-[hsl(var(--user-msg-border))] object-cover\"\n />\n </button>\n ) : blobUrl === null ? null : (\n <div\n key={`${att.uploadedPath}:${att.name}`}\n className=\"flex h-20 items-center justify-center rounded-xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] text-xs text-[hsl(var(--muted-foreground))]\"\n >\n 加载中...\n </div>\n )\n })}\n </div>\n )}\n {lightboxImages.length > 0 && (\n <ImageLightbox\n open={lightboxIndex != null}\n onOpenChange={(open) => {\n if (!open) setLightboxIndex(null)\n }}\n images={lightboxImages}\n initialIndex={lightboxIndex ?? 0}\n />\n )}\n <MessageFileAttachmentList files={fileParts} />\n <TextAttachmentPills\n attachments={nonImageTextAttachments}\n onPreview={handleTextAttachmentPreview}\n />\n {preview && (\n <AttachmentPreviewDialog\n open={preview != null}\n onOpenChange={(open) => {\n if (!open) setPreview(null)\n }}\n filename={preview.filename}\n url={preview.url}\n mode={preview.mode}\n />\n )}\n <MessageContextPills contexts={textContexts} />\n {pluginPills}\n {topicAssetPills}\n <ContextAttachmentPills attachments={message.context_attachments} />\n {trimmedClean && (\n customBubble != null ? customBubble : <div\n part=\"user-bubble\"\n className={cn(\"blade-chat-user-bubble max-w-full rounded-[24px] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-base leading-[1.7] transition-colors duration-200\",\n isSending(message) ? \"text-[hsl(var(--muted-foreground))]\" : \"text-[hsl(var(--user-msg-fg))]\")}>\n <MarkdownContent\n className={cn(USER_MESSAGE_MARKDOWN_CLASS, \"text-inherit [&_strong]:text-inherit [&_p]:text-inherit\")}\n controls={{ code: true }}\n >\n {cleanText}\n </MarkdownContent>\n </div>\n )}\n {trimmedClean && !isSending(message) && (\n <MessageActions content={cleanText} className=\"opacity-0 transition-opacity group-hover:opacity-100 [@media(hover:none)]:opacity-100\" />\n )}\n </div>\n </div>\n )\n}\n\nexport function ErrorMessageBlock({\n message,\n className,\n}: {\n message: ErrorChatMessage\n className?: string\n}) {\n const text = chatErrorForDisplay(getTextContent(message.content))\n const looksLikeModelUnavailable = /no source matches this model|404/i.test(text)\n return (\n <div part=\"error-row\" className={cn(\"blade-chat-error-row flex min-w-0 justify-start\", className)}>\n <div className=\"min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]\">\n {text}\n {looksLikeModelUnavailable ? (\n <div className=\"mt-1 opacity-80\">模型可能未启动,请稍后重试。</div>\n ) : null}\n </div>\n </div>\n )\n}\n","/** 一条 canonical what-if 消息中的引用快照。 */\nexport interface WhatIfQuote {\n stepNumber: number | null\n label: string\n snapshot: string\n}\n\nexport interface ParsedWhatIfPrompt {\n fromStep: number | null\n quotes: WhatIfQuote[]\n userText: string\n}\n\nconst HEADER_RE =\n /^以下消息和 step 产物标记为 deprecated_by_rerun,请基于最新用户假设从 step(\\d+) 开始完整重新推演,不要复用旧结论。$/\nconst QUOTE_HEADER_RE = /^\\[步骤(\\d+)\\s*·\\s*(.+?)\\]$/\nconst USER_INPUT_TAG = \"[用户输入]\"\n\n/**\n * 解析 Server 历史与流式消息共用的 canonical what-if 文本。\n *\n * 无 `[用户输入]` 标签的历史消息仍按最后一条快照尾部的空行切分,保持内置\n * Web 原有兼容行为。\n */\nexport function parseWhatIfPrompt(text: string): ParsedWhatIfPrompt | null {\n const lines = text.replace(/\\r\\n/g, \"\\n\").trimEnd().split(\"\\n\")\n const headerMatch = lines[0]?.match(HEADER_RE)\n if (!headerMatch) return null\n\n const userTagIdx = lines.indexOf(USER_INPUT_TAG)\n const hasUserTag = userTagIdx >= 0\n const quoteBlockEndExclusive = hasUserTag ? userTagIdx : lines.length\n const quoteHeaderIdxs: number[] = []\n let quoteBlockFound = false\n for (let i = 1; i < quoteBlockEndExclusive; i++) {\n if (!quoteBlockFound && lines[i].trim() === \"[引用]\") {\n quoteBlockFound = true\n } else if (quoteBlockFound && QUOTE_HEADER_RE.test(lines[i])) {\n quoteHeaderIdxs.push(i)\n }\n }\n\n let legacyUserTextStart = -1\n if (!hasUserTag && quoteHeaderIdxs.length > 0) {\n const lastSnapshotStart = quoteHeaderIdxs.at(-1)! + 1\n let i = lines.length - 1\n while (i >= lastSnapshotStart && lines[i].trim() === \"\") i -= 1\n while (i >= lastSnapshotStart && lines[i].trim() !== \"\") i -= 1\n if (i >= lastSnapshotStart) legacyUserTextStart = i + 1\n }\n\n const quotes = quoteHeaderIdxs.map((headerIdx, index) => {\n const match = lines[headerIdx].match(QUOTE_HEADER_RE)!\n const nextHeader = quoteHeaderIdxs[index + 1]\n const end = nextHeader ?? (legacyUserTextStart >= 0 ? legacyUserTextStart : quoteBlockEndExclusive)\n const snapshotLines = lines.slice(headerIdx + 1, end)\n while (snapshotLines.at(-1)?.trim() === \"\") snapshotLines.pop()\n return {\n stepNumber: Number.parseInt(match[1], 10),\n label: match[2].trim(),\n snapshot: snapshotLines.join(\"\\n\"),\n }\n })\n\n const userTextStart = hasUserTag ? userTagIdx + 1 : legacyUserTextStart\n const userLines = userTextStart >= 0 ? lines.slice(userTextStart) : []\n while (userLines[0]?.trim() === \"\") userLines.shift()\n while (userLines.at(-1)?.trim() === \"\") userLines.pop()\n\n const fromStep = Number.parseInt(headerMatch[1], 10)\n return {\n fromStep: Number.isFinite(fromStep) ? fromStep : null,\n quotes,\n userText: userLines.join(\"\\n\"),\n }\n}\n","import { Bookmark } from \"lucide-react\"\nimport type { ParsedTextContext } from \"@blade-hq/agent-client/internal\"\n\ninterface MessageContextPillsProps {\n contexts: ParsedTextContext[]\n}\n\nexport function MessageContextPills({ contexts }: MessageContextPillsProps) {\n if (contexts.length === 0) return null\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {contexts.map((ctx, index) => (\n <div\n key={`${ctx.label}:${index}`}\n className=\"flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.25)] bg-[hsl(var(--primary)/0.1)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.85)]\"\n title={ctx.content}\n >\n <Bookmark size={12} className=\"shrink-0 text-[hsl(var(--primary)/0.65)]\" />\n <span className=\"max-w-56 truncate\">{ctx.label}</span>\n </div>\n ))}\n </div>\n )\n}\n","import { Archive, File, FileCode2, FileText, Film, Music, FileSpreadsheet, Image } from \"lucide-react\"\nimport type { ParsedTextAttachment } from \"@blade-hq/agent-client/internal\"\n\nfunction getFileIcon(fileName: string) {\n const lower = fileName.toLowerCase()\n if (/\\.(zip|rar|7z|tar|gz)$/.test(lower)) return Archive\n if (/\\.(ts|tsx|js|jsx|py|go|rs|java|html|json|yaml|yml|css)$/.test(lower)) return FileCode2\n if (/\\.(mp3|wav|flac|m4a|aac|ogg)$/.test(lower)) return Music\n if (/\\.(mp4|mov|mkv|avi|webm)$/.test(lower)) return Film\n if (/\\.(png|jpg|jpeg|gif|svg|webp|bmp)$/.test(lower)) return Image\n if (/\\.(xlsx?|csv)$/.test(lower)) return FileSpreadsheet\n if (/\\.(txt|pdf|docx?|rtf|md)$/.test(lower)) return FileText\n return File\n}\n\ninterface TextAttachmentPillsProps {\n attachments: ParsedTextAttachment[]\n onPreview?: (attachment: ParsedTextAttachment) => void\n}\n\nexport function TextAttachmentPills({ attachments, onPreview }: TextAttachmentPillsProps) {\n if (attachments.length === 0) return null\n\n const pillClass =\n \"flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.2)] bg-[hsl(var(--primary)/0.08)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.8)]\"\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {attachments.map((att, index) => {\n const Icon = getFileIcon(att.name)\n const key = `${att.uploadedPath ?? att.name}:${att.name}:${index}`\n const content = (\n <>\n <Icon size={12} className=\"shrink-0 text-[hsl(var(--primary)/0.6)]\" />\n <span className=\"max-w-40 truncate\">{att.name}</span>\n </>\n )\n if (onPreview) {\n return (\n <button\n key={key}\n type=\"button\"\n onClick={() => onPreview(att)}\n className={`${pillClass} cursor-pointer transition-colors hover:border-[hsl(var(--primary)/0.45)]`}\n title={`预览 ${att.name}`}\n >\n {content}\n </button>\n )\n }\n return (\n <div key={key} className={pillClass} title={att.name}>\n {content}\n </div>\n )\n })}\n </div>\n )\n}\n","import { RefreshCcw } from \"lucide-react\"\nimport type { ParsedWhatIfPrompt } from \"../lib/whatif-prompt\"\nimport { MarkdownContent } from \"../chat/markdown/MarkdownContent\"\n\nexport interface WhatIfUserBubbleProps {\n parsed: ParsedWhatIfPrompt\n onQuoteClick?: (stepNumber: number) => void\n}\n\n/** SDK 与内置 Web 共用的 canonical 引用消息渲染。 */\nexport function WhatIfUserBubble({ parsed, onQuoteClick }: WhatIfUserBubbleProps) {\n const { fromStep, quotes, userText } = parsed\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.5)] px-2.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]\">\n <RefreshCcw size={10} />\n <span>{fromStep != null ? `重跑自 step ${fromStep}` : \"重跑\"}</span>\n </div>\n {quotes.length > 0 && (\n <div className=\"flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2\">\n {quotes.map((quote, index) => {\n const clickable = quote.stepNumber != null && !!onQuoteClick\n const label = quote.stepNumber != null ? `步骤${quote.stepNumber} · ${quote.label}` : quote.label\n return (\n <div key={`${quote.stepNumber ?? \"x\"}-${index}`} className=\"rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left\">\n <button type=\"button\" disabled={!clickable} onClick={() => clickable && onQuoteClick(quote.stepNumber!)} className=\"inline-flex max-w-full items-center gap-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] disabled:cursor-default\" title={clickable ? \"跳转到对应步骤卡片\" : undefined}>\n <span>↳</span><span className=\"truncate\">{label}</span>\n </button>\n {quote.snapshot ? <div className=\"mt-1 border-l-2 border-[hsl(var(--accent-foreground)/0.35)] pl-2 text-xs leading-relaxed text-[hsl(var(--foreground)/0.8)]\"><MarkdownContent className=\"blade-chat-prose\">{quote.snapshot}</MarkdownContent></div> : null}\n </div>\n )\n })}\n </div>\n )}\n {userText && <div className=\"rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))]\"><MarkdownContent className=\"blade-chat-prose\">{userText}</MarkdownContent></div>}\n </div>\n )\n}\n","import type { ChatMessage } from \"@blade-hq/agent-client/internal\"\n\nexport function findLatestReasoningMessageIndex(messages: readonly ChatMessage[]): number {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index].reasoning) return index\n }\n return -1\n}\n","import type { ChatMessage, ToolCallInfo } from \"@blade-hq/agent-client/internal\"\nimport type { AskUserAnswerData } from \"./AskUserQuestionBlock\"\nimport { formatToolName } from \"./display-utils\"\n\nfunction getAgentToolCallIds(messages: ChatMessage[]) {\n return new Set(\n messages\n .flatMap((message) => message.tool_calls ?? [])\n .filter((toolCall) => formatToolName(toolCall.name) === \"Agent\")\n .map((toolCall) => toolCall.id),\n )\n}\n\nexport function collectTurnMessages({\n rootMessages,\n sessionMessages,\n agentLoops,\n}: {\n rootMessages: ChatMessage[]\n sessionMessages: ChatMessage[]\n agentLoops: Record<string, { toolCallId: string }>\n}) {\n const collectedLoopNames = new Set<string>()\n const visitedToolCallIds = new Set<string>()\n let pendingToolCallIds = [...getAgentToolCallIds(rootMessages)]\n\n while (pendingToolCallIds.length > 0) {\n const currentIds = pendingToolCallIds\n pendingToolCallIds = []\n\n for (const [loopName, info] of Object.entries(agentLoops)) {\n if (collectedLoopNames.has(loopName) || visitedToolCallIds.has(info.toolCallId)) continue\n if (!currentIds.includes(info.toolCallId)) continue\n\n visitedToolCallIds.add(info.toolCallId)\n collectedLoopNames.add(loopName)\n const childMessages = sessionMessages.filter((message) => message.loop_name === loopName)\n pendingToolCallIds.push(...getAgentToolCallIds(childMessages))\n }\n }\n\n if (collectedLoopNames.size === 0) return rootMessages\n\n const rootIds = new Set(rootMessages.map((message) => message.entry_id).filter(Boolean))\n const childMessages = sessionMessages.filter(\n (message) =>\n message.loop_name &&\n collectedLoopNames.has(message.loop_name) &&\n (!message.entry_id || !rootIds.has(message.entry_id)),\n )\n const merged = [...rootMessages, ...childMessages]\n merged.sort((a, b) => {\n const ta = a.timestamp ?? \"\"\n const tb = b.timestamp ?? \"\"\n return ta < tb ? -1 : ta > tb ? 1 : 0\n })\n return merged\n}\n\nexport function getPersistentAskUserQuestions(messages: ChatMessage[]) {\n return messages.flatMap((message) =>\n (message.tool_calls ?? [])\n .filter((toolCall) => formatToolName(toolCall.name) === \"AskUserQuestion\")\n .map((toolCall) => ({ toolCall, turnBlocks: message.blocks })),\n )\n}\n\nexport function toolCallAnswered(\n toolCall: ToolCallInfo,\n sessionStatus: string | undefined,\n answerData: AskUserAnswerData | undefined,\n) {\n if (formatToolName(toolCall.name) !== \"AskUserQuestion\") {\n return sessionStatus !== \"waiting_for_input\"\n }\n if (answerData) return true\n return !(\n toolCall.status === \"awaiting_answer\" ||\n (toolCall.status === \"done\" && sessionStatus === \"waiting_for_input\")\n )\n}\n","import { useCallback, useEffect, useRef } from \"react\"\n\nconst DEFAULT_MARGIN_PX = 24\nconst MANUAL_SCROLL_TOLERANCE_PX = 2\n\nexport interface UseMessagePinOptions {\n targetKey: string | null\n pinTarget: boolean\n /**\n * 省略时按旧行为处理(视为一直流式中,只靠 targetKey 变化释放)——\n * useMessagePin 是导出的公开 hook,加这个字段前如果直接改成必填,\n * 所有已经在调用这个 hook 的外部使用方都会编译不过。\n */\n isStreaming?: boolean\n layoutKey?: string\n getScrollElement: () => HTMLElement | null\n getContentElement?: () => HTMLElement | null\n getTargetElement: () => HTMLElement | null\n getTargetScrollTop?: (scroll: HTMLElement) => number | null\n getSpacerHeight: () => number\n setSpacerHeight: (height: number) => void\n stopAutoScroll: () => void\n scrollToBottom: () => void\n margin?: number\n}\n\n/**\n * 用户发言顶置的共享状态机。SDK 和内置轻量列表只提供 DOM/虚拟列表适配器,\n * 触发、调度、resize、手动接管和跟随交还的决策只在这里维护。\n */\nexport function useMessagePin({\n targetKey,\n pinTarget,\n isStreaming = true,\n layoutKey,\n getScrollElement,\n getContentElement,\n getTargetElement,\n getTargetScrollTop,\n getSpacerHeight,\n setSpacerHeight,\n stopAutoScroll,\n margin = DEFAULT_MARGIN_PX,\n}: UseMessagePinOptions) {\n const pinActiveRef = useRef(false)\n const frameRef = useRef<number | null>(null)\n const retryTimeoutRef = useRef<number | null>(null)\n const manualScrollCheckTimeoutRef = useRef<number | null>(null)\n const repositionPendingRef = useRef(false)\n const pinnedTargetScrollTopRef = useRef<number | null>(null)\n const appliedTargetKeyRef = useRef<string | null>(null)\n const initialObservedTargetKeyRef = useRef<string | null>(pinTarget ? null : targetKey)\n const observedTargetKeyRef = useRef<string | null>(initialObservedTargetKeyRef.current)\n const setSpacerHeightRef = useRef(setSpacerHeight)\n setSpacerHeightRef.current = setSpacerHeight\n\n const release = useCallback(() => {\n if (!pinActiveRef.current) return\n pinActiveRef.current = false\n repositionPendingRef.current = false\n pinnedTargetScrollTopRef.current = null\n if (frameRef.current != null) cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n if (manualScrollCheckTimeoutRef.current != null) {\n clearTimeout(manualScrollCheckTimeoutRef.current)\n manualScrollCheckTimeoutRef.current = null\n }\n setSpacerHeightRef.current(0)\n }, [])\n\n const reposition = useCallback(\n () => {\n const scroll = getScrollElement()\n const target = getTargetElement()\n if (!scroll || !pinActiveRef.current) return\n\n const targetScrollTop = target\n ? Math.max(\n 0,\n scroll.scrollTop +\n target.getBoundingClientRect().top -\n scroll.getBoundingClientRect().top -\n margin,\n )\n : getTargetScrollTop?.(scroll)\n if (targetScrollTop == null) return\n const previousSpacerHeight = getSpacerHeight()\n const baseScrollHeight = scroll.scrollHeight - previousSpacerHeight\n const nextSpacerHeight = Math.max(\n 0,\n targetScrollTop + scroll.clientHeight - baseScrollHeight + 1,\n )\n setSpacerHeightRef.current(nextSpacerHeight)\n pinnedTargetScrollTopRef.current = targetScrollTop\n\n stopAutoScroll()\n scroll.scrollTop = targetScrollTop\n if (nextSpacerHeight === 0 && previousSpacerHeight > 0) {\n pinActiveRef.current = false\n }\n },\n [\n getScrollElement,\n getSpacerHeight,\n getTargetElement,\n getTargetScrollTop,\n margin,\n stopAutoScroll,\n ],\n )\n\n const scheduleReposition = useCallback(\n () => {\n if (!pinActiveRef.current) return\n repositionPendingRef.current = true\n if (frameRef.current != null) return\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null\n const shouldReposition = repositionPendingRef.current\n repositionPendingRef.current = false\n if (shouldReposition) reposition()\n })\n },\n [reposition],\n )\n\n useEffect(() => {\n if (!targetKey) {\n release()\n appliedTargetKeyRef.current = null\n observedTargetKeyRef.current = null\n return\n }\n if (!pinTarget) {\n if (\n pinActiveRef.current &&\n appliedTargetKeyRef.current != null &&\n (appliedTargetKeyRef.current !== targetKey || !isStreaming)\n ) {\n release()\n }\n observedTargetKeyRef.current = targetKey\n return\n }\n if (appliedTargetKeyRef.current === targetKey) {\n observedTargetKeyRef.current = targetKey\n return\n }\n if (observedTargetKeyRef.current === targetKey) return\n\n appliedTargetKeyRef.current = targetKey\n observedTargetKeyRef.current = targetKey\n pinActiveRef.current = true\n stopAutoScroll()\n scheduleReposition()\n if (retryTimeoutRef.current != null) clearTimeout(retryTimeoutRef.current)\n retryTimeoutRef.current = window.setTimeout(() => {\n retryTimeoutRef.current = null\n scheduleReposition()\n }, 80)\n }, [isStreaming, pinTarget, release, scheduleReposition, stopAutoScroll, targetKey])\n\n useEffect(() => {\n if (layoutKey !== undefined) scheduleReposition()\n }, [layoutKey, scheduleReposition])\n\n useEffect(() => {\n const scroll = getScrollElement()\n if (!scroll) return\n const content = getContentElement?.()\n const observer = new ResizeObserver(scheduleReposition)\n observer.observe(scroll)\n if (content && content !== scroll) observer.observe(content)\n window.addEventListener(\"resize\", scheduleReposition)\n window.visualViewport?.addEventListener(\"resize\", scheduleReposition)\n\n const handleScroll = () => {\n if (!pinActiveRef.current) return\n if (manualScrollCheckTimeoutRef.current != null) {\n clearTimeout(manualScrollCheckTimeoutRef.current)\n }\n manualScrollCheckTimeoutRef.current = window.setTimeout(() => {\n manualScrollCheckTimeoutRef.current = null\n if (!pinActiveRef.current || repositionPendingRef.current) return\n const targetScrollTop = pinnedTargetScrollTopRef.current\n if (\n targetScrollTop != null &&\n Math.abs(scroll.scrollTop - targetScrollTop) > MANUAL_SCROLL_TOLERANCE_PX\n ) {\n release()\n }\n }, 0)\n }\n scroll.addEventListener(\"scroll\", handleScroll, { passive: true })\n return () => {\n observer.disconnect()\n window.removeEventListener(\"resize\", scheduleReposition)\n window.visualViewport?.removeEventListener(\"resize\", scheduleReposition)\n scroll.removeEventListener(\"scroll\", handleScroll)\n }\n }, [getContentElement, getScrollElement, release, scheduleReposition])\n\n useEffect(\n () => () => {\n if (frameRef.current != null) cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n if (retryTimeoutRef.current != null) clearTimeout(retryTimeoutRef.current)\n retryTimeoutRef.current = null\n if (manualScrollCheckTimeoutRef.current != null) {\n clearTimeout(manualScrollCheckTimeoutRef.current)\n }\n manualScrollCheckTimeoutRef.current = null\n repositionPendingRef.current = false\n pinnedTargetScrollTopRef.current = null\n appliedTargetKeyRef.current = null\n observedTargetKeyRef.current = initialObservedTargetKeyRef.current\n pinActiveRef.current = false\n setSpacerHeightRef.current(0)\n },\n [],\n )\n\n const isActive = useCallback(() => pinActiveRef.current, [])\n return { release, isActive }\n}\n","import { groupAdjacentContextRuns, isBackgroundWakeMessage } from \"@blade-hq/agent-client/internal\"\nimport { contentPreview, isHiddenInternalMessage } from \"@blade-hq/agent-client/internal\"\nimport type { ChatMessage } from \"@blade-hq/agent-client/internal\"\n\nexport const RECENT_RESIDENT_TURNS = 8\n\ntype RenderBlockBase = {\n key: string\n persistentId: string | null\n isStreaming: boolean\n}\n\nexport type AssistantTurnRenderBlock = RenderBlockBase & {\n type: \"assistant_turn\"\n messages: ChatMessage[]\n anchorId: string\n railTitle: string\n /**\n * 本轮对应的用户发言 entry_id。导航条以用户发言命名,跳转也应落在用户\n * 发言上而不是智能体回复上;只给紧跟用户发言的第一个回复块,同一发言\n * 后的第二个回复块(被压缩卡/规划分隔线切开)回退到自身锚点。\n */\n userEntryId: string | null\n}\n\nexport type RenderBlock =\n | (RenderBlockBase & {\n type: \"message\"\n message: ChatMessage\n anchorId: string | null\n })\n | AssistantTurnRenderBlock\n | (RenderBlockBase & { type: \"context_group\"; messages: ChatMessage[] })\n | (RenderBlockBase & { type: \"context_divider\" })\n | (RenderBlockBase & { type: \"compaction\"; message: ChatMessage })\n | (RenderBlockBase & {\n type: \"planning_divider\"\n kind: \"enter\" | \"exit\"\n message: ChatMessage\n })\n\nfunction parseModeChange(message: ChatMessage): { from: string; to: string } | null {\n if (message.kind !== \"mode_change\" || typeof message.content !== \"string\") {\n return null\n }\n try {\n const parsed = JSON.parse(message.content) as { from?: unknown; to?: unknown }\n if (typeof parsed.from === \"string\" && typeof parsed.to === \"string\") {\n return { from: parsed.from, to: parsed.to }\n }\n } catch {}\n return null\n}\n\nfunction getPlanningDividerKind(message: ChatMessage): \"enter\" | \"exit\" | null {\n const modeChange = parseModeChange(message)\n if (modeChange?.to === \"planning\") return \"enter\"\n if (modeChange?.from === \"planning\") return \"exit\"\n return null\n}\n\nfunction getMessagePreview(message: ChatMessage) {\n return contentPreview(message.content, 42)\n}\n\nfunction getAssistantTurnPreview(messages: ChatMessage[]) {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const preview = getMessagePreview(messages[index])\n if (preview) return preview\n }\n return \"本轮回复\"\n}\n\nexport function shouldAppendPendingAssistantTurn(\n sessionIsStreaming: boolean,\n lastMessage: ChatMessage | undefined,\n) {\n return sessionIsStreaming && lastMessage?.role === \"user\"\n}\n\nfunction hasAssistantReply(block: RenderBlock | undefined) {\n return block?.type === \"assistant_turn\" && block.messages.some((message) => {\n if (typeof message.content === \"string\") return message.content.trim().length > 0\n return message.content != null\n })\n}\n\n/** 从同一份消息序列生成唯一的渲染计划,流式和历史加载都复用它。 */\nexport function buildMessageListBlocks({\n messages,\n agentLoopNames,\n sessionIsStreaming,\n showContexts = true,\n}: {\n messages: ChatMessage[]\n agentLoopNames: ReadonlySet<string>\n sessionIsStreaming: boolean\n showContexts?: boolean\n}): RenderBlock[] {\n const visible = messages.filter((message) => {\n const loopName = message.loop_name ?? \"root\"\n if (loopName !== \"root\") return false\n if (agentLoopNames.has(loopName)) return false\n if (isHiddenInternalMessage(message) && !isBackgroundWakeMessage(message)) return false\n if (message.kind === \"context\") return showContexts && Boolean(message.context)\n if (message.kind === \"compaction\") return true\n return message.role !== \"tool\" || getPlanningDividerKind(message) !== null\n })\n\n\n const blocks: RenderBlock[] = []\n let contextBuffer: ChatMessage[] = []\n let assistantBuffer: ChatMessage[] = []\n let assistantTurnCount = 0\n let lastUserPreview = \"\"\n let pendingUserEntryId: string | null = null\n\n const flushAssistant = () => {\n if (assistantBuffer.length === 0) return\n\n assistantTurnCount += 1\n const messagesInTurn = assistantBuffer\n const first = messagesInTurn[0]\n const persistentId = first.entry_id ?? null\n const isStreaming = messagesInTurn.some((message) => message.status === \"streaming\")\n blocks.push({\n type: \"assistant_turn\",\n messages: messagesInTurn,\n key: persistentId ?? `assistant-${assistantTurnCount}`,\n persistentId,\n anchorId: `chat-turn-${assistantTurnCount}`,\n isStreaming,\n railTitle: lastUserPreview || getAssistantTurnPreview(messagesInTurn),\n userEntryId: pendingUserEntryId,\n })\n pendingUserEntryId = null\n assistantBuffer = []\n }\n\n // 一批上下文注入折叠成一行。会话首轮会一次注入十几个原子,逐条一行会把\n // 真正的对话挤出屏幕。\n //\n // 相邻判定用 agent-client 的 groupAdjacentContextRuns,和调试日志、SDK 卡片\n // 共用同一份;这里只按它给的分组落块。**不要**在这里另写一套相邻判定,\n // 否则以后改边界规则时两边会静默分叉。\n //\n // 只产出 context_group 一种块,单条也不例外:流式时第二条到达会让同一个 key\n // 的行从单条卡片变成分组卡片,React 看到组件类型变了就重挂 <details>,\n // 用户刚展开的行会被收起来。\n const flushContexts = () => {\n if (contextBuffer.length === 0) return\n const messagesInGroup = contextBuffer\n contextBuffer = []\n if (hasAssistantReply(blocks.at(-1))) {\n blocks.push({\n type: \"context_divider\",\n key: `context-divider-${messagesInGroup[0].entry_id ?? blocks.length}`,\n persistentId: null,\n isStreaming: false,\n })\n }\n const persistentId = messagesInGroup[0].entry_id ?? null\n blocks.push({\n type: \"context_group\",\n messages: messagesInGroup,\n key: persistentId ?? `context-group-${blocks.length}`,\n persistentId,\n isStreaming: false,\n })\n }\n\n const contextRunStarts = new Set(\n groupAdjacentContextRuns(\n visible.map((message) =>\n message.kind === \"context\" && message.context ? message.context.context_kind : null,\n ),\n ).map((run) => run[0]),\n )\n\n for (let visibleIndex = 0; visibleIndex < visible.length; visibleIndex += 1) {\n const message = visible[visibleIndex]\n if (contextRunStarts.has(visibleIndex) || message.kind !== \"context\") {\n flushContexts()\n }\n const dividerKind = getPlanningDividerKind(message)\n if (dividerKind) {\n flushAssistant()\n const persistentId = message.entry_id ?? null\n blocks.push({\n type: \"planning_divider\",\n kind: dividerKind,\n message,\n key: persistentId ?? `${dividerKind}-${blocks.length}`,\n persistentId,\n isStreaming: message.status === \"streaming\",\n })\n continue\n }\n\n if (message.kind === \"compaction\") {\n flushAssistant()\n const persistentId = message.entry_id ?? null\n blocks.push({\n type: \"compaction\",\n message,\n key: persistentId ?? `compaction-${blocks.length}`,\n persistentId,\n isStreaming: message.status === \"streaming\",\n })\n continue\n }\n\n if (message.kind === \"context\" && message.context) {\n flushAssistant()\n contextBuffer.push(message)\n continue\n }\n\n if (message.role === \"assistant\") {\n assistantBuffer.push(message)\n continue\n }\n\n flushAssistant()\n const persistentId = message.entry_id ?? null\n if (message.role === \"user\" && !isHiddenInternalMessage(message)) {\n lastUserPreview = getMessagePreview(message)\n pendingUserEntryId = persistentId\n }\n blocks.push({\n type: \"message\",\n message,\n key: message.render_id ?? persistentId ?? `${message.role}-${blocks.length}`,\n persistentId,\n anchorId: persistentId ? `chat-entry-${persistentId}` : null,\n isStreaming: message.status === \"streaming\",\n })\n }\n\n flushAssistant()\n flushContexts()\n\n if (sessionIsStreaming) {\n const last = blocks[blocks.length - 1]\n if (last?.type === \"assistant_turn\") {\n last.isStreaming = true\n } else if (\n shouldAppendPendingAssistantTurn(\n sessionIsStreaming,\n last?.type === \"message\" ? last.message : undefined,\n )\n ) {\n assistantTurnCount += 1\n const pendingKey = `pending-assistant-${last.key}`\n blocks.push({\n type: \"assistant_turn\",\n messages: [\n {\n role: \"assistant\",\n content: \"\",\n entry_id: pendingKey,\n status: \"streaming\",\n loop_name: \"root\",\n },\n ],\n key: pendingKey,\n persistentId: null,\n anchorId: `chat-turn-${assistantTurnCount}`,\n isStreaming: true,\n railTitle: lastUserPreview || \"本轮回复\",\n userEntryId: pendingUserEntryId,\n })\n }\n }\n\n return blocks\n}\n\nexport function getRenderBlockPersistentId(block: RenderBlock) {\n return block.persistentId\n}\n\n/**\n * 完整 turn 从上一个 assistant turn 之后开始,到当前已完成 assistant turn 结束。\n * 返回最近 N 个完整 turn 的起点;更靠后的流式/pending 内容自然落入常驻尾部。\n */\nexport function startIndexOfLastNCompleteTurns(blocks: RenderBlock[], count: number) {\n if (count <= 0) return blocks.length\n const completedAssistantIndexes = blocks.flatMap((block, index) =>\n block.type === \"assistant_turn\" && !block.isStreaming ? [index] : [],\n )\n if (completedAssistantIndexes.length <= count) return 0\n\n const firstRecentAssistantIndex =\n completedAssistantIndexes[completedAssistantIndexes.length - count]\n let previousAssistantIndex = -1\n for (let index = 0; index < firstRecentAssistantIndex; index += 1) {\n if (blocks[index].type === \"assistant_turn\") previousAssistantIndex = index\n }\n return previousAssistantIndex + 1\n}\n\nexport function findStablePrefixEnd(\n blocks: RenderBlock[],\n recentResidentTurns = RECENT_RESIDENT_TURNS,\n) {\n const recentStart = startIndexOfLastNCompleteTurns(blocks, recentResidentTurns)\n for (let index = 0; index < recentStart; index += 1) {\n const block = blocks[index]\n if (getRenderBlockPersistentId(block) === null || block.isStreaming) return index\n }\n return recentStart\n}\n\n/**\n * 目录刷新信号:窗口里**最后一条**用户发言的稳定 entry id。\n *\n * 与 SDK 的 `latestUserSpeechEntryId`(agent-react 的 use-turn-navigation.ts)同一\n * 判据、同一名称,输入不同:那边拿投影轮,这边拿渲染好的消息。两边都只认\"最新\n * 一条\",因为往前翻页补进的更早发言不改变目录的结尾,用\"窗口里全部发言\"当信号\n * 会把正在进行的定位判成过期。\n *\n * AskUserQuestion 的回答在列表里也渲染成用户发言(entry id 就是它自己),所以算一条。\n */\nexport function latestUserSpeechEntryId(messages: ChatMessage[]): string | null {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index]\n if ((message.loop_name ?? \"root\") !== \"root\") continue\n if (message.role === \"user\") return message.entry_id ?? null\n }\n return null\n}\n\nexport function buildMessageListBlockIndexes(blocks: RenderBlock[]) {\n const entryIdToBlockIndex = new Map<string, number>()\n const turnIdToBlockIndex = new Map<string, number>()\n\n blocks.forEach((block, blockIndex) => {\n if (block.type === \"assistant_turn\") {\n turnIdToBlockIndex.set(block.anchorId, blockIndex)\n for (const message of block.messages) {\n if (message.entry_id) entryIdToBlockIndex.set(message.entry_id, blockIndex)\n }\n return\n }\n if (block.persistentId) entryIdToBlockIndex.set(block.persistentId, blockIndex)\n })\n\n return { entryIdToBlockIndex, turnIdToBlockIndex }\n}\n\nexport type VisibleTurnRect = {\n turnId: string\n top: number\n bottom: number\n}\n\nconst ACTIVE_TURN_SWITCH_MARGIN_PX = 32\n\n/** 判定“已滚到底”的容差:浏览器 scrollTop 按物理像素取整会留 1-2px 残差。 */\nexport const NAV_AT_BOTTOM_EPSILON_PX = 4\n\n/** 按原有 viewport 15% 位置语义,从已相交的 turn 中选择导航高亮项。 */\nexport function selectActiveTurnAtViewportPosition({\n visibleTurns,\n containerTop,\n containerBottom,\n fallbackTurnId,\n currentTurnId = null,\n atBottom = false,\n}: {\n visibleTurns: Iterable<VisibleTurnRect>\n containerTop: number\n containerBottom: number\n fallbackTurnId: string | null\n currentTurnId?: string | null\n atBottom?: boolean\n}) {\n if (atBottom && fallbackTurnId != null) return fallbackTurnId\n const targetY = containerTop + (containerBottom - containerTop) * 0.15\n let bestId: string | null = null\n let bestDistance = Number.POSITIVE_INFINITY\n let currentDistance = Number.POSITIVE_INFINITY\n for (const turn of visibleTurns) {\n if (turn.bottom < containerTop || turn.top > containerBottom) continue\n const distance = Math.abs(turn.top - targetY)\n if (turn.turnId === currentTurnId) currentDistance = distance\n if (distance < bestDistance) {\n bestDistance = distance\n bestId = turn.turnId\n }\n }\n if (bestId == null) return currentTurnId ?? fallbackTurnId\n if (\n currentTurnId != null &&\n currentDistance !== Number.POSITIVE_INFINITY &&\n bestDistance > currentDistance - ACTIVE_TURN_SWITCH_MARGIN_PX\n ) {\n return currentTurnId\n }\n return bestId\n}\n\n/** 测试双通道最终渲染计划时忽略仅影响布局的 wrapper。 */\nexport function snapshotMessageListRenderPlan(blocks: RenderBlock[]) {\n return blocks.map((block, globalIndex) => ({\n type: block.type,\n persistentId: block.persistentId,\n globalIndex,\n messages:\n block.type === \"assistant_turn\" || block.type === \"context_group\"\n ? block.messages\n : block.type === \"context_divider\"\n ? []\n : [block.message],\n isStreaming: block.isStreaming,\n }))\n}\n","import {\n getContextDisplayState,\n getContextGroupDisplayState,\n type ContextProjectionData,\n} from \"@blade-hq/agent-client/internal\"\nimport { ChevronDown, Layers3 } from \"lucide-react\"\n\nexport interface ContextCardProps {\n context: ContextProjectionData\n className?: string\n}\n\n/** Business-facing Context summary. Native details keeps every card collapsed by default. */\nexport function ContextCard({ context, className }: ContextCardProps) {\n const display = getContextDisplayState(context)\n return (\n <details\n className={`blade-chat-context-card group/context-card overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? \"\"}`}\n >\n <summary className=\"blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden\">\n <Layers3\n size={15}\n className=\"blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]\"\n aria-hidden=\"true\"\n />\n <span className=\"blade-chat-context-copy min-w-0 flex-1\">\n <span className=\"blade-chat-context-title block font-medium text-[hsl(var(--foreground))]\">\n {display.title}\n </span>\n <span className=\"blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]\">\n {display.summary}\n </span>\n </span>\n <ChevronDown\n size={14}\n className=\"blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform duration-[180ms] ease-[cubic-bezier(0.25,0.1,0.25,1)] group-open/context-card:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div className=\"blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]\">\n {display.detail}\n </div>\n </details>\n )\n}\n\nexport interface ContextGroupCardProps {\n contexts: readonly ContextProjectionData[]\n className?: string\n}\n\n/**\n * 一批上下文注入折叠成一行。会话首轮会一次注入十几个原子,一条一张卡片会把\n * 真正的对话挤出屏幕。\n *\n * 单条和多条**共用同一个 details 外壳**,不在数量变化时切换组件:流式时第二条\n * 到达会让这一行从单条变成多条,组件类型一换 React 就重挂 <details>,\n * 用户刚展开的行会被收起来。同理,key 由调用方按组内第一条给,不能带数量。\n */\nexport function ContextGroupCard({ contexts, className }: ContextGroupCardProps) {\n if (contexts.length === 0) return null\n const single = contexts.length === 1 ? getContextDisplayState(contexts[0]) : null\n const group = single ? null : getContextGroupDisplayState(contexts)\n return (\n <details className={`blade-chat-context-card group/context-group overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? \"\"}`}>\n <summary className=\"blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden\">\n <Layers3\n size={15}\n className=\"blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]\"\n aria-hidden=\"true\"\n />\n <span className=\"blade-chat-context-copy min-w-0 flex-1\">\n <span className=\"blade-chat-context-title block font-medium text-[hsl(var(--foreground))]\">\n {single ? single.title : `${group?.title} · ${group?.count} 项`}\n </span>\n <span className=\"blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]\">\n {single ? single.summary : group?.summary}\n </span>\n </span>\n <ChevronDown\n size={14}\n className=\"blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform duration-[180ms] ease-[cubic-bezier(0.25,0.1,0.25,1)] group-open/context-group:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n {single ? (\n <div className=\"blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]\">\n {single.detail}\n </div>\n ) : (\n <div className=\"blade-chat-context-group-items flex flex-col gap-1.5 border-t border-[hsl(var(--border))] p-2\">\n {contexts.map((context) => (\n <ContextCard\n key={`${context.context_kind}:${context.context_key}`}\n context={context}\n />\n ))}\n </div>\n )}\n </details>\n )\n}\n","import type {\n PostChatFollowup,\n ResultFeedback as SavedResultFeedback,\n ResultFeedbackReason,\n} from \"@blade-hq/agent-client/internal\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useBladeClient } from \"../context\"\nimport { useFollowupInteraction } from \"./followup-interaction\"\n\nconst REASONS: Array<{ value: ResultFeedbackReason; label: string }> = [\n { value: \"not_solved\", label: \"没解决问题\" },\n { value: \"inaccurate\", label: \"内容不准确\" },\n { value: \"incomplete\", label: \"内容不完整\" },\n { value: \"needs_major_changes\", label: \"需要大量修改\" },\n { value: \"too_slow\", label: \"太慢\" },\n { value: \"other\", label: \"其他\" },\n]\n\nfunction reasonLabel(reason: ResultFeedbackReason | null): string | null {\n return REASONS.find((item) => item.value === reason)?.label ?? null\n}\n\nexport function HistoricalResultFeedback({ feedback }: { feedback: SavedResultFeedback }) {\n const label = reasonLabel(feedback.reason)\n return (\n <section\n aria-label=\"历史结果反馈\"\n className=\"w-fit max-w-full rounded-lg border border-[hsl(var(--border)/0.7)] bg-[hsl(var(--muted)/0.2)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\"\n >\n <span>你对此轮结果的评价:{feedback.helpful ? \"有帮助\" : \"没帮助\"}</span>\n {label ? <span> · {label}</span> : null}\n </section>\n )\n}\n\nexport function ResultFeedback({\n sessionId,\n followup,\n isViewer,\n savedFeedback,\n onSaved,\n}: {\n sessionId: string\n followup: PostChatFollowup\n isViewer: boolean\n savedFeedback?: SavedResultFeedback\n onSaved?: (feedback: SavedResultFeedback) => void\n}) {\n const client = useBladeClient()\n const [saved, setSaved] = useState<SavedResultFeedback | null>(savedFeedback ?? null)\n const [selectedHelpful, setSelectedHelpful] = useState<boolean | null>(\n savedFeedback?.helpful ?? null,\n )\n const [selectedReason, setSelectedReason] = useState<ResultFeedbackReason | null>(\n savedFeedback?.reason ?? null,\n )\n const [saving, setSaving] = useState(false)\n const [saveError, setSaveError] = useState(false)\n const latestChoice = useRef<{\n helpful: boolean\n reason: ResultFeedbackReason | null\n } | null>(null)\n const eligible = followup.feedback_eligible === true\n const emit = useFollowupInteraction()\n const reportedShown = useRef(false)\n const visible = eligible && !isViewer\n\n useEffect(() => {\n if (!visible || reportedShown.current) return\n reportedShown.current = true\n emit({ type: \"result_feedback_shown\", sessionId, assistantEntryId: followup.assistant_entry_id })\n }, [emit, followup.assistant_entry_id, sessionId, visible])\n\n useEffect(() => {\n if (!savedFeedback || latestChoice.current) return\n setSaved(savedFeedback)\n setSelectedHelpful(savedFeedback.helpful)\n setSelectedReason(savedFeedback.reason)\n }, [savedFeedback])\n\n const submit = useCallback(\n async (helpful: boolean, reason: ResultFeedbackReason | null) => {\n const choice = { helpful, reason }\n latestChoice.current = choice\n setSelectedHelpful(helpful)\n setSelectedReason(reason)\n setSaving(true)\n setSaveError(false)\n try {\n const result = await client.sessions.putResultFeedback(\n sessionId,\n followup.assistant_entry_id,\n { helpful, reason },\n )\n if (latestChoice.current !== choice) return\n setSaved(result)\n onSaved?.(result)\n emit({\n type: \"result_feedback_submitted\",\n sessionId,\n assistantEntryId: followup.assistant_entry_id,\n helpful: result.helpful,\n reason: result.reason,\n updatedAt: result.updated_at,\n })\n } catch {\n if (latestChoice.current === choice) setSaveError(true)\n } finally {\n if (latestChoice.current === choice) setSaving(false)\n }\n },\n [client, emit, followup.assistant_entry_id, onSaved, sessionId],\n )\n\n if (!visible) return null\n\n return (\n <section\n aria-label=\"结果反馈\"\n className=\"flex flex-col gap-2 border-t border-[hsl(var(--border)/0.7)] pt-3\"\n >\n <div className=\"text-xs font-medium text-[hsl(var(--muted-foreground))]\">\n 目前的整体结果有帮助吗?\n </div>\n <div className=\"flex flex-wrap gap-1.5\">\n <button\n type=\"button\"\n aria-pressed={selectedHelpful === true}\n disabled={saving}\n onClick={() => void submit(true, null)}\n className=\"rounded-lg border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs aria-pressed:border-[hsl(var(--primary)/0.55)] aria-pressed:bg-[hsl(var(--primary)/0.1)] disabled:opacity-60\"\n >\n 有帮助\n </button>\n <button\n type=\"button\"\n aria-pressed={selectedHelpful === false}\n disabled={saving}\n onClick={() => void submit(false, selectedReason)}\n className=\"rounded-lg border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs aria-pressed:border-[hsl(var(--primary)/0.55)] aria-pressed:bg-[hsl(var(--primary)/0.1)] disabled:opacity-60\"\n >\n 没帮助\n </button>\n </div>\n {selectedHelpful === false ? (\n <div className=\"flex max-w-[520px] flex-wrap gap-1.5\" aria-label=\"没帮助的主要原因\">\n {REASONS.map((reason) => (\n <button\n key={reason.value}\n type=\"button\"\n aria-pressed={selectedReason === reason.value}\n disabled={saving}\n onClick={() => void submit(false, reason.value)}\n className=\"rounded-full bg-[hsl(var(--muted)/0.62)] px-2.5 py-1 text-[11px] aria-pressed:bg-[hsl(var(--primary)/0.14)] aria-pressed:text-[hsl(var(--primary))] disabled:opacity-60\"\n >\n {reason.label}\n </button>\n ))}\n </div>\n ) : null}\n {saveError ? (\n <div className=\"flex items-center gap-2 text-xs text-[hsl(var(--destructive))]\">\n <span>反馈暂未保存,可重试</span>\n <button\n type=\"button\"\n className=\"underline underline-offset-2\"\n onClick={() => {\n const choice = latestChoice.current\n if (choice) void submit(choice.helpful, choice.reason)\n }}\n >\n 重试\n </button>\n </div>\n ) : saved ? (\n <div className=\"text-[11px] text-[hsl(var(--muted-foreground))]\">已保存,可随时修改</div>\n ) : null}\n </section>\n )\n}\n","import { ChatLoadingIndicator, isPreparingReply } from \"./ChatLoadingIndicator\"\nimport { isBackgroundWakeMessage } from \"@blade-hq/agent-client/internal\"\nimport { ChevronDown, Lightbulb, MessageSquare } from \"lucide-react\"\nimport { useEffectEvent } from \"../lib/use-effect-event\"\nimport { cn } from \"../lib/utils\"\nimport { type ChatVirtualItem as VirtualItem, useChatEnvironment, useChatVirtualizer } from \"./runtime/environment\"\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from \"react\"\nimport {\n StickToBottom,\n type GetTargetScrollTop,\n type StickToBottomContext,\n useStickToBottomContext,\n} from \"use-stick-to-bottom\"\nimport type { ChatMessage } from \"@blade-hq/agent-client/internal\"\nimport type { PostChatFollowup } from \"@blade-hq/agent-client/internal\"\nimport type { ResultFeedback } from \"@blade-hq/agent-client/internal\"\nimport { BackgroundWakeNotice } from \"../components/BackgroundWakeNotice\"\nimport { turnNavItemsFromMessages, useTurnNavigation } from \"../hooks/use-turn-navigation\"\nimport { useTypewriterReveal } from \"../hooks/use-typewriter-reveal\"\nimport { CurrentChatSessionProvider, useSessionHandle, useSessionState } from \"./runtime/session-source\"\nimport { PlanSummaryCard } from \"./plan/PlanSummaryCard\"\nimport { extractPlanMessagesForTurn } from \"./plan/extract-plan-messages\"\nimport type { AskUserAnswerData } from \"./AskUserQuestionBlock\"\nimport { AssistantTurnBlock } from \"./AssistantTurnBlock\"\nimport { ContextGroupCard } from \"../components/ContextCard\"\nimport { PostChatFollowupBlock } from \"./PostChatFollowupBlock\"\nimport { HistoricalResultFeedback } from \"./ResultFeedback\"\nimport { RenderErrorBoundary } from \"./RenderErrorBoundary\"\nimport { TurnNavRail, type TurnNavItem } from \"./TurnNavRail\"\nimport {\n ErrorMessageBlock,\n UserMessageBubble,\n isErrorMessage,\n isUserMessage,\n} from \"./UserMessageBubble\"\nimport { formatToolName } from \"./display-utils\"\nimport type { ChatViewCustomization } from \"./customization\"\nimport {\n MANUAL_SCROLL_TOLERANCE_PX,\n NEW_TURN_SCROLL_DURATION_MS,\n calculateAnchoredScrollTop,\n calculateAnimatedScrollTop,\n calculateStickyAwareMargin,\n calculateTrailingSpacerHeight,\n normalizeScrollEntryKey,\n shouldAnimateNewTurnScroll,\n} from \"./scroll-anchor\"\nimport {\n type AssistantTurnRenderBlock,\n NAV_AT_BOTTOM_EPSILON_PX,\n type RenderBlock,\n buildMessageListBlockIndexes,\n buildMessageListBlocks,\n findStablePrefixEnd,\n getRenderBlockPersistentId,\n latestUserSpeechEntryId,\n selectActiveTurnAtViewportPosition,\n} from \"./message-list-blocks\"\n\nexport { shouldAppendPendingAssistantTurn } from \"./message-list-blocks\"\n\nexport function isReasoningRevealingForMessage(\n message: ChatMessage | undefined,\n isRevealing: boolean,\n isStopping = false,\n): boolean {\n if (isStopping) return false\n const hasContent = message?.content != null && message.content.length > 0\n return isRevealing || Boolean(message?.reasoning && !hasContent && !message.tool_calls?.length)\n}\n\nfunction getMessageMeasureSignature(message: ChatMessage) {\n const contentSize =\n typeof message.content === \"string\"\n ? message.content.length\n : message.content.length\n\n return [\n message.entry_id ?? message.timestamp ?? message.role,\n message.status ?? \"\",\n message.reasoning ? 1 : 0,\n message.tool_calls?.length ?? 0,\n message.blocks?.length ?? 0,\n contentSize,\n ].join(\":\")\n}\n\nfunction getMessagesMeasureSignature(messages: ChatMessage[]) {\n return messages.map((message) => getMessageMeasureSignature(message)).join(\"|\")\n}\n\nfunction getMessageResetSignature(message: ChatMessage) {\n const contentSize = typeof message.content === \"string\" ? message.content.length : message.content.length\n const toolSignature =\n message.tool_calls\n ?.map((toolCall) => `${toolCall.id}:${toolCall.status}:${toolCall.result == null ? 0 : 1}`)\n .join(\",\") ?? \"\"\n return [\n message.entry_id ?? message.timestamp ?? message.role,\n message.status ?? \"\",\n contentSize,\n message.reasoning?.length ?? 0,\n message.blocks?.length ?? 0,\n message.memory_refs?.length ?? 0,\n toolSignature,\n ].join(\":\")\n}\n\nfunction getMessagesResetSignature(messages: ChatMessage[]) {\n return messages.map((message) => getMessageResetSignature(message)).join(\"|\")\n}\n\nfunction estimateRenderBlockSize(block: RenderBlock) {\n if (block.type === \"assistant_turn\") return 320\n if (block.type === \"context_group\") return 72\n if (block.type === \"context_divider\") return 20\n if (block.type === \"compaction\") return 96\n if (block.type === \"planning_divider\") return 64\n return 120\n}\n\nfunction findScrollContainer(start: HTMLElement | null) {\n let current = start\n while (current) {\n const overflowY = getComputedStyle(current).overflowY\n if (overflowY === \"auto\" || overflowY === \"scroll\") {\n return current\n }\n current = current.parentElement\n }\n return null\n}\n\nfunction prefersReducedMotion() {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return false\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n}\n\nfunction findEntryAnchor(root: HTMLElement, entryId: string) {\n return Array.from(root.querySelectorAll<HTMLElement>(\"[data-entry-id]\")).find(\n (el) => el.dataset.entryId === entryId,\n ) ?? null\n}\n\nexport interface MessageListProps {\n sessionId: string\n messages: ChatMessage[]\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n sessionStatus?: string\n onConfirmPlan?: (action: \"execute\" | \"revise\", text?: string) => void\n customization?: ChatViewCustomization\n scrollToStartKey?: string | null\n scrollToEntryKey?: string | null\n postChatFollowup?: PostChatFollowup | null\n resultFeedbackByEntry?: ReadonlyMap<string, ResultFeedback>\n onResultFeedbackSaved?: (feedback: ResultFeedback) => void\n isViewer?: boolean\n /** 历史消息还在加载中(大会话要等几秒)。 */\n isLoadingHistory?: boolean\n onLoadOlder?: (beforeCommit?: () => void) => Promise<boolean>\n historyLoadRevision?: number\n /** 外部改写 timeline(rewind / checkout / 修复重载)的次数:导航目录据此作废。 */\n historyRewriteRevision?: number\n /**\n * 用户点了停止(还没等服务端确认)——打字机式显示节流要在这一刻立刻整段\n * 显示已到达内容,不能等 chat:stop 的服务端回包才响应。跟 sessionIsStreaming\n * 翻转成 false 不是一回事:那个信号来得晚,点击到服务端确认之间有一段\n * 网络往返,这段时间里节流动画不该继续播。\n */\n isStopping?: boolean\n /**\n * 打字机式显示节流是否还没追平目标全文——调用方需要跟 isStreaming 做\n * `||` 判断输入框\"运行中\"状态,否则输入框会先于文字播完就翻回可输入。\n */\n onRevealingChange?: (revealing: boolean) => void\n /**\n * 是否正在回放(演示 / 彩排)而非真正的实时直播——回放期间即使内容在\n * 增长也不进入打字机式节流,直接整段显示:这是\"流式与历史必须产生相同\n * 结果\"这条硬规则的一部分,节流只在真正的实时直播里生效。\n */\n isReplay?: boolean\n /** 无消息时的空状态;不传时用默认的「开始对话」。 */\n emptyState?: ReactNode\n /** 是否正在生成;不传时读会话状态(纯 LLM 模式没有会话,由调用方给)。 */\n isStreaming?: boolean\n}\n\nfunction MessageListBody({\n sessionId,\n messages: rawMessages,\n onAnswer,\n sessionStatus,\n onConfirmPlan,\n customization,\n scrollToStartKey,\n scrollToEntryKey,\n postChatFollowup = null,\n resultFeedbackByEntry = new Map(),\n onResultFeedbackSaved,\n isViewer = false,\n isLoadingHistory = false,\n onLoadOlder,\n historyLoadRevision = 0,\n historyRewriteRevision = 0,\n isStopping = false,\n onRevealingChange,\n isReplay = false,\n emptyState,\n isStreaming: streamingOverride,\n}: MessageListProps) {\n const messages = Array.isArray(rawMessages) ? rawMessages : []\n const session = useSessionHandle(sessionId)\n const agentLoops = useSessionState(sessionId, (state) => state.agentLoops)\n const askAnswers = useSessionState(sessionId, (state) => state.askAnswers)\n const stateIsStreaming = useSessionState(sessionId, (state) => state.isStreaming)\n const sessionIsStreaming = streamingOverride ?? stateIsStreaming\n const isPreparing = sessionIsStreaming && isPreparingReply(messages)\n const agentLoopNameSet = useMemo(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops])\n const assistantMessagesCacheRef = useRef(new Map<string, ChatMessage[]>())\n const stickContextRef = useRef<StickToBottomContext | null>(null)\n\n const latestAssistantIndex = (() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const candidate = messages[i]\n if (candidate.role === \"assistant\" && (candidate.loop_name ?? \"root\") === \"root\") return i\n }\n return -1\n })()\n const latestAssistantMessage = latestAssistantIndex >= 0 ? messages[latestAssistantIndex] : undefined\n const revealTargetKey =\n latestAssistantMessage != null\n ? (latestAssistantMessage.entry_id ??\n latestAssistantMessage.render_id ??\n `assistant-index-${latestAssistantIndex}`)\n : null\n const revealContentText =\n typeof latestAssistantMessage?.content === \"string\" ? latestAssistantMessage.content : \"\"\n const revealReasoningText = latestAssistantMessage?.reasoning ?? \"\"\n const isRevealLive = latestAssistantMessage != null && !isReplay\n const contentReveal = useTypewriterReveal(revealContentText, isRevealLive, revealTargetKey)\n const reasoningReveal = useTypewriterReveal(revealReasoningText, isRevealLive, revealTargetKey)\n const isReasoningRevealing = isReasoningRevealingForMessage(\n latestAssistantMessage,\n reasoningReveal.isRevealing,\n isStopping,\n )\n const isRevealingAny = contentReveal.isRevealing || reasoningReveal.isRevealing\n\n useEffect(() => {\n onRevealingChange?.(isRevealingAny)\n }, [isRevealingAny, onRevealingChange])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: flushNow 引用稳定(useCallback 空依赖),只在 isStopping 变化时触发即可。\n useEffect(() => {\n if (isStopping) {\n contentReveal.flushNow()\n reasoningReveal.flushNow()\n }\n }, [isStopping])\n\n const renderBlocks = useMemo(() => {\n const blocks = buildMessageListBlocks({\n messages: messages.filter((message) => message.kind !== \"compaction\"),\n agentLoopNames: agentLoopNameSet,\n sessionIsStreaming: sessionIsStreaming || isRevealingAny,\n showContexts: false,\n })\n for (const block of blocks) {\n if (block.type !== \"assistant_turn\") continue\n const previous = assistantMessagesCacheRef.current.get(block.key)\n if (\n previous &&\n previous.length === block.messages.length &&\n previous.every((message, index) => message === block.messages[index])\n ) {\n block.messages = previous\n } else {\n assistantMessagesCacheRef.current.set(block.key, block.messages)\n }\n }\n\n const activeAssistantKeys = new Set(\n blocks\n .filter((block): block is AssistantTurnRenderBlock => block.type === \"assistant_turn\")\n .map((block) => block.key),\n )\n for (const key of assistantMessagesCacheRef.current.keys()) {\n if (!activeAssistantKeys.has(key)) {\n assistantMessagesCacheRef.current.delete(key)\n }\n }\n\n return blocks\n }, [agentLoopNameSet, messages, sessionIsStreaming, isRevealingAny])\n\n const hasInterruptedTurn = useMemo(\n () =>\n renderBlocks.some(\n (block) =>\n block.type === \"assistant_turn\" &&\n block.messages.some((message) => message.status === \"interrupted\"),\n ),\n [renderBlocks],\n )\n\n const lastTurnId = useMemo(() => {\n for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {\n const block = renderBlocks[index]\n if (block.type === \"assistant_turn\") return block.anchorId\n if (block.type === \"message\" && isUserMessage(block.message)) return null\n }\n return null\n }, [renderBlocks])\n\n const isSharedSession = sessionId.startsWith(\"share:\")\n const sharedNavItems = useMemo<TurnNavItem[]>(\n () => (isSharedSession ? turnNavItemsFromMessages(messages) : []),\n [isSharedSession, messages],\n )\n\n const stickyTurn = useMemo(\n () =>\n renderBlocks.find(\n (block): block is AssistantTurnRenderBlock =>\n block.type === \"assistant_turn\" &&\n block.anchorId === lastTurnId &&\n block.isStreaming,\n ) ?? null,\n [lastTurnId, renderBlocks],\n )\n const stickyTurnAnchorId = stickyTurn?.anchorId ?? null\n const scrollEntryId = useMemo(() => normalizeScrollEntryKey(scrollToEntryKey), [scrollToEntryKey])\n const shouldAnchorEntry = Boolean(scrollEntryId)\n const hasMessages = messages.length > 0\n const latestUserBlock = useMemo(() => {\n for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {\n const block = renderBlocks[index]\n if (block.type === \"message\" && isUserMessage(block.message)) {\n return block\n }\n }\n return null\n }, [renderBlocks])\n const latestUserAnchorId = latestUserBlock?.anchorId ?? null\n const latestUserStableId = latestUserBlock?.message.render_id ?? latestUserAnchorId\n const latestUserIsOptimistic = latestUserBlock?.message.entry_id?.startsWith(\"local-user-\") ?? false\n const effectiveNewUserMessageKey = latestUserIsOptimistic\n ? latestUserBlock?.key ?? latestUserAnchorId\n : null\n\n const containerRef = useRef<HTMLDivElement>(null)\n const scrollContainerRef = useRef<HTMLElement | null>(null)\n const virtualPrefixRef = useRef<HTMLDivElement>(null)\n const visibleTurnsRef = useRef(new Map<string, HTMLElement>())\n const visibleBlockRowsRef = useRef(new Map<string, HTMLElement>())\n const mountedTurnElementsRef = useRef(new Map<string, HTMLElement>())\n const turnRefCallbacksRef = useRef(\n new Map<string, (element: HTMLDivElement | null) => void>(),\n )\n const intersectionObserverRef = useRef<IntersectionObserver | null>(null)\n const measuredSizeByKeyRef = useRef(new Map<string, number>())\n const measuredRowElementsRef = useRef(new Map<string, HTMLElement>())\n const rowRefCallbacksRef = useRef(\n new Map<string, (element: HTMLDivElement | null) => void>(),\n )\n const rowResizeObserverRef = useRef<ResizeObserver | null>(null)\n const boundaryAnchorRef = useRef<{\n persistentId: string\n globalBlockIndex: number\n viewportOffset: number\n } | null>(null)\n const previousStablePrefixEndRef = useRef<number | null>(null)\n const frameRef = useRef<number | null>(null)\n const startScrollFrameRef = useRef<number | null>(null)\n const startScrollTimeoutRef = useRef<number | null>(null)\n const entryScrollFrameRef = useRef<number | null>(null)\n const entryScrollTimeoutRefs = useRef<number[]>([])\n const appliedStartScrollKeyRef = useRef<string | null>(null)\n const appliedEntryScrollKeyRef = useRef<string | null>(null)\n const newTurnSpacerRef = useRef<HTMLDivElement>(null)\n const newTurnScrollFrameRef = useRef<number | null>(null)\n const newTurnScrollTimeoutRef = useRef<number | null>(null)\n const newTurnSpacerFrameRef = useRef<number | null>(null)\n const newTurnAnimationFrameRef = useRef<number | null>(null)\n const newTurnAnimationCleanupRef = useRef<(() => void) | null>(null)\n const isAnimatingNewTurnRef = useRef(false)\n const heldStickToBottomRef = useRef(false)\n const pinnedScrollTopRef = useRef<number | null>(null)\n const newTurnPinActiveRef = useRef(false)\n const appliedNewUserMessageKeyRef = useRef<string | null>(null)\n const observedLatestUserAnchorRef = useRef<string | null>(\n latestUserIsOptimistic ? null : latestUserAnchorId,\n )\n const observedLatestUserStableIdRef = useRef<string | null>(\n latestUserIsOptimistic ? null : latestUserStableId,\n )\n const [activeTurnId, setActiveTurnId] = useState<string | null>(lastTurnId)\n const [virtualScrollMargin, setVirtualScrollMargin] = useState(0)\n const [scrollContainerElement, setScrollContainerElement] = useState<HTMLElement | null>(null)\n const loadingOlderRef = useRef(false)\n\n const virtualizationEnabled = Boolean(useChatEnvironment().useVirtualizer)\n const stablePrefixEnd = useMemo(\n () => (virtualizationEnabled ? findStablePrefixEnd(renderBlocks) : 0),\n [renderBlocks, virtualizationEnabled],\n )\n const stablePrefix = useMemo(\n () => renderBlocks.slice(0, stablePrefixEnd),\n [renderBlocks, stablePrefixEnd],\n )\n const { entryIdToBlockIndex, turnIdToBlockIndex } = useMemo(\n () => buildMessageListBlockIndexes(renderBlocks),\n [renderBlocks],\n )\n const { virtualizer } = useChatVirtualizer({\n count: stablePrefix.length,\n getScrollElement: () => scrollContainerElement,\n getItemKey: (index) => {\n const persistentId = stablePrefix[index]\n ? getRenderBlockPersistentId(stablePrefix[index])\n : null\n if (!persistentId) throw new Error(\"虚拟前缀包含缺少持久 ID 的消息块\")\n return persistentId\n },\n estimateSize: (index) => {\n const block = stablePrefix[index]\n if (!block) return 120\n const persistentId = getRenderBlockPersistentId(block)\n return (\n (persistentId ? measuredSizeByKeyRef.current.get(persistentId) : undefined) ??\n estimateRenderBlockSize(block)\n )\n },\n overscan: 6,\n scrollMargin: virtualScrollMargin,\n })\n\n const {\n items: turnNavItems,\n activeEntryId: activeNavEntryId,\n loadingEntryId: navLoadingEntryId,\n error: navError,\n failedEntryId: navFailedEntryId,\n selectEntry: selectNavEntry,\n } = useTurnNavigation({\n sessionId,\n reloadKey: latestUserSpeechEntryId(messages),\n rewriteKey: historyRewriteRevision,\n loadTurnIndex: isSharedSession\n ? undefined\n : session\n ? () => session.loadTurnIndex()\n : undefined,\n fallbackItems: sharedNavItems,\n locateEntry: (entryId) => session?.locateEntry(entryId) ?? Promise.resolve(false),\n cancelPendingLocate: () => session?.cancelPendingLocate(),\n getLoadedEntryElement: (entryId) => {\n const root = containerRef.current\n return root ? findEntryAnchor(root, entryId) : null\n },\n isEntryLoaded: (entryId) => entryIdToBlockIndex.has(entryId),\n revealEntry: (entryId) => {\n const blockIndex = entryIdToBlockIndex.get(entryId)\n if (blockIndex === undefined || blockIndex >= stablePrefixEnd) return\n virtualizer.scrollToIndex(blockIndex, { align: \"start\" })\n },\n beforeSeek: () => {\n stopNewTurnScrollAnimation()\n stickContextRef.current?.stopScroll()\n },\n })\n\n const activeViewportEntryId = useMemo(() => {\n if (!activeTurnId) return null\n const blockIndex = turnIdToBlockIndex.get(activeTurnId)\n const block = blockIndex === undefined ? undefined : renderBlocks[blockIndex]\n if (block?.type === \"assistant_turn\") return block.userEntryId\n if (block?.type === \"message\" && isUserMessage(block.message)) {\n return block.message.entry_id ?? null\n }\n return null\n }, [activeTurnId, renderBlocks, turnIdToBlockIndex])\n\n const lastNavTurnId = turnNavItems.at(-1)?.id ?? null\n\n const layoutSignature = useMemo(\n () =>\n `${getMessagesMeasureSignature(messages)}|${\n postChatFollowup\n ? `${postChatFollowup.assistant_entry_id}:${postChatFollowup.recaption ?? \"\"}:${postChatFollowup.suggestions.join(\"\\u0001\")}`\n : \"\"\n }|${\n (postChatFollowup?.final_artifacts ?? [])\n .map((artifact) => artifact.target)\n .join(\",\")\n }|${[...resultFeedbackByEntry.values()]\n .map((feedback) => `${feedback.assistant_entry_id}:${feedback.updated_at}`)\n .join(\",\")}`,\n [messages, postChatFollowup, resultFeedbackByEntry],\n )\n\n const followupTurnId = useMemo(() => {\n if (isRevealingAny) return null\n if (!postChatFollowup) return null\n if (postChatFollowup.assistant_entry_id) {\n const exactBlock = renderBlocks.find(\n (block): block is AssistantTurnRenderBlock =>\n block.type === \"assistant_turn\" &&\n block.messages.some(\n (message) => message.entry_id === postChatFollowup.assistant_entry_id,\n ),\n )\n if (exactBlock) return exactBlock.anchorId\n }\n return lastTurnId\n }, [lastTurnId, postChatFollowup, renderBlocks, isRevealingAny])\n\n const captureBoundaryAnchor = useCallback(() => {\n const scrollContainer = scrollContainerRef.current\n if (!scrollContainer) return null\n const containerRect = scrollContainer.getBoundingClientRect()\n const visibleRows = visibleBlockRowsRef.current\n const mountedRows = measuredRowElementsRef.current\n const candidates = Array.from(\n visibleRows.size > 0 ? visibleRows.values() : mountedRows.values(),\n (element) => ({ element, rect: element.getBoundingClientRect() }),\n )\n .filter(({ rect }) => rect.bottom >= containerRect.top && rect.top <= containerRect.bottom)\n .sort((left, right) => left.rect.top - right.rect.top)\n const first = candidates[0]\n const persistentId = first?.element.dataset.blockId\n const globalBlockIndex = Number(first?.element.dataset.globalBlockIndex)\n if (!first || !persistentId || !Number.isInteger(globalBlockIndex)) return null\n return {\n persistentId,\n globalBlockIndex,\n viewportOffset: first.rect.top - containerRect.top,\n }\n }, [])\n\n const measureActiveTurn = useEffectEvent(() => {\n const container = scrollContainerRef.current\n if (!container) {\n setActiveTurnId(lastTurnId)\n return\n }\n const containerRect = container.getBoundingClientRect()\n const visibleTurns = Array.from(mountedTurnElementsRef.current, ([turnId, element]) => {\n const rect = element.getBoundingClientRect()\n return { turnId, top: rect.top, bottom: rect.bottom }\n })\n const atBottom =\n container.scrollTop + container.clientHeight >=\n container.scrollHeight - NAV_AT_BOTTOM_EPSILON_PX\n setActiveTurnId((current) =>\n selectActiveTurnAtViewportPosition({\n visibleTurns,\n containerTop: containerRect.top,\n containerBottom: containerRect.bottom,\n fallbackTurnId: lastTurnId,\n currentTurnId: current,\n atBottom,\n }),\n )\n boundaryAnchorRef.current = captureBoundaryAnchor()\n })\n\n const scheduleMeasure = useEffectEvent(() => {\n if (frameRef.current != null) return\n frameRef.current = window.requestAnimationFrame(() => {\n frameRef.current = null\n measureActiveTurn()\n })\n })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: scheduleMeasure 是 Effect Event;只在滚动元素因 entry key 重建时重绑。\n useEffect(() => {\n void historyLoadRevision\n scrollContainerRef.current =\n stickContextRef.current?.scrollRef.current ?? findScrollContainer(containerRef.current)\n const sc = scrollContainerRef.current\n if (!sc) return\n setScrollContainerElement(sc)\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const element = entry.target as HTMLElement\n const turnId = element.dataset.turnId\n if (turnId && entry.isIntersecting) {\n visibleTurnsRef.current.set(turnId, element)\n } else if (turnId && visibleTurnsRef.current.get(turnId) === element) {\n visibleTurnsRef.current.delete(turnId)\n }\n const persistentId = element.dataset.blockId\n if (persistentId && entry.isIntersecting) {\n visibleBlockRowsRef.current.set(persistentId, element)\n } else if (\n persistentId &&\n visibleBlockRowsRef.current.get(persistentId) === element\n ) {\n visibleBlockRowsRef.current.delete(persistentId)\n }\n }\n scheduleMeasure()\n },\n { root: sc, threshold: 0, rootMargin: \"0px\" },\n )\n intersectionObserverRef.current = observer\n for (const element of mountedTurnElementsRef.current.values()) observer.observe(element)\n for (const element of measuredRowElementsRef.current.values()) observer.observe(element)\n\n let historySentinel: HTMLDivElement | null = null\n let historyObserver: IntersectionObserver | null = null\n let historyDisposed = false\n if (onLoadOlder) {\n historySentinel = document.createElement(\"div\")\n historySentinel.dataset.historySentinel = \"\"\n sc.prepend(historySentinel)\n const loadOlder = async () => {\n if (loadingOlderRef.current) return\n loadingOlderRef.current = true\n let anchorKey: string | undefined\n let anchorOffset = 0\n let height = sc.scrollHeight\n const advanced = await onLoadOlder(() => {\n const scrollerTop = sc.getBoundingClientRect().top\n const row = Array.from(sc.querySelectorAll<HTMLElement>(\"[data-block-id]\"))\n .find((item) => item.getBoundingClientRect().bottom >= scrollerTop)\n anchorKey = row?.dataset.blockId\n anchorOffset = row ? row.getBoundingClientRect().top - scrollerTop : 0\n height = sc.scrollHeight\n }).catch(() => false)\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))\n if (historyDisposed) return\n const anchored = anchorKey\n ? Array.from(sc.querySelectorAll<HTMLElement>(\"[data-block-id]\"))\n .find((item) => item.dataset.blockId === anchorKey)\n : null\n if (anchored) {\n sc.scrollTop += anchored.getBoundingClientRect().top\n - sc.getBoundingClientRect().top\n - anchorOffset\n } else {\n sc.scrollTop += sc.scrollHeight - height\n }\n loadingOlderRef.current = false\n if (advanced && sc.scrollHeight <= sc.clientHeight) void loadOlder()\n }\n historyObserver = new IntersectionObserver(([entry]) => {\n if (!entry?.isIntersecting) return\n void loadOlder()\n }, { root: sc, rootMargin: \"160px 0px 0px\" })\n historyObserver.observe(historySentinel)\n }\n\n sc.addEventListener(\"scroll\", scheduleMeasure, { passive: true })\n window.addEventListener(\"resize\", scheduleMeasure)\n scheduleMeasure()\n return () => {\n observer.disconnect()\n historyDisposed = true\n loadingOlderRef.current = false\n historyObserver?.disconnect()\n historySentinel?.remove()\n if (intersectionObserverRef.current === observer) {\n intersectionObserverRef.current = null\n }\n visibleTurnsRef.current.clear()\n visibleBlockRowsRef.current.clear()\n sc.removeEventListener(\"scroll\", scheduleMeasure)\n window.removeEventListener(\"resize\", scheduleMeasure)\n if (frameRef.current != null) {\n window.cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n }\n }, [scrollEntryId, onLoadOlder, historyLoadRevision])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: scheduleMeasure 是 Effect Event,React 要求不放进依赖数组。\n const getTurnElementRef = useCallback(\n (turnId: string) => {\n const existing = turnRefCallbacksRef.current.get(turnId)\n if (existing) return existing\n const callback = (element: HTMLDivElement | null) => {\n const previous = mountedTurnElementsRef.current.get(turnId)\n if (previous && previous !== element) {\n intersectionObserverRef.current?.unobserve(previous)\n if (visibleTurnsRef.current.get(turnId) === previous) {\n visibleTurnsRef.current.delete(turnId)\n }\n }\n if (element) {\n mountedTurnElementsRef.current.set(turnId, element)\n intersectionObserverRef.current?.observe(element)\n } else {\n mountedTurnElementsRef.current.delete(turnId)\n visibleTurnsRef.current.delete(turnId)\n turnRefCallbacksRef.current.delete(turnId)\n }\n scheduleMeasure()\n }\n turnRefCallbacksRef.current.set(turnId, callback)\n return callback\n },\n [],\n )\n\n const getMeasuredRowRef = useCallback(\n (block: RenderBlock, globalBlockIndex: number, isVirtual: boolean) => {\n const persistentId = getRenderBlockPersistentId(block)\n const callbackKey = `${persistentId ?? block.key}:${globalBlockIndex}:${isVirtual ? \"virtual\" : \"resident\"}`\n const existing = rowRefCallbacksRef.current.get(callbackKey)\n if (existing) return existing\n\n const callback = (element: HTMLDivElement | null) => {\n const previous = persistentId\n ? measuredRowElementsRef.current.get(persistentId)\n : undefined\n if (previous && previous !== element) rowResizeObserverRef.current?.unobserve(previous)\n if (previous && previous !== element) {\n intersectionObserverRef.current?.unobserve(previous)\n visibleBlockRowsRef.current.delete(persistentId ?? \"\")\n }\n if (isVirtual) virtualizer.measureElement(element)\n\n if (persistentId && element) {\n measuredRowElementsRef.current.set(persistentId, element)\n measuredSizeByKeyRef.current.set(\n persistentId,\n element.getBoundingClientRect().height,\n )\n rowResizeObserverRef.current?.observe(element)\n intersectionObserverRef.current?.observe(element)\n } else if (persistentId) {\n measuredRowElementsRef.current.delete(persistentId)\n visibleBlockRowsRef.current.delete(persistentId)\n rowRefCallbacksRef.current.delete(callbackKey)\n }\n }\n rowRefCallbacksRef.current.set(callbackKey, callback)\n return callback\n },\n [virtualizer],\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: layoutSignature 和 stickyTurnAnchorId 会改变前缀的实际顶部偏移。\n useLayoutEffect(() => {\n const prefix = virtualPrefixRef.current\n const scrollContainer = scrollContainerElement\n if (!prefix || !scrollContainer || stablePrefixEnd === 0) {\n setVirtualScrollMargin(0)\n return\n }\n const nextMargin =\n prefix.getBoundingClientRect().top -\n scrollContainer.getBoundingClientRect().top +\n scrollContainer.scrollTop\n setVirtualScrollMargin((current) =>\n Math.abs(current - nextMargin) > 0.5 ? nextMargin : current,\n )\n }, [layoutSignature, scrollContainerElement, stablePrefixEnd, stickyTurnAnchorId])\n\n const restoreBoundaryAnchor = useEffectEvent(\n (anchor: NonNullable<typeof boundaryAnchorRef.current>) => {\n const root = containerRef.current\n const scrollContainer = scrollContainerRef.current\n if (!root || !scrollContainer) return\n\n const adjust = () => {\n const target = Array.from(\n root.querySelectorAll<HTMLElement>(\"[data-block-id]\"),\n ).find((element) => element.dataset.blockId === anchor.persistentId)\n if (!target) return false\n const currentOffset =\n target.getBoundingClientRect().top - scrollContainer.getBoundingClientRect().top\n const drift = currentOffset - anchor.viewportOffset\n scrollContainer.scrollTop += drift\n if (newTurnPinActiveRef.current) pinnedScrollTopRef.current = scrollContainer.scrollTop\n return true\n }\n\n if (adjust()) return\n if (anchor.globalBlockIndex < stablePrefixEnd) {\n virtualizer.scrollToIndex(anchor.globalBlockIndex, { align: \"start\" })\n }\n window.requestAnimationFrame(adjust)\n },\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: restoreBoundaryAnchor 是 Effect Event,React 要求不放进依赖数组。\n useLayoutEffect(() => {\n const previousStablePrefixEnd = previousStablePrefixEndRef.current\n if (\n previousStablePrefixEnd !== null &&\n previousStablePrefixEnd !== stablePrefixEnd &&\n boundaryAnchorRef.current &&\n !isAnimatingNewTurnRef.current\n ) {\n restoreBoundaryAnchor(boundaryAnchorRef.current)\n }\n previousStablePrefixEndRef.current = stablePrefixEnd\n boundaryAnchorRef.current = captureBoundaryAnchor()\n }, [captureBoundaryAnchor, stablePrefixEnd])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: lastTurnId and layoutSignature are intentional triggers to re-measure\n useEffect(() => {\n scheduleMeasure()\n }, [lastTurnId, layoutSignature])\n\n const stopNewTurnScrollAnimation = useCallback(() => {\n if (newTurnAnimationFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnAnimationFrameRef.current)\n newTurnAnimationFrameRef.current = null\n }\n newTurnAnimationCleanupRef.current?.()\n newTurnAnimationCleanupRef.current = null\n isAnimatingNewTurnRef.current = false\n }, [])\n\n const scrollToSessionStart = useEffectEvent(() => {\n const container = scrollContainerRef.current ?? findScrollContainer(containerRef.current)\n if (!container) return\n stopNewTurnScrollAnimation()\n container.scrollTo({ top: 0, behavior: \"auto\" })\n setActiveTurnId(null)\n })\n\n const updateNewTurnSpacer = useEffectEvent((anchorId: string) => {\n const root = containerRef.current\n const spacer = newTurnSpacerRef.current\n if (!root || !spacer) return null\n const found = root.ownerDocument.getElementById(anchorId)\n const target = found && root.contains(found) ? found : null\n if (!target) return null\n const container = scrollContainerRef.current ?? findScrollContainer(root)\n if (!container) return null\n\n const containerRect = container.getBoundingClientRect()\n const targetRect = target.getBoundingClientRect()\n const stickyStatus = root.querySelector<HTMLElement>(\"[data-sticky-status-bar='true']\")\n const stickyStyle = stickyStatus ? getComputedStyle(stickyStatus) : null\n const margin = calculateStickyAwareMargin(\n stickyStatus?.getBoundingClientRect().height ?? 0,\n stickyStyle ? Number.parseFloat(stickyStyle.marginBottom) || 0 : 0,\n )\n const targetScrollTop = calculateAnchoredScrollTop({\n scrollTop: container.scrollTop,\n containerTop: containerRect.top,\n targetTop: targetRect.top,\n margin,\n })\n const spacerHeight = calculateTrailingSpacerHeight({\n targetScrollTop,\n scrollHeight: container.scrollHeight - spacer.getBoundingClientRect().height,\n clientHeight: container.clientHeight,\n currentScrollTop: container.scrollTop,\n })\n spacer.style.height = `${spacerHeight}px`\n const stick = stickContextRef.current\n if (spacerHeight > 0) {\n if (stick?.state.isAtBottom) stick.stopScroll()\n heldStickToBottomRef.current = true\n } else if (heldStickToBottomRef.current) {\n heldStickToBottomRef.current = false\n releaseNewTurnPin()\n }\n return { container, targetScrollTop }\n })\n\n const scheduleNewTurnSpacerUpdate = useEffectEvent(() => {\n const anchorId = observedLatestUserAnchorRef.current\n if (!newTurnPinActiveRef.current) return\n if (!appliedNewUserMessageKeyRef.current || !anchorId) return\n if (newTurnSpacerFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnSpacerFrameRef.current)\n }\n newTurnSpacerFrameRef.current = window.requestAnimationFrame(() => {\n newTurnSpacerFrameRef.current = null\n placeLatestUserAtTop(anchorId)\n })\n })\n\n // 行内容真正换行或展开时才维护高度;折叠态的逐字增量不会触发 ResizeObserver。\n // biome-ignore lint/correctness/useExhaustiveDependencies: scheduleMeasure 和 scheduleNewTurnSpacerUpdate 都是 Effect Event。\n useEffect(() => {\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const element = entry.target as HTMLElement\n const persistentId = element.dataset.blockId\n if (!persistentId) continue\n measuredSizeByKeyRef.current.set(\n persistentId,\n element.getBoundingClientRect().height,\n )\n }\n scheduleMeasure()\n scheduleNewTurnSpacerUpdate()\n })\n rowResizeObserverRef.current = observer\n for (const element of measuredRowElementsRef.current.values()) observer.observe(element)\n return () => {\n observer.disconnect()\n if (rowResizeObserverRef.current === observer) rowResizeObserverRef.current = null\n }\n }, [])\n\n const animateNewTurnScroll = useEffectEvent(\n (container: HTMLElement, anchorId: string, targetScrollTop: number) => {\n stopNewTurnScrollAnimation()\n const fromScrollTop = container.scrollTop\n const startedAt = performance.now()\n isAnimatingNewTurnRef.current = true\n\n const abortByUser = () => stopNewTurnScrollAnimation()\n container.addEventListener(\"wheel\", abortByUser, { passive: true })\n container.addEventListener(\"touchstart\", abortByUser, { passive: true })\n newTurnAnimationCleanupRef.current = () => {\n container.removeEventListener(\"wheel\", abortByUser)\n container.removeEventListener(\"touchstart\", abortByUser)\n }\n\n let latestTarget = targetScrollTop\n let currentFrom = fromScrollTop\n let currentStartedAt = startedAt\n let writtenScrollTop: number | null = null\n const step = (now: number) => {\n newTurnAnimationFrameRef.current = null\n if (\n writtenScrollTop !== null &&\n Math.abs(container.scrollTop - writtenScrollTop) > MANUAL_SCROLL_TOLERANCE_PX\n ) {\n stopNewTurnScrollAnimation()\n return\n }\n const nextTarget = updateNewTurnSpacer(anchorId)?.targetScrollTop ?? latestTarget\n if (Math.abs(nextTarget - latestTarget) > MANUAL_SCROLL_TOLERANCE_PX) {\n currentFrom = writtenScrollTop ?? container.scrollTop\n currentStartedAt = now\n }\n latestTarget = nextTarget\n const elapsedMs = now - currentStartedAt\n container.scrollTop = calculateAnimatedScrollTop({\n fromScrollTop: currentFrom,\n targetScrollTop: latestTarget,\n elapsedMs,\n })\n writtenScrollTop = container.scrollTop\n pinnedScrollTopRef.current = writtenScrollTop\n if (elapsedMs < NEW_TURN_SCROLL_DURATION_MS) {\n newTurnAnimationFrameRef.current = window.requestAnimationFrame(step)\n return\n }\n stopNewTurnScrollAnimation()\n }\n newTurnAnimationFrameRef.current = window.requestAnimationFrame(step)\n },\n )\n\n const placeLatestUserAtTop = useEffectEvent((anchorId: string) => {\n const placement = updateNewTurnSpacer(anchorId)\n if (!placement) return false\n const { container, targetScrollTop } = placement\n stickContextRef.current?.stopScroll()\n setActiveTurnId(null)\n if (\n shouldAnimateNewTurnScroll({\n fromScrollTop: container.scrollTop,\n targetScrollTop,\n clientHeight: container.clientHeight,\n prefersReducedMotion: prefersReducedMotion(),\n })\n ) {\n animateNewTurnScroll(container, anchorId, targetScrollTop)\n return true\n }\n stopNewTurnScrollAnimation()\n pinnedScrollTopRef.current = targetScrollTop\n container.scrollTo({ top: targetScrollTop, behavior: \"auto\" })\n return true\n })\n\n const cancelPendingNewTurnScroll = useCallback(() => {\n const hadPending =\n newTurnScrollFrameRef.current != null || newTurnScrollTimeoutRef.current != null\n if (newTurnScrollFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnScrollFrameRef.current)\n newTurnScrollFrameRef.current = null\n }\n if (newTurnScrollTimeoutRef.current != null) {\n window.clearTimeout(newTurnScrollTimeoutRef.current)\n newTurnScrollTimeoutRef.current = null\n }\n // 取消掉还没执行的滚动就等于这次没做成,去重守卫要跟着回退,\n // 否则开发环境 StrictMode 重放 effect 时会永久跳过这次滚动。\n if (hadPending) {\n appliedNewUserMessageKeyRef.current = null\n observedLatestUserAnchorRef.current = null\n observedLatestUserStableIdRef.current = null\n pinnedScrollTopRef.current = null\n }\n }, [])\n\n const releaseNewTurnPin = useCallback(() => {\n if (!newTurnPinActiveRef.current) return\n newTurnPinActiveRef.current = false\n if (newTurnScrollFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnScrollFrameRef.current)\n newTurnScrollFrameRef.current = null\n }\n if (newTurnScrollTimeoutRef.current != null) {\n window.clearTimeout(newTurnScrollTimeoutRef.current)\n newTurnScrollTimeoutRef.current = null\n }\n if (newTurnSpacerFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnSpacerFrameRef.current)\n newTurnSpacerFrameRef.current = null\n }\n stopNewTurnScrollAnimation()\n heldStickToBottomRef.current = false\n pinnedScrollTopRef.current = null\n const spacer = newTurnSpacerRef.current\n if (spacer) {\n const currentHeight = spacer.getBoundingClientRect().height\n if (currentHeight > 0) {\n spacer.style.transition = \"height 220ms ease-out\"\n spacer.style.height = \"0px\"\n window.setTimeout(() => {\n if (newTurnSpacerRef.current === spacer) spacer.style.transition = \"\"\n }, 240)\n } else {\n spacer.style.height = \"0px\"\n }\n }\n }, [stopNewTurnScrollAnimation])\n\n useEffect(\n () => () => {\n cancelPendingNewTurnScroll()\n stopNewTurnScrollAnimation()\n },\n [cancelPendingNewTurnScroll, stopNewTurnScrollAnimation],\n )\n\n // 顶置整段生效期间(不只是发言那一下的跳转动画)持续监听原生 scroll 事件,\n // 解决两个问题:\n //\n // 1)\"生成到一定程度之前拖不动滚动条\"——旧代码只在 animateNewTurnScroll\n // 那次一次性跳转动画里挂了 wheel/touchstart 的让位监听,动画一结束\n // (或者根本没走动画分支)就没人再听用户的手动滚动了;只要 spacer 还没\n // 收完,updateNewTurnSpacer 每一帧都会把 scrollTop 强制纠正回锚点,用户\n // 拖滚动条这种不发 wheel/touchstart、只体现为 scrollTop 被改的操作,\n // 完全没有退出通道。这里用 pinnedScrollTopRef 记录\"我们自己刚写成了\n // 什么\",一旦观测到的 scrollTop 跟这个值对不上(容差之外),不管是滚轮、\n // 触控板惯性还是拖滚动条,一律当场释放顶置。\n //\n // 2)\"上下抖动\"——use-stick-to-bottom 内部的 handleScroll 是异步的\n // (scroll 事件到 isAtBottom 重新被掰回 true 之间隔着一个 1ms 的\n // setTimeout),跟我们自己在 updateNewTurnSpacer 里\"只在偶尔几个时机\n // 调 stopScroll\"的节奏对不上:这个间隙里它把 isAtBottom 掰回 true 后,\n // 下一次内容增长它会用自己的弹簧动画抢着滚到底,我们要等到自己下一次\n // rAF 才发现、纠正回去——来回拉扯就是抖动。这里只要观测到的 scrollTop\n // 没有偏离我们自己写的值(说明这次 scroll 事件就是我们自己那次写入的\n // 回声,不是真实的手动滚动),就顺手再按一次 stopScroll,把重新武装的\n // 窗口从\"等我们自己下一次调度\"缩短到\"下一个 scroll 事件\",不给它可乘之机。\n useEffect(() => {\n const container = scrollContainerElement\n if (!container) return\n const handleScroll = () => {\n if (!newTurnPinActiveRef.current) return\n if (pinnedScrollTopRef.current == null) return\n if (Math.abs(container.scrollTop - pinnedScrollTopRef.current) > MANUAL_SCROLL_TOLERANCE_PX) {\n releaseNewTurnPin()\n return\n }\n stickContextRef.current?.stopScroll()\n }\n container.addEventListener(\"scroll\", handleScroll, { passive: true })\n return () => container.removeEventListener(\"scroll\", handleScroll)\n }, [scrollContainerElement, releaseNewTurnPin])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: placeLatestUserAtTop 是 Effect Event,React 要求不放进依赖数组。\n useEffect(() => {\n if (!effectiveNewUserMessageKey) {\n const acknowledgedSameTarget =\n newTurnPinActiveRef.current &&\n latestUserStableId != null &&\n observedLatestUserStableIdRef.current === latestUserStableId\n observedLatestUserStableIdRef.current = latestUserStableId\n observedLatestUserAnchorRef.current = latestUserAnchorId\n if (!acknowledgedSameTarget || (!sessionIsStreaming && !isRevealingAny)) releaseNewTurnPin()\n return\n }\n if (appliedNewUserMessageKeyRef.current === effectiveNewUserMessageKey) {\n observedLatestUserAnchorRef.current = latestUserAnchorId\n observedLatestUserStableIdRef.current = latestUserStableId\n return\n }\n if (!latestUserAnchorId || observedLatestUserAnchorRef.current === latestUserAnchorId) return\n\n cancelPendingNewTurnScroll()\n appliedNewUserMessageKeyRef.current = effectiveNewUserMessageKey\n observedLatestUserAnchorRef.current = latestUserAnchorId\n observedLatestUserStableIdRef.current = latestUserStableId\n newTurnPinActiveRef.current = true\n newTurnScrollFrameRef.current = window.requestAnimationFrame(() => {\n newTurnScrollFrameRef.current = null\n if (placeLatestUserAtTop(latestUserAnchorId)) return\n newTurnScrollTimeoutRef.current = window.setTimeout(() => {\n newTurnScrollTimeoutRef.current = null\n placeLatestUserAtTop(latestUserAnchorId)\n }, 80)\n })\n }, [\n cancelPendingNewTurnScroll,\n effectiveNewUserMessageKey,\n isRevealingAny,\n latestUserAnchorId,\n latestUserStableId,\n releaseNewTurnPin,\n sessionIsStreaming,\n ])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: layoutSignature 是唯一触发条件;scheduleNewTurnSpacerUpdate 是 Effect Event。\n useEffect(() => {\n scheduleNewTurnSpacerUpdate()\n return () => {\n if (newTurnSpacerFrameRef.current != null) {\n window.cancelAnimationFrame(newTurnSpacerFrameRef.current)\n newTurnSpacerFrameRef.current = null\n }\n }\n }, [layoutSignature])\n\n // 打字机式显示节流按帧推进正文/推理,是逐字增量、不改变换行前的行高——上面\n // 那个 ResizeObserver 只在真正换行/展开时才触发(layoutSignature 同理,故意\n // 不跟着逐字增量变,避免每个 delta 都重测整段虚拟列表)。这导致 spacer 只有\n // 在内容真正长出新的一行时才收缩一次,追不上节流本身\"每帧一点点\"的视觉增长\n // 节奏,顶置的发言看起来会随着下面内容变高而慢慢往上漂。这里单独接一路,只\n // 在顶置生效期间跟着节流的每一帧重新收一次 spacer,不去碰 layoutSignature,\n // 不影响虚拟列表的测量频率。\n // biome-ignore lint/correctness/useExhaustiveDependencies: scheduleNewTurnSpacerUpdate 是 Effect Event。\n useEffect(() => {\n if (!newTurnPinActiveRef.current) return\n scheduleNewTurnSpacerUpdate()\n }, [contentReveal.displayedText, reasoningReveal.displayedText])\n\n useEffect(() => () => {\n if (startScrollFrameRef.current != null) {\n window.cancelAnimationFrame(startScrollFrameRef.current)\n startScrollFrameRef.current = null\n }\n if (startScrollTimeoutRef.current != null) {\n window.clearTimeout(startScrollTimeoutRef.current)\n startScrollTimeoutRef.current = null\n }\n if (entryScrollFrameRef.current != null) {\n window.cancelAnimationFrame(entryScrollFrameRef.current)\n entryScrollFrameRef.current = null\n }\n for (const timeoutId of entryScrollTimeoutRefs.current) {\n window.clearTimeout(timeoutId)\n }\n entryScrollTimeoutRefs.current = []\n appliedStartScrollKeyRef.current = null\n appliedEntryScrollKeyRef.current = null\n }, [])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: scrollToSessionStart 是 Effect Event,React 要求不放进依赖数组。\n useEffect(() => {\n if (!scrollToStartKey || !hasMessages) {\n if (startScrollFrameRef.current != null) window.cancelAnimationFrame(startScrollFrameRef.current)\n if (startScrollTimeoutRef.current != null) window.clearTimeout(startScrollTimeoutRef.current)\n startScrollFrameRef.current = null\n startScrollTimeoutRef.current = null\n appliedStartScrollKeyRef.current = null\n return\n }\n const applyKey = scrollToStartKey\n if (appliedStartScrollKeyRef.current === applyKey) return\n appliedStartScrollKeyRef.current = applyKey\n if (startScrollFrameRef.current != null) {\n window.cancelAnimationFrame(startScrollFrameRef.current)\n }\n if (startScrollTimeoutRef.current != null) {\n window.clearTimeout(startScrollTimeoutRef.current)\n }\n startScrollFrameRef.current = window.requestAnimationFrame(() => {\n startScrollFrameRef.current = null\n scrollToSessionStart()\n startScrollTimeoutRef.current = window.setTimeout(() => {\n startScrollTimeoutRef.current = null\n scrollToSessionStart()\n }, 80)\n })\n }, [hasMessages, scrollToStartKey])\n\n const scrollToEntry = useEffectEvent((entryId: string) => {\n const root = containerRef.current\n if (!root) return false\n const blockIndex = entryIdToBlockIndex.get(entryId)\n const target =\n findEntryAnchor(root, entryId) ??\n (blockIndex === undefined\n ? null\n : Array.from(\n root.querySelectorAll<HTMLElement>(\"[data-global-block-index]\"),\n ).find(\n (element) => Number(element.dataset.globalBlockIndex) === blockIndex,\n ) ?? null)\n if (!target) return false\n stickContextRef.current?.stopScroll()\n stopNewTurnScrollAnimation()\n const container = scrollContainerRef.current ?? findScrollContainer(root)\n if (container) {\n const containerRect = container.getBoundingClientRect()\n const targetRect = target.getBoundingClientRect()\n container.scrollTo({\n top: calculateAnchoredScrollTop({\n scrollTop: container.scrollTop,\n containerTop: containerRect.top,\n targetTop: targetRect.top,\n }),\n behavior: \"auto\",\n })\n } else {\n target.scrollIntoView({ behavior: \"auto\", block: \"start\" })\n }\n setActiveTurnId(target.dataset.turnId ?? null)\n return true\n })\n\n const getAnchorTargetScrollTop = useCallback<GetTargetScrollTop>(\n (defaultTargetScrollTop, { scrollElement, contentElement }) => {\n if (!scrollEntryId) return defaultTargetScrollTop\n const target = findEntryAnchor(contentElement, scrollEntryId)\n if (!target) return defaultTargetScrollTop\n const containerRect = scrollElement.getBoundingClientRect()\n const targetRect = target.getBoundingClientRect()\n return calculateAnchoredScrollTop({\n scrollTop: scrollElement.scrollTop,\n containerTop: containerRect.top,\n targetTop: targetRect.top,\n })\n },\n [scrollEntryId],\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: scrollToEntry 和 scrollToSessionStart 是 Effect Event,React 要求不放进依赖数组。\n useEffect(() => {\n if (appliedEntryScrollKeyRef.current !== scrollEntryId) {\n if (entryScrollFrameRef.current != null) window.cancelAnimationFrame(entryScrollFrameRef.current)\n for (const timeoutId of entryScrollTimeoutRefs.current) window.clearTimeout(timeoutId)\n entryScrollFrameRef.current = null\n entryScrollTimeoutRefs.current = []\n appliedEntryScrollKeyRef.current = null\n }\n if (!scrollEntryId || !hasMessages) return\n const entryId = scrollEntryId\n const blockIndex = entryIdToBlockIndex.get(entryId)\n const isVirtualTarget = blockIndex !== undefined && blockIndex < stablePrefixEnd\n if (\n isVirtualTarget &&\n (!scrollContainerElement || scrollContainerElement !== scrollContainerRef.current)\n ) return\n const applyKey = scrollEntryId\n if (appliedEntryScrollKeyRef.current === applyKey) return\n appliedEntryScrollKeyRef.current = applyKey\n if (entryScrollFrameRef.current != null) {\n window.cancelAnimationFrame(entryScrollFrameRef.current)\n }\n for (const timeoutId of entryScrollTimeoutRefs.current) {\n window.clearTimeout(timeoutId)\n }\n entryScrollTimeoutRefs.current = []\n if (isVirtualTarget) {\n virtualizer.scrollToIndex(blockIndex, { align: \"start\" })\n }\n entryScrollFrameRef.current = window.requestAnimationFrame(() => {\n entryScrollFrameRef.current = null\n const attempts = [0, 60, 160, 360, 700, 1200]\n let matched = false\n for (const delay of attempts) {\n const timeoutId = window.setTimeout(() => {\n matched = scrollToEntry(entryId) || matched\n }, delay)\n entryScrollTimeoutRefs.current.push(timeoutId)\n }\n const fallbackId = window.setTimeout(() => {\n entryScrollTimeoutRefs.current = []\n if (!matched && !scrollToEntry(entryId)) {\n scrollToSessionStart()\n }\n }, 1400)\n entryScrollTimeoutRefs.current.push(fallbackId)\n })\n }, [\n entryIdToBlockIndex,\n hasMessages,\n scrollContainerElement,\n scrollEntryId,\n stablePrefixEnd,\n virtualizer,\n ])\n\n return (\n <div\n ref={containerRef}\n part=\"messages\"\n className={`blade-chat-messages relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? \"\"}`}\n >\n {!isPreparing && (sessionIsStreaming || isRevealingAny) ? (\n <output className=\"sr-only\">正在生成回复</output>\n ) : null}\n {turnNavItems.length > 1 ? (\n <TurnNavRail\n items={turnNavItems}\n activeTurnId={activeViewportEntryId ?? activeNavEntryId ?? lastNavTurnId}\n onSelectTurn={selectNavEntry}\n loadingTurnId={navLoadingEntryId}\n error={navError}\n failedTurnId={navFailedEntryId}\n />\n ) : null}\n <StickToBottom\n key={scrollEntryId ?? \"latest\"}\n contextRef={stickContextRef}\n className=\"h-full overflow-y-hidden\"\n initial={shouldAnchorEntry ? \"instant\" : \"instant\"}\n resize={stickyTurn ? { damping: 0.8, stiffness: 0.08, mass: 1 } : \"instant\"}\n targetScrollTop={shouldAnchorEntry ? getAnchorTargetScrollTop : undefined}\n >\n <StickToBottom.Content\n part=\"messages-scroll\"\n className={cn(\n \"blade-chat-messages-scroll px-5 pb-7 pt-8 sm:px-10 sm:pt-10\",\n customization?.classNames?.messageListViewport,\n )}\n >\n <MessageListContent\n askAnswers={askAnswers}\n hasInterruptedTurn={hasInterruptedTurn}\n lastTurnId={lastTurnId}\n layoutSignature={layoutSignature}\n messages={messages}\n onAnswer={onAnswer}\n onConfirmPlan={onConfirmPlan}\n renderBlocks={renderBlocks}\n sessionId={sessionId}\n sessionStatus={sessionStatus}\n isReasoningRevealing={isReasoningRevealing}\n revealTargetMessage={latestAssistantMessage}\n revealedContentText={contentReveal.displayedText}\n revealedReasoningText={reasoningReveal.displayedText}\n isRevealingAny={isRevealingAny}\n customization={customization}\n followupTurnId={followupTurnId}\n postChatFollowup={postChatFollowup}\n resultFeedbackByEntry={resultFeedbackByEntry}\n onResultFeedbackSaved={onResultFeedbackSaved}\n isViewer={isViewer}\n isLoadingHistory={isLoadingHistory}\n stablePrefixEnd={stablePrefixEnd}\n virtualItems={virtualizer.getVirtualItems()}\n virtualTotalSize={virtualizer.getTotalSize()}\n virtualScrollMargin={virtualScrollMargin}\n virtualPrefixRef={virtualPrefixRef}\n getMeasuredRowRef={getMeasuredRowRef}\n getTurnElementRef={getTurnElementRef}\n emptyState={emptyState}\n />\n {isPreparing ? (\n <div className=\"mx-auto mt-3 max-w-[748px] px-4\"><ChatLoadingIndicator preparing /></div>\n ) : null}\n <div ref={newTurnSpacerRef} aria-hidden=\"true\" className=\"pointer-events-none w-full\" />\n </StickToBottom.Content>\n <ScrollToBottomButton onBeforeScroll={releaseNewTurnPin} />\n </StickToBottom>\n </div>\n )\n}\n\nfunction MessageListContent({\n askAnswers,\n hasInterruptedTurn,\n lastTurnId,\n layoutSignature,\n messages,\n onAnswer,\n onConfirmPlan,\n renderBlocks,\n sessionId,\n sessionStatus,\n isReasoningRevealing,\n revealTargetMessage,\n revealedContentText,\n revealedReasoningText,\n isRevealingAny,\n customization,\n followupTurnId,\n postChatFollowup,\n resultFeedbackByEntry,\n onResultFeedbackSaved,\n isViewer,\n isLoadingHistory,\n stablePrefixEnd,\n virtualItems,\n virtualTotalSize,\n virtualScrollMargin,\n virtualPrefixRef,\n getMeasuredRowRef,\n getTurnElementRef,\n emptyState,\n}: {\n askAnswers?: Record<string, AskUserAnswerData>\n hasInterruptedTurn: boolean\n lastTurnId: string | null\n layoutSignature: string\n messages: ChatMessage[]\n onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void\n onConfirmPlan?: (action: \"execute\" | \"revise\", text?: string) => void\n renderBlocks: RenderBlock[]\n sessionId: string\n sessionStatus?: string\n isReasoningRevealing: boolean\n revealTargetMessage?: ChatMessage\n revealedContentText: string\n revealedReasoningText: string\n isRevealingAny: boolean\n customization?: ChatViewCustomization\n followupTurnId: string | null\n postChatFollowup: PostChatFollowup | null\n resultFeedbackByEntry: ReadonlyMap<string, ResultFeedback>\n onResultFeedbackSaved?: (feedback: ResultFeedback) => void\n isViewer: boolean\n emptyState?: ReactNode\n isLoadingHistory: boolean\n stablePrefixEnd: number\n virtualItems: VirtualItem[]\n virtualTotalSize: number\n virtualScrollMargin: number\n virtualPrefixRef: RefObject<HTMLDivElement | null>\n getMeasuredRowRef: (\n block: RenderBlock,\n globalBlockIndex: number,\n isVirtual: boolean,\n ) => (element: HTMLDivElement | null) => void\n getTurnElementRef: (turnId: string) => (element: HTMLDivElement | null) => void\n}) {\n const latestPlanCardBlockIndex = useMemo(() => {\n for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {\n const block = renderBlocks[index]\n if (block.type !== \"assistant_turn\") continue\n const hasExitPlan = block.messages.some((message) => message.tool_calls?.some(\n (toolCall) => formatToolName(toolCall.name) === \"ExitPlanMode\" &&\n toolCall.status !== \"error\" && toolCall.status !== \"cancelled\",\n ))\n const nextBlock = renderBlocks[index + 1]\n if (hasExitPlan || (nextBlock?.type === \"planning_divider\" && nextBlock.kind === \"exit\")) {\n return index\n }\n }\n return -1\n }, [renderBlocks])\n const applyReveal = (message: ChatMessage): ChatMessage => {\n if (message !== revealTargetMessage) return message\n const content = typeof message.content === \"string\" ? revealedContentText : message.content\n const reasoning = message.reasoning != null ? revealedReasoningText : message.reasoning\n const toolCalls = isRevealingAny ? undefined : message.tool_calls\n return { ...message, content, reasoning, tool_calls: toolCalls }\n }\n\n const RenderBlockView = (block: RenderBlock, globalBlockIndex: number) => {\n if (block.type === \"message\") {\n return (\n <div\n id={block.anchorId ?? undefined}\n data-entry-id={block.message.entry_id}\n className=\"msg-animate scroll-mt-6\"\n >\n {isBackgroundWakeMessage(block.message) ? (\n <BackgroundWakeNotice />\n ) : isUserMessage(block.message) ? (\n customization?.components?.UserMessage ? (\n <customization.components.UserMessage\n message={block.message}\n className={customization.classNames?.userMessage}\n />\n ) : (\n <UserMessageBubble\n message={block.message}\n className={customization?.classNames?.userMessage}\n />\n )\n ) : isErrorMessage(block.message) ? (\n customization?.components?.ErrorMessage ? (\n <customization.components.ErrorMessage\n message={block.message}\n className={customization.classNames?.errorMessage}\n />\n ) : (\n <ErrorMessageBlock\n message={block.message}\n className={customization?.classNames?.errorMessage}\n />\n )\n ) : null}\n </div>\n )\n }\n\n if (block.type === \"assistant_turn\") {\n const displayMessages = revealTargetMessage && block.messages.includes(revealTargetMessage)\n ? block.messages.map(applyReveal)\n : block.messages\n const nextBlock = renderBlocks[globalBlockIndex + 1]\n const hasExitPlan = displayMessages.some((message) =>\n message.tool_calls?.some(\n (toolCall) =>\n formatToolName(toolCall.name) === \"ExitPlanMode\" &&\n toolCall.status !== \"error\" &&\n toolCall.status !== \"cancelled\",\n ),\n )\n const isFollowedByPlanningExit =\n nextBlock?.type === \"planning_divider\" && nextBlock.kind === \"exit\"\n const showPlanCard =\n (hasExitPlan || isFollowedByPlanningExit) &&\n onConfirmPlan &&\n sessionStatus === \"waiting_for_input\"\n const isHistoricalPlan = globalBlockIndex !== latestPlanCardBlockIndex\n const blockFeedback = displayMessages\n .map((message) => message.entry_id && resultFeedbackByEntry.get(message.entry_id))\n .find((feedback): feedback is ResultFeedback => feedback != null)\n const isActiveFollowup = block.anchorId === followupTurnId\n return (\n <div\n ref={getTurnElementRef(block.anchorId)}\n id={block.anchorId}\n data-turn-id={block.anchorId}\n data-entry-id={block.messages[0]?.entry_id}\n className=\"msg-animate flex scroll-mt-6 flex-col gap-4\"\n >\n <RenderErrorBoundary\n label=\"助手消息\"\n details={block.key}\n resetKey={getMessagesResetSignature(displayMessages)}\n >\n {customization?.components?.AssistantTurn ? (\n <customization.components.AssistantTurn\n turnKey={block.key}\n sessionId={sessionId}\n messages={displayMessages}\n isStreaming={block.isStreaming}\n isReasoningRevealing={isReasoningRevealing}\n isLastTurn={block.anchorId === lastTurnId}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n sessionStatus={sessionStatus}\n customization={customization}\n />\n ) : (\n <AssistantTurnBlock\n turnKey={block.key}\n sessionId={sessionId}\n messages={displayMessages}\n isStreaming={block.isStreaming}\n isReasoningRevealing={isReasoningRevealing}\n isLastTurn={block.anchorId === lastTurnId}\n askAnswers={askAnswers}\n onAnswer={onAnswer}\n sessionStatus={sessionStatus}\n customization={customization}\n />\n )}\n </RenderErrorBoundary>\n {showPlanCard ? (\n <RenderErrorBoundary\n label=\"规划摘要\"\n details={block.key}\n resetKey={`${sessionStatus ?? \"\"}:${layoutSignature}`}\n >\n <PlanSummaryCard\n messages={extractPlanMessagesForTurn(messages, block.messages.at(-1)!)}\n sessionStatus={isHistoricalPlan ? undefined : sessionStatus}\n onConfirmPlan={isHistoricalPlan ? undefined : onConfirmPlan}\n isHistorical={isHistoricalPlan}\n sessionId={sessionId}\n />\n </RenderErrorBoundary>\n ) : null}\n {blockFeedback && !isActiveFollowup ? (\n <HistoricalResultFeedback feedback={blockFeedback} />\n ) : null}\n {isActiveFollowup ? (\n <PostChatFollowupBlock\n sessionId={sessionId}\n followup={postChatFollowup}\n isViewer={isViewer}\n savedFeedback={blockFeedback}\n onFeedbackSaved={onResultFeedbackSaved}\n />\n ) : null}\n </div>\n )\n }\n\n if (block.type === \"compaction\") return null\n\n if (block.type === \"context_group\") {\n const contexts = block.messages\n .map((message) => message.context)\n .filter((context) => Boolean(context)) as NonNullable<ChatMessage[\"context\"]>[]\n return contexts.length > 0 ? (\n <div className=\"msg-animate\" data-entry-id={block.messages[0].entry_id}>\n <ContextGroupCard contexts={contexts} />\n </div>\n ) : null\n }\n\n if (block.type === \"context_divider\") {\n return <ContextDivider />\n }\n\n return <PlanningDivider kind={block.kind} />\n }\n\n const renderMeasuredRow = (\n block: RenderBlock,\n globalBlockIndex: number,\n virtualItem?: VirtualItem,\n ) => {\n const persistentId = getRenderBlockPersistentId(block)\n const isVirtual = virtualItem !== undefined\n return (\n <div\n key={block.key}\n ref={getMeasuredRowRef(block, globalBlockIndex, isVirtual)}\n className={isVirtual ? \"flex flex-col\" : undefined}\n data-index={virtualItem?.index}\n data-block-id={persistentId ?? undefined}\n data-global-block-index={globalBlockIndex}\n style={{\n ...(virtualItem\n ? {\n position: \"absolute\" as const,\n top: 0,\n left: 0,\n width: \"100%\",\n rowGap: \"inherit\",\n transform: `translateY(${virtualItem.start - virtualScrollMargin}px)`,\n }\n : {}),\n }}\n >\n {RenderBlockView(block, globalBlockIndex)}\n {isVirtual && globalBlockIndex < stablePrefixEnd - 1 ? (\n <div aria-hidden=\"true\" className=\"h-0 shrink-0\" />\n ) : null}\n </div>\n )\n }\n\n return (\n <div\n part=\"messages-content\"\n className={`blade-chat-messages-content mx-auto max-w-[748px] ${customization?.classNames?.messageListContent ?? \"\"}`}\n >\n <div className={`min-w-0 flex flex-col gap-9 ${customization?.classNames?.messageListInner ?? \"\"}`}>\n {renderBlocks.length === 0 && isLoadingHistory ? (\n <HistoryLoadingPlaceholder />\n ) : renderBlocks.length === 0 ? (\n emptyState ? (\n emptyState\n ) : customization?.components?.EmptyState ? (\n <customization.components.EmptyState />\n ) : (\n <div\n part=\"empty\"\n className={`blade-chat-empty flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? \"\"}`}\n >\n <MessageSquare size={40} strokeWidth={1.5} />\n <span className=\"text-base font-medium\">开始对话</span>\n <span className=\"text-sm opacity-60\">在下方输入消息开始聊天</span>\n </div>\n )\n ) : (\n <>\n {stablePrefixEnd > 0 ? (\n <div\n ref={virtualPrefixRef}\n data-virtual-prefix=\"true\"\n className=\"relative w-full\"\n style={{ height: virtualTotalSize, rowGap: \"inherit\" }}\n >\n {virtualItems.map((virtualItem) => {\n const block = renderBlocks[virtualItem.index]\n return block\n ? renderMeasuredRow(block, virtualItem.index, virtualItem)\n : null\n })}\n </div>\n ) : null}\n {renderBlocks\n .slice(stablePrefixEnd)\n .map((block, residentIndex) =>\n renderMeasuredRow(block, stablePrefixEnd + residentIndex),\n )}\n </>\n )}\n {sessionStatus === \"interrupted\" && !hasInterruptedTurn ? (\n <div className=\"flex\">\n <div className=\"rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]\">\n 已中断\n </div>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction HistoryLoadingPlaceholder() {\n return (\n <div className=\"flex flex-col gap-9\" aria-busy=\"true\" aria-live=\"polite\">\n <div className=\"flex items-center justify-center gap-2 text-sm text-[hsl(var(--muted-foreground))]\">\n <span className=\"size-3.5 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n <span>正在加载对话记录…</span>\n </div>\n {[0, 1].map((index) => (\n <div key={index} className=\"flex flex-col gap-4\">\n <div className=\"flex justify-end\">\n <div className=\"h-10 w-2/5 animate-pulse rounded-2xl bg-[hsl(var(--muted))]\" />\n </div>\n <div className=\"flex flex-col gap-2.5\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-[hsl(var(--muted))]\" />\n <div className=\"h-4 w-4/5 animate-pulse rounded bg-[hsl(var(--muted))]\" />\n <div className=\"h-4 w-3/5 animate-pulse rounded bg-[hsl(var(--muted))]\" />\n </div>\n </div>\n ))}\n </div>\n )\n}\n\nfunction ScrollToBottomButton({ onBeforeScroll }: { onBeforeScroll?: () => void }) {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n if (isAtBottom) return null\n\n return (\n <button\n type=\"button\"\n onClick={() => {\n onBeforeScroll?.()\n scrollToBottom()\n }}\n aria-label=\"滚动到底部\"\n part=\"scroll-bottom\"\n className=\"blade-chat-scroll-bottom absolute bottom-4 right-4 flex items-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-1.5 text-xs text-[hsl(var(--muted-foreground))] shadow-[var(--swf-shadow-overlay)] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]\"\n >\n <ChevronDown size={14} />\n <span className=\"blade-chat-scroll-bottom-label\">滚动到底部</span>\n </button>\n )\n}\n\nfunction PlanningDivider({ kind }: { kind: \"enter\" | \"exit\" }) {\n const isEnter = kind === \"enter\"\n\n return (\n <div className=\"flex items-center gap-3 py-1\">\n <div className=\"h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent\" />\n <div className=\"inline-flex items-center gap-1.5 rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-3 py-1 text-[11px] text-[hsl(var(--swf-warning))]\">\n <Lightbulb size={12} />\n <span>{isEnter ? \"进入规划模式\" : \"规划完成\"}</span>\n </div>\n <div className=\"h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent\" />\n </div>\n )\n}\n\nfunction ContextDivider() {\n return <div aria-hidden=\"true\" className=\"h-px w-full bg-[hsl(var(--border)/0.55)]\" />\n}\n\n/**\n * 消息列表。单独使用时(方案布局、开发调试页)没有聊天面板提供的「当前会话」,这里按传入的\n * 会话补上,用户消息里的附件预览、工具卡的文件入口据此找到会话文件。\n */\nexport function MessageList(props: MessageListProps) {\n return (\n <CurrentChatSessionProvider sessionId={props.sessionId || null}>\n <MessageListBody {...props} />\n </CurrentChatSessionProvider>\n )\n}\n","/*!---------------------------------------------------------------------------------------------\n * Copyright (c) StackBlitz. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport { useCallback, useMemo, useRef, useState, } from \"react\";\nconst DEFAULT_SPRING_ANIMATION = {\n /**\n * A value from 0 to 1, on how much to damp the animation.\n * 0 means no damping, 1 means full damping.\n *\n * @default 0.7\n */\n damping: 0.7,\n /**\n * The stiffness of how fast/slow the animation gets up to speed.\n *\n * @default 0.05\n */\n stiffness: 0.05,\n /**\n * The inertial mass associated with the animation.\n * Higher numbers make the animation slower.\n *\n * @default 1.25\n */\n mass: 1.25,\n};\nconst STICK_TO_BOTTOM_OFFSET_PX = 70;\nconst SIXTY_FPS_INTERVAL_MS = 1000 / 60;\nconst RETAIN_ANIMATION_DURATION_MS = 350;\nlet mouseDown = false;\nglobalThis.document?.addEventListener(\"mousedown\", () => {\n mouseDown = true;\n});\nglobalThis.document?.addEventListener(\"mouseup\", () => {\n mouseDown = false;\n});\nglobalThis.document?.addEventListener(\"click\", () => {\n mouseDown = false;\n});\nexport const useStickToBottom = (options = {}) => {\n const [escapedFromLock, updateEscapedFromLock] = useState(false);\n const [isAtBottom, updateIsAtBottom] = useState(options.initial !== false);\n const [isNearBottom, setIsNearBottom] = useState(false);\n const optionsRef = useRef(null);\n optionsRef.current = options;\n const isSelecting = useCallback(() => {\n if (!mouseDown) {\n return false;\n }\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount) {\n return false;\n }\n const range = selection.getRangeAt(0);\n return (range.commonAncestorContainer.contains(scrollRef.current) ||\n scrollRef.current?.contains(range.commonAncestorContainer));\n }, []);\n const setIsAtBottom = useCallback((isAtBottom) => {\n state.isAtBottom = isAtBottom;\n updateIsAtBottom(isAtBottom);\n }, []);\n const setEscapedFromLock = useCallback((escapedFromLock) => {\n state.escapedFromLock = escapedFromLock;\n updateEscapedFromLock(escapedFromLock);\n }, []);\n // biome-ignore lint/correctness/useExhaustiveDependencies: not needed\n const state = useMemo(() => {\n let lastCalculation;\n return {\n escapedFromLock,\n isAtBottom,\n resizeDifference: 0,\n accumulated: 0,\n velocity: 0,\n listeners: new Set(),\n get scrollTop() {\n return scrollRef.current?.scrollTop ?? 0;\n },\n set scrollTop(scrollTop) {\n if (scrollRef.current) {\n scrollRef.current.scrollTop = scrollTop;\n state.ignoreScrollToTop = scrollRef.current.scrollTop;\n }\n },\n get targetScrollTop() {\n if (!scrollRef.current || !contentRef.current) {\n return 0;\n }\n return (scrollRef.current.scrollHeight - 1 - scrollRef.current.clientHeight);\n },\n get calculatedTargetScrollTop() {\n if (!scrollRef.current || !contentRef.current) {\n return 0;\n }\n const { targetScrollTop } = this;\n if (!options.targetScrollTop) {\n return targetScrollTop;\n }\n if (lastCalculation?.targetScrollTop === targetScrollTop) {\n return lastCalculation.calculatedScrollTop;\n }\n const calculatedScrollTop = Math.max(Math.min(options.targetScrollTop(targetScrollTop, {\n scrollElement: scrollRef.current,\n contentElement: contentRef.current,\n }), targetScrollTop), 0);\n lastCalculation = { targetScrollTop, calculatedScrollTop };\n requestAnimationFrame(() => {\n lastCalculation = undefined;\n });\n return calculatedScrollTop;\n },\n get scrollDifference() {\n return this.calculatedTargetScrollTop - this.scrollTop;\n },\n get isNearBottom() {\n return this.scrollDifference <= STICK_TO_BOTTOM_OFFSET_PX;\n },\n };\n }, []);\n const scrollToBottom = useCallback((scrollOptions = {}) => {\n if (typeof scrollOptions === \"string\") {\n scrollOptions = { animation: scrollOptions };\n }\n if (!scrollOptions.preserveScrollPosition) {\n setIsAtBottom(true);\n }\n const waitElapsed = Date.now() + (Number(scrollOptions.wait) || 0);\n const behavior = mergeAnimations(optionsRef.current, scrollOptions.animation);\n const { ignoreEscapes = false } = scrollOptions;\n let durationElapsed;\n let startTarget = state.calculatedTargetScrollTop;\n if (scrollOptions.duration instanceof Promise) {\n scrollOptions.duration.finally(() => {\n durationElapsed = Date.now();\n });\n }\n else {\n durationElapsed = waitElapsed + (scrollOptions.duration ?? 0);\n }\n const next = async () => {\n const promise = new Promise(requestAnimationFrame).then(() => {\n if (!state.isAtBottom) {\n state.animation = undefined;\n return false;\n }\n const { scrollTop } = state;\n const tick = performance.now();\n const tickDelta = (tick - (state.lastTick ?? tick)) / SIXTY_FPS_INTERVAL_MS;\n state.animation || (state.animation = { behavior, promise, ignoreEscapes });\n if (state.animation.behavior === behavior) {\n state.lastTick = tick;\n }\n if (isSelecting()) {\n return next();\n }\n if (waitElapsed > Date.now()) {\n return next();\n }\n if (scrollTop < Math.min(startTarget, state.calculatedTargetScrollTop)) {\n if (state.animation?.behavior === behavior) {\n if (behavior === \"instant\") {\n state.scrollTop = state.calculatedTargetScrollTop;\n return next();\n }\n state.velocity =\n (behavior.damping * state.velocity +\n behavior.stiffness * state.scrollDifference) /\n behavior.mass;\n state.accumulated += state.velocity * tickDelta;\n state.scrollTop += state.accumulated;\n if (state.scrollTop !== scrollTop) {\n state.accumulated = 0;\n }\n }\n return next();\n }\n if (durationElapsed > Date.now()) {\n startTarget = state.calculatedTargetScrollTop;\n return next();\n }\n state.animation = undefined;\n /**\n * If we're still below the target, then queue\n * up another scroll to the bottom with the last\n * requested animatino.\n */\n if (state.scrollTop < state.calculatedTargetScrollTop) {\n return scrollToBottom({\n animation: mergeAnimations(optionsRef.current, optionsRef.current.resize),\n ignoreEscapes,\n duration: Math.max(0, durationElapsed - Date.now()) || undefined,\n });\n }\n return state.isAtBottom;\n });\n return promise.then((isAtBottom) => {\n requestAnimationFrame(() => {\n if (!state.animation) {\n state.lastTick = undefined;\n state.velocity = 0;\n }\n });\n return isAtBottom;\n });\n };\n if (scrollOptions.wait !== true) {\n state.animation = undefined;\n }\n if (state.animation?.behavior === behavior) {\n return state.animation.promise;\n }\n return next();\n }, [setIsAtBottom, isSelecting, state]);\n const stopScroll = useCallback(() => {\n setEscapedFromLock(true);\n setIsAtBottom(false);\n }, [setEscapedFromLock, setIsAtBottom]);\n const handleScroll = useCallback(({ target }) => {\n if (target !== scrollRef.current) {\n return;\n }\n const { scrollTop, ignoreScrollToTop } = state;\n let { lastScrollTop = scrollTop } = state;\n state.lastScrollTop = scrollTop;\n state.ignoreScrollToTop = undefined;\n if (ignoreScrollToTop && ignoreScrollToTop > scrollTop) {\n /**\n * When the user scrolls up while the animation plays, the `scrollTop` may\n * not come in separate events; if this happens, to make sure `isScrollingUp`\n * is correct, set the lastScrollTop to the ignored event.\n */\n lastScrollTop = ignoreScrollToTop;\n }\n setIsNearBottom(state.isNearBottom);\n /**\n * Scroll events may come before a ResizeObserver event,\n * so in order to ignore resize events correctly we use a\n * timeout.\n *\n * @see https://github.com/WICG/resize-observer/issues/25#issuecomment-248757228\n */\n setTimeout(() => {\n /**\n * When theres a resize difference ignore the resize event.\n */\n if (state.resizeDifference || scrollTop === ignoreScrollToTop) {\n return;\n }\n if (isSelecting()) {\n setEscapedFromLock(true);\n setIsAtBottom(false);\n return;\n }\n const isScrollingDown = scrollTop > lastScrollTop;\n const isScrollingUp = scrollTop < lastScrollTop;\n if (state.animation?.ignoreEscapes) {\n state.scrollTop = lastScrollTop;\n return;\n }\n if (isScrollingUp) {\n setEscapedFromLock(true);\n setIsAtBottom(false);\n }\n if (isScrollingDown) {\n setEscapedFromLock(false);\n }\n if (!state.escapedFromLock && state.isNearBottom) {\n setIsAtBottom(true);\n }\n }, 1);\n }, [setEscapedFromLock, setIsAtBottom, isSelecting, state]);\n const handleWheel = useCallback(({ target, deltaY }) => {\n let element = target;\n while (![\"scroll\", \"auto\"].includes(getComputedStyle(element).overflow)) {\n if (!element.parentElement) {\n return;\n }\n element = element.parentElement;\n }\n /**\n * The browser may cancel the scrolling from the mouse wheel\n * if we update it from the animation in meantime.\n * To prevent this, always escape when the wheel is scrolled up.\n */\n if (element === scrollRef.current &&\n deltaY < 0 &&\n scrollRef.current.scrollHeight > scrollRef.current.clientHeight &&\n !state.animation?.ignoreEscapes) {\n setEscapedFromLock(true);\n setIsAtBottom(false);\n }\n }, [setEscapedFromLock, setIsAtBottom, state]);\n const scrollRef = useRefCallback((scroll) => {\n scrollRef.current?.removeEventListener(\"scroll\", handleScroll);\n scrollRef.current?.removeEventListener(\"wheel\", handleWheel);\n scroll?.addEventListener(\"scroll\", handleScroll, { passive: true });\n scroll?.addEventListener(\"wheel\", handleWheel, { passive: true });\n }, []);\n const contentRef = useRefCallback((content) => {\n state.resizeObserver?.disconnect();\n if (!content) {\n return;\n }\n let previousHeight;\n state.resizeObserver = new ResizeObserver(([entry]) => {\n const { height } = entry.contentRect;\n const difference = height - (previousHeight ?? height);\n state.resizeDifference = difference;\n /**\n * Sometimes the browser can overscroll past the target,\n * so check for this and adjust appropriately.\n */\n if (state.scrollTop > state.targetScrollTop) {\n state.scrollTop = state.targetScrollTop;\n }\n setIsNearBottom(state.isNearBottom);\n if (difference >= 0) {\n /**\n * If it's a positive resize, scroll to the bottom when\n * we're already at the bottom.\n */\n const animation = mergeAnimations(optionsRef.current, previousHeight\n ? optionsRef.current.resize\n : optionsRef.current.initial);\n scrollToBottom({\n animation,\n wait: true,\n preserveScrollPosition: true,\n duration: animation === \"instant\" ? undefined : RETAIN_ANIMATION_DURATION_MS,\n });\n }\n else {\n /**\n * Else if it's a negative resize, check if we're near the bottom\n * if we are want to un-escape from the lock, because the resize\n * could have caused the container to be at the bottom.\n */\n if (state.isNearBottom) {\n setEscapedFromLock(false);\n setIsAtBottom(true);\n }\n }\n previousHeight = height;\n /**\n * Reset the resize difference after the scroll event\n * has fired. Requires a rAF to wait for the scroll event,\n * and a setTimeout to wait for the other timeout we have in\n * resizeObserver in case the scroll event happens after the\n * resize event.\n */\n requestAnimationFrame(() => {\n setTimeout(() => {\n if (state.resizeDifference === difference) {\n state.resizeDifference = 0;\n }\n }, 1);\n });\n });\n state.resizeObserver?.observe(content);\n }, []);\n return {\n contentRef,\n scrollRef,\n scrollToBottom,\n stopScroll,\n isAtBottom: isAtBottom || isNearBottom,\n isNearBottom,\n escapedFromLock,\n state,\n };\n};\nfunction useRefCallback(callback, deps) {\n // biome-ignore lint/correctness/useExhaustiveDependencies: not needed\n const result = useCallback((ref) => {\n result.current = ref;\n return callback(ref);\n }, deps);\n return result;\n}\nconst animationCache = new Map();\nfunction mergeAnimations(...animations) {\n const result = { ...DEFAULT_SPRING_ANIMATION };\n let instant = false;\n for (const animation of animations) {\n if (animation === \"instant\") {\n instant = true;\n continue;\n }\n if (typeof animation !== \"object\") {\n continue;\n }\n instant = false;\n result.damping = animation.damping ?? result.damping;\n result.stiffness = animation.stiffness ?? result.stiffness;\n result.mass = animation.mass ?? result.mass;\n }\n const key = JSON.stringify(result);\n if (!animationCache.has(key)) {\n animationCache.set(key, Object.freeze(result));\n }\n return instant ? \"instant\" : animationCache.get(key);\n}\n","/*!---------------------------------------------------------------------------------------------\n * Copyright (c) StackBlitz. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nimport * as React from \"react\";\nimport { createContext, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, } from \"react\";\nimport { useStickToBottom, } from \"./useStickToBottom.js\";\nconst StickToBottomContext = createContext(null);\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\nexport function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {\n const customTargetScrollTop = useRef(null);\n const targetScrollTop = React.useCallback((target, elements) => {\n const get = context?.targetScrollTop ?? currentTargetScrollTop;\n return get?.(target, elements) ?? target;\n }, [currentTargetScrollTop]);\n const defaultInstance = useStickToBottom({\n mass,\n damping,\n stiffness,\n resize,\n initial,\n targetScrollTop,\n });\n const { scrollRef, contentRef, scrollToBottom, stopScroll, isAtBottom, escapedFromLock, state, } = instance ?? defaultInstance;\n const context = useMemo(() => ({\n scrollToBottom,\n stopScroll,\n scrollRef,\n isAtBottom,\n escapedFromLock,\n contentRef,\n state,\n get targetScrollTop() {\n return customTargetScrollTop.current;\n },\n set targetScrollTop(targetScrollTop) {\n customTargetScrollTop.current = targetScrollTop;\n },\n }), [\n scrollToBottom,\n isAtBottom,\n contentRef,\n scrollRef,\n stopScroll,\n escapedFromLock,\n state,\n ]);\n useImperativeHandle(contextRef, () => context, [context]);\n useIsomorphicLayoutEffect(() => {\n if (!scrollRef.current) {\n return;\n }\n if (getComputedStyle(scrollRef.current).overflow === \"visible\") {\n scrollRef.current.style.overflow = \"auto\";\n }\n }, []);\n return (React.createElement(StickToBottomContext.Provider, { value: context },\n React.createElement(\"div\", { ...props }, typeof children === \"function\" ? children(context) : children)));\n}\n(function (StickToBottom) {\n function Content({ children, scrollClassName, ...props }) {\n const context = useStickToBottomContext();\n return (React.createElement(\"div\", { ref: context.scrollRef, style: {\n height: \"100%\",\n width: \"100%\",\n scrollbarGutter: \"stable both-edges\",\n }, className: scrollClassName },\n React.createElement(\"div\", { ...props, ref: context.contentRef }, typeof children === \"function\" ? children(context) : children)));\n }\n StickToBottom.Content = Content;\n})(StickToBottom || (StickToBottom = {}));\n/**\n * Use this hook inside a <StickToBottom> component to gain access to whether the component is at the bottom of the scrollable area.\n */\nexport function useStickToBottomContext() {\n const context = useContext(StickToBottomContext);\n if (!context) {\n throw new Error(\"use-stick-to-bottom component context must be used within a StickToBottom component\");\n }\n return context;\n}\n","import {\n getTextContent,\n isHiddenInternalMessage,\n normalizeMessageContent,\n type ChatMessage,\n type SessionTurnIndexItem,\n type TurnProjection,\n} from \"@blade-hq/agent-client/internal\"\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\"\n\nconst HIGHLIGHT_MS = 1600\n/** 高亮用的类名。样式在 agent-react 的 style.css 与内置 Web 的 app.css 各有一份。 */\nexport const TURN_NAV_HIGHLIGHT_CLASS = \"blade-turn-nav-flash\"\nconst MAX_FRAMES_AFTER_LOCATE = 20\nconst LOCATE_FAILED_MESSAGE = \"没能定位到这条发言,请重试。\"\nconst LOCATE_OFFSCREEN_MESSAGE = \"已加载到这条发言所在的历史,但没能滚动到它,请重试。\"\nconst TURN_TITLE_MAX_LEN = 80\n\nfunction prefersReducedMotion(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n )\n}\n\nfunction nextFrame(): Promise<void> {\n return new Promise((resolve) => {\n if (typeof window === \"undefined\" || typeof window.requestAnimationFrame !== \"function\") {\n resolve()\n return\n }\n window.requestAnimationFrame(() => resolve())\n })\n}\n\ntype HighlightTimer = ReturnType<typeof setTimeout>\n\n/**\n * 消息导航的数据源:宿主把\"目录从哪来\"\"定位怎么发\"接给共享时序。\n *\n * SDK 的 AgentChat 用 `AgentSession.loadTurnIndex` / `locateEntry`;内置 Web 用\n * 自己的 store。没有会话目录的宿主(例如分享页)只传 `locateEntry` 与兜底条目。\n */\n/** 刻度轨的一条:稳定 entry id + 标题。内置 Web 的同名类型形状一致。 */\nexport interface TurnNavItem {\n id: string\n title: string\n}\n\nexport interface TurnNavigationSource {\n /** 目录来源;不传就不请求目录,导航条目只由 `fallbackItems` 兜底。 */\n loadTurnIndex?: () => Promise<SessionTurnIndexItem[]>\n /** 定位:服务端返回\"从这条发言到最新\"的窗口并整窗替换。成功返回 true。 */\n locateEntry: (entryId: string) => Promise<boolean>\n /**\n * 取消在途定位。每次新的选择都会先调它每次新的选择都会先调它:用户改点一条**已加载**的发言时不发定位请求,\n * 前一次在途的定位却已经发出去了——不取消的话它晚回来照样换窗口,把用户刚选中的\n * 那一段换掉。\n */\n cancelPendingLocate?: () => void\n /**\n * 目录刷新信号:会话里最新的用户发言变了(新发言、乐观发言被服务端确认)。\n *\n * 只认**最新一条**发言:往上翻页会补进更早的发言,用\"窗口里全部发言\"当信号的话,\n * 正在进行的定位会被自己触发的刷新作废——翻页成功了却不滚动,要再点一次。\n */\n reloadKey?: number | string | null\n /**\n * timeline 被**外部**整体重写(rewind / checkout / 修复重载)时变化。与 `reloadKey`\n * 的区别是语义:`reloadKey` 变化只是「可能变了」,刷新期间先照旧显示;这里变化一定是\n * 旧目录作废,旧条目必须立刻丢掉——它们的 entry id 可能已经不在 timeline 上了。\n *\n * 必须只由外部改写推进:定位自己换窗口同样会推进\"窗口世代\",拿它当信号会把正在进行的\n * 那次定位当场作废(点了没反应,要再点一次)。内置 Web 用 store 的\n * `historyRewriteRevision`,SDK 用会话的 `rewind` 事件。\n */\n rewriteKey?: number | string | null\n /**\n * 目录拿不到时的兜底条目。\n *\n * 分享页的历史本来就是整份加载的:它没有会话目录接口,导航条目直接由已加载的\n * 发言推出来。这只覆盖\"整份都在窗口里\"的场景,长会话不能拿它代替目录。\n */\n fallbackItems?: TurnNavItem[]\n}\n\n/** 共享时序还要知道\"怎么在宿主自己的列表里找到那一行\"。 */\nexport interface TurnNavigationOptions extends TurnNavigationSource {\n /** 当前会话;变了就丢弃在途的定位结果、目录和高亮。 */\n sessionId?: string | null\n /** 已加载窗口里该发言的行;不在当前列表里返回 null。 */\n getLoadedEntryElement: (entryId: string) => HTMLElement | null\n /**\n * 这条发言在不在已加载窗口里(哪怕它的行因为虚拟列表还没挂出来)。\n *\n * 没有它就只能拿\"DOM 里有没有这一行\"当\"加载没加载\":长会话里滚出挂载范围的旧发言\n * 会被当成窗口外,白白发一次定位请求(分享页更糟——那里根本没有定位接口)。不传则\n * 退回只看 DOM。\n */\n isEntryLoaded?: (entryId: string) => boolean\n /**\n * 已加载但还没进 DOM 的行(虚拟列表)——让宿主先把目标挂出来,下一帧\n * `getLoadedEntryElement` 就能查到。宿主没有虚拟列表时不用传。\n */\n revealEntry?: (entryId: string) => void\n /**\n * 开始定位前的一次性钩子:宿主在这里放弃自己的滚动控制(新轮置顶动画、\n * 「跟随到底」),否则它们会继续写 `scrollTop`,把视口从目标行上拽走。\n */\n beforeSeek?: (entryId: string) => void\n}\n\n/**\n * 目录刷新信号:窗口里**最后一条**用户发言的稳定 id。\n *\n * 与内置 Web 的 `latestUserSpeechEntryId`(message-list-blocks.ts)同一判据、同一\n * 名称,输入不同:那边拿渲染好的消息,这边拿投影轮。两边都只认\"最新一条\",因为\n * 往前翻页补进的更早发言不改变目录的结尾,用\"窗口里全部发言\"当信号会把正在进行的\n * 定位判成过期。\n *\n * AskUserQuestion 的回答在消息列表里也渲染成用户发言,所以带回答标记的轮同样算一条。\n */\nexport function latestUserSpeechEntryId(turns: TurnProjection[]): string | null {\n for (let index = turns.length - 1; index >= 0; index -= 1) {\n const turn = turns[index]\n if (turn.loop_id !== \"root\") continue\n if (turn.role === \"user\") return turn.turn_id\n if (turn.blocks.some((block) => block.type === \"ask_user_answer\")) return turn.turn_id\n }\n return null\n}\n\n/**\n * 从已加载的消息推出轨道条目:给没有目录接口的宿主(分享页、静态会话)兜底。\n *\n * 判据与内置 Web 的 `MessageList` 一致:根循环里渲染成用户发言的消息、排除内部提示,\n * 标题按服务端目录同一口径截断。**不能**拿它代替长会话的目录——窗口里没有更早的发言。\n */\nexport function turnNavItemsFromMessages(messages: ChatMessage[]): TurnNavItem[] {\n const items: TurnNavItem[] = []\n for (const message of messages) {\n if ((message.loop_name ?? \"root\") !== \"root\") continue\n if (message.role !== \"user\" || !message.entry_id) continue\n if (isHiddenInternalMessage(message)) continue\n const text = getTextContent(normalizeMessageContent(message.content)).trim()\n items.push({\n id: message.entry_id,\n title: text.length > TURN_TITLE_MAX_LEN ? `${text.slice(0, TURN_TITLE_MAX_LEN)}…` : text,\n })\n }\n return items\n}\n\nexport interface TurnNavigationResult {\n /** 当前会话的用户发言目录。 */\n items: TurnNavItem[]\n /** 正在请求定位的那条发言;请求结束就清空。 */\n loadingEntryId: string | null\n /** 上一条定位失败的提示;点下一条时清空。 */\n error: string | null\n /** 定位失败的那条发言:重试就是再点它一次。 */\n failedEntryId: string | null\n /** 最后一条被定位(或正在定位)的发言,用来给刻度轨选中态。 */\n activeEntryId: string | null\n selectEntry: (entryId: string) => void\n}\n\n/**\n * 用户发言的跨页定位:滚动、加载状态、高亮三件事的唯一实现,内置 Web 与 SDK\n * 共用同一份时序。\n *\n * 点已加载的发言:不请求任何东西,直接滚动 + 高亮。点窗口外的发言:发一次定位请求\n * (服务端返回\"从它到最新\"的窗口),等 React 提交、目标行挂出来再滚动 + 高亮;\n * 请求失败或行始终没出现就报一句可重试的提示,**不动滚动位置**。\n *\n * 会话切换、历史被整体重写、或用户点了下一条时,在途结果一律丢弃。\n */\nexport function useTurnNavigation({\n sessionId,\n getLoadedEntryElement,\n isEntryLoaded,\n locateEntry,\n cancelPendingLocate,\n loadTurnIndex,\n fallbackItems,\n revealEntry,\n beforeSeek,\n reloadKey,\n rewriteKey,\n}: TurnNavigationOptions): TurnNavigationResult {\n const callbacks = useRef({\n getLoadedEntryElement,\n isEntryLoaded,\n locateEntry,\n cancelPendingLocate,\n loadTurnIndex,\n revealEntry,\n beforeSeek,\n })\n\n\n const [index, setIndex] = useState<{\n sessionId: string | null\n items: TurnNavItem[]\n }>({ sessionId: null, items: [] })\n const [loadingEntryId, setLoadingEntryId] = useState<string | null>(null)\n const [activeEntryId, setActiveEntryId] = useState<string | null>(null)\n const [failedEntryId, setFailedEntryId] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [indexRefresh, setIndexRefresh] = useState(0)\n\n const seekSeq = useRef(0)\n const indexSeq = useRef(0)\n const indexRef = useRef<{ sessionId: string | null; items: TurnNavItem[] }>({\n sessionId: null,\n items: [],\n })\n const highlightTimer = useRef<HighlightTimer | undefined>(undefined)\n const highlightedRef = useRef<HTMLElement | null>(null)\n\n const clearHighlight = useCallback(() => {\n clearTimeout(highlightTimer.current)\n highlightTimer.current = undefined\n highlightedRef.current?.classList.remove(TURN_NAV_HIGHLIGHT_CLASS)\n highlightedRef.current = null\n }, [])\n\n useEffect(\n () => () => {\n seekSeq.current += 1\n indexSeq.current += 1\n callbacks.current.cancelPendingLocate?.()\n },\n [],\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: sessionId / rewriteKey 不是 effect 里读的值,而是\"换命了\"的信号。\n useLayoutEffect(() => {\n seekSeq.current += 1\n indexSeq.current += 1\n indexRef.current = { sessionId: null, items: [] }\n setIndex({ sessionId: null, items: [] })\n setLoadingEntryId(null)\n setFailedEntryId(null)\n setError(null)\n setActiveEntryId(null)\n clearHighlight()\n callbacks.current.cancelPendingLocate?.()\n return clearHighlight\n }, [sessionId, rewriteKey, clearHighlight])\n\n useLayoutEffect(() => {\n callbacks.current = {\n getLoadedEntryElement,\n isEntryLoaded,\n locateEntry,\n cancelPendingLocate,\n loadTurnIndex,\n revealEntry,\n beforeSeek,\n }\n })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: reloadKey / rewriteKey / indexRefresh 不是 effect 里读的值,而是「目录该重拉了」的信号。\n useEffect(() => {\n const load = callbacks.current.loadTurnIndex\n indexSeq.current += 1\n const seq = indexSeq.current\n const owner = sessionId ?? null\n if (!load || sessionId == null) {\n indexRef.current = { sessionId: owner, items: [] }\n setIndex({ sessionId: owner, items: [] })\n return\n }\n const keep = indexRef.current.sessionId === sessionId ? indexRef.current.items : []\n setIndex({ sessionId, items: keep })\n load()\n .then((items) => {\n if (seq !== indexSeq.current) return\n const navItems = items.map((item) => ({ id: item.entryId, title: item.preview }))\n indexRef.current = { sessionId, items: navItems }\n setIndex({ sessionId, items: navItems })\n })\n .catch(() => {\n if (seq !== indexSeq.current) return\n setIndex({ sessionId, items: keep })\n })\n }, [sessionId, reloadKey, rewriteKey, indexRefresh])\n\n const flashEntry = useCallback(\n (element: HTMLElement) => {\n clearHighlight()\n element.classList.add(TURN_NAV_HIGHLIGHT_CLASS)\n highlightedRef.current = element\n highlightTimer.current = setTimeout(() => {\n element.classList.remove(TURN_NAV_HIGHLIGHT_CLASS)\n if (highlightedRef.current === element) highlightedRef.current = null\n }, HIGHLIGHT_MS)\n element.scrollIntoView({\n behavior: prefersReducedMotion() ? \"auto\" : \"smooth\",\n block: \"center\",\n })\n },\n [clearHighlight],\n )\n\n const selectEntry = useCallback(\n (entryId: string) => {\n seekSeq.current += 1\n const seq = seekSeq.current\n setError(null)\n setFailedEntryId(null)\n setLoadingEntryId(null)\n callbacks.current.cancelPendingLocate?.()\n setActiveEntryId(entryId)\n callbacks.current.beforeSeek?.(entryId)\n\n const loaded = callbacks.current.getLoadedEntryElement(entryId)\n if (loaded) {\n flashEntry(loaded)\n return\n }\n\n const seek = async () => {\n if (callbacks.current.isEntryLoaded?.(entryId)) {\n for (let frame = 0; frame < MAX_FRAMES_AFTER_LOCATE; frame += 1) {\n callbacks.current.revealEntry?.(entryId)\n await nextFrame()\n if (seq !== seekSeq.current) return\n const element = callbacks.current.getLoadedEntryElement(entryId)\n if (element) {\n flashEntry(element)\n return\n }\n }\n setFailedEntryId(entryId)\n setError(LOCATE_OFFSCREEN_MESSAGE)\n return\n }\n\n if (seq !== seekSeq.current) return\n setLoadingEntryId(entryId)\n let located = false\n try {\n located = await callbacks.current.locateEntry(entryId)\n } catch {\n located = false\n }\n if (seq !== seekSeq.current) return\n if (!located) {\n setLoadingEntryId(null)\n setFailedEntryId(entryId)\n setError(LOCATE_FAILED_MESSAGE)\n setIndexRefresh((current) => current + 1)\n return\n }\n for (let frame = 0; frame < MAX_FRAMES_AFTER_LOCATE; frame += 1) {\n const element = callbacks.current.getLoadedEntryElement(entryId)\n if (element) {\n setLoadingEntryId(null)\n flashEntry(element)\n return\n }\n callbacks.current.revealEntry?.(entryId)\n await nextFrame()\n if (seq !== seekSeq.current) return\n }\n setLoadingEntryId(null)\n setFailedEntryId(entryId)\n setError(LOCATE_OFFSCREEN_MESSAGE)\n setIndexRefresh((current) => current + 1)\n }\n void seek()\n },\n [flashEntry],\n )\n\n return {\n // 目录按会话归属:切会话 / timeline 重写后的那一帧(作废 effect 还没跑)不能拿\n // 上一份目录画轨道,否则列出来的是别的会话的发言,点下去还会拿旧 entry id 去定位。\n // 比的是**归一化后**的会话标识:没有 sessionId 的宿主(只给 fallbackItems 的静态接入方)\n // 记进来的也是 null,拿原始 undefined 比会永远不等、兜底条目一个都不显示。\n items:\n index.sessionId === (sessionId ?? null)\n ? index.items.length > 0\n ? index.items\n : (fallbackItems ?? [])\n : [],\n loadingEntryId,\n error,\n failedEntryId,\n activeEntryId,\n selectEntry,\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nconst REVEAL_INITIAL_CPS = 18\nconst REVEAL_MIN_CPS = 6\nconst REVEAL_MAX_CPS = 240\nconst REVEAL_DISPLAY_RATIO = 0.82\nconst REVEAL_EMA_ALPHA = 0.25\nconst REVEAL_MAX_ARRIVAL_GAP_MS = 1000\nconst REVEAL_CATCHUP_TIME_CONSTANT_MS = 400\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\n/** JS 字符串按 UTF-16 code unit 计数/切片——多数 emoji 之类的字符是一对\n * 高/低代理项拼成的,`advance` 按字符数推进时可能刚好落在这一对中间,\n * `.slice()` 切出来的末尾就是一个孤立的高代理项,浏览器只能显示成一个\n * 破损的替换字符,下一帧凑齐了才恢复正常——这一帧的显示不能停在这种\n * 半个字符的位置,宁可少显示一个字符,等下一帧把这一对代理项一起放出来。 */\nfunction clampToCodeUnitBoundary(text: string, length: number): number {\n if (length > 0 && length < text.length) {\n const codeUnit = text.charCodeAt(length - 1)\n if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) return length - 1\n }\n return length\n}\n\nfunction scheduleAnimationFrame(callback: (ts: number) => void): () => void {\n if (typeof window !== \"undefined\" && typeof window.requestAnimationFrame === \"function\") {\n const handle = window.requestAnimationFrame(callback)\n return () => window.cancelAnimationFrame(handle)\n }\n const handle = globalThis.setTimeout(() => callback(Date.now()), 33)\n return () => globalThis.clearTimeout(handle)\n}\n\nexport interface UseTypewriterRevealResult {\n /** 当前应该渲染的文字——被截断到\"已显示长度\",不是目标全文。 */\n displayedText: string\n /** 缓冲池是否还没追平目标全文;跟 isStreaming 做 || 判断输入框状态用。 */\n isRevealing: boolean\n /**\n * 立即把 displayedText 设成当前目标全文、取消播放循环——用户主动点了\n * 停止,或者这一路因为中断/出错结束时调用。到达的内容不能丢,只是不再\n * 需要\"看起来在打字\"这个动画效果。\n */\n flushNow: () => void\n}\n\ninterface RevealState {\n resetKey: string | null\n displayedText: string\n revealedLen: number\n isRevealing: boolean\n}\n\nfunction initialRevealState(targetText: string, isLive: boolean, resetKey: string | null): RevealState {\n const revealedLen = isLive ? 0 : targetText.length\n return {\n resetKey,\n displayedText: targetText.slice(0, revealedLen),\n revealedLen,\n isRevealing: false,\n }\n}\n\n/**\n * 打字机式显示节流:服务端到达速率天然不均匀(一次推 5 个字、一次推 20\n * 个字),直接原样渲染会显得忽快忽慢。按估算到达速度、留一个很小的固定\n * 滞后量匀速播放 targetText。\n *\n * 纯渲染层的本地播放状态,不触碰 AgentSession/chat-store 的任何内部状态——\n * 调用方从各自现有的、没有改动过的数据里取 targetText,这里只负责\"这一帧\n * 该显示到第几个字\"。\n *\n * @param targetText 当前已到达的完整(未截断)文本。\n * @param isLive 是否是真正的实时直播(不是历史加载 / rewind / replay)——\n * 非直播场景永远整段直接显示,这是\"流式与历史必须产生相同结果\"这条硬\n * 规则唯一允许的例外,只在真正的实时直播里生效。\n * @param resetKey 标识\"这是哪一段正在增长的内容\"(比如 turn_id 或者\n * `${turnId}:${blockIndex}`)——变化时说明换了一段全新的内容(比如上一个\n * block 已经交付完、轮到下一个 block 在长,或者切到了新的一轮),播放\n * 状态要重新从头开始,不能带着上一段的进度继续,否则会出现\"从上一段的\n * 长度往下掉\"这种回退闪烁。\n */\nexport function useTypewriterReveal(\n targetText: string,\n isLive: boolean,\n resetKey: string | null,\n): UseTypewriterRevealResult {\n const [state, setState] = useState<RevealState>(() => initialRevealState(targetText, isLive, resetKey))\n\n const targetTextRef = useRef(targetText)\n targetTextRef.current = targetText\n const revealedLenRef = useRef(state.revealedLen)\n const priorTargetLenRef = useRef(targetText.length)\n const emaCpsRef = useRef(REVEAL_INITIAL_CPS)\n const lastTickTsRef = useRef<number | null>(null)\n const lastArrivalTsRef = useRef<number | null>(null)\n const cancelRef = useRef<(() => void) | null>(null)\n\n const stopTicking = useCallback(() => {\n cancelRef.current?.()\n cancelRef.current = null\n }, [])\n\n const flushNow = useCallback(() => {\n stopTicking()\n revealedLenRef.current = targetTextRef.current.length\n priorTargetLenRef.current = targetTextRef.current.length\n setState((s) => ({ ...s, displayedText: targetTextRef.current, revealedLen: revealedLenRef.current, isRevealing: false }))\n }, [stopTicking])\n\n // 下面这几种情况需要立即(不等下一帧)生效:换了一段全新内容、非直播、\n // 或者这段内容还没显示过任何一个字。用 React 官方推荐的\"渲染期间调整\n // state\"模式而不是放进 useEffect——effect 要等这次渲染提交、下一个宏\n // 任务才跑,会让新内容先上屏成空白,下一帧才补上,出现一闪。渲染期间\n // 调用 setState 时 React 会在提交前用新值重新渲染,不会有这一闪。\n if (state.resetKey !== resetKey) {\n const next = initialRevealState(targetText, isLive, resetKey)\n revealedLenRef.current = next.revealedLen\n priorTargetLenRef.current = targetText.length\n emaCpsRef.current = REVEAL_INITIAL_CPS\n lastTickTsRef.current = null\n lastArrivalTsRef.current = null\n stopTicking()\n setState(next)\n } else if (!isLive) {\n if (state.revealedLen !== targetText.length || state.displayedText !== targetText) {\n revealedLenRef.current = targetText.length\n priorTargetLenRef.current = targetText.length\n stopTicking()\n setState((s) => ({ ...s, displayedText: targetText, revealedLen: targetText.length, isRevealing: false }))\n }\n } else if (state.revealedLen === 0 && targetText.length > 0) {\n revealedLenRef.current = targetText.length\n priorTargetLenRef.current = targetText.length\n setState((s) => ({ ...s, displayedText: targetText, revealedLen: targetText.length, isRevealing: false }))\n }\n\n // 真正的匀速追赶:目标全文继续增长、且已经显示过至少一个字——这部分本来\n // 就是异步、跨帧的动画,放在 effect 里没有\"渲染期间调整\"那种一闪的问题。\n //\n // tick 的实现放进 ref、调度效果不返回取消函数,是为了绕开一个真实复现过\n // 的竞态:这个效果原本以 targetText 作为依赖项,且 cleanup 无条件调用\n // stopTicking。服务端到达间隔一旦比一帧(~16ms)还密——多条 WS delta\n // 挤在相邻的宏任务里各自触发一次 store 更新和重渲染——后一次到达总会\n // 在前一次排的那个 requestAnimationFrame 真正触发之前,被这次 effect\n // 重跑的 cleanup 取消掉再重新排一个。只要到达速率一直快过一帧,这个\n // tick 就永远轮不上执行:displayedText 死死卡住不动,直到某次到达间隔\n // 恰好慢过一帧,才终于跑成一次——这时候 dt 已经攒了好几秒,一次性把\n // 积压内容大段追平,表现正是\"卡一下吐好多\"。\n //\n // 修法:调度效果只负责\"当前没有排队中的 tick、且还有内容没追平时,排一个\",\n // 不再因为 targetText 变化就取消已经排队、还没来得及执行的 tick——那个\n // tick 靠 targetTextRef 读最新内容,不需要被重新调度也能追上。真正的\n // 停止交给下面单独两个只在 isLive 变化/组件卸载时才触发的 effect。\n const tickRef = useRef<((ts: number) => void) | null>(null)\n tickRef.current = (ts: number) => {\n cancelRef.current = null\n const currentTargetLen = targetTextRef.current.length\n const dt = lastTickTsRef.current == null ? 16 : Math.max(1, ts - lastTickTsRef.current)\n const arrived = Math.max(0, currentTargetLen - priorTargetLenRef.current)\n if (arrived > 0) {\n if (lastArrivalTsRef.current != null) {\n const arrivalDt = Math.min(\n REVEAL_MAX_ARRIVAL_GAP_MS,\n Math.max(1, ts - lastArrivalTsRef.current),\n )\n const instantCps = (arrived / arrivalDt) * 1000\n emaCpsRef.current = emaCpsRef.current + REVEAL_EMA_ALPHA * (instantCps - emaCpsRef.current)\n }\n lastArrivalTsRef.current = ts\n }\n priorTargetLenRef.current = currentTargetLen\n lastTickTsRef.current = ts\n\n const cps = clamp(emaCpsRef.current, REVEAL_MIN_CPS, REVEAL_MAX_CPS)\n const paced = Math.round((cps * REVEAL_DISPLAY_RATIO * dt) / 1000)\n const backlog = Math.max(0, currentTargetLen - revealedLenRef.current)\n const catchUp = Math.ceil((backlog * dt) / REVEAL_CATCHUP_TIME_CONSTANT_MS)\n const advance = Math.max(1, paced, catchUp)\n revealedLenRef.current = Math.min(currentTargetLen, revealedLenRef.current + advance)\n const revealed = revealedLenRef.current >= currentTargetLen\n setState((s) => ({\n ...s,\n displayedText: targetTextRef.current.slice(\n 0,\n clampToCodeUnitBoundary(targetTextRef.current, revealedLenRef.current),\n ),\n revealedLen: revealedLenRef.current,\n isRevealing: !revealed,\n }))\n\n if (!revealed) {\n cancelRef.current = scheduleAnimationFrame((nextTs) => tickRef.current?.(nextTs))\n }\n }\n\n useEffect(() => {\n if (!isLive) return\n if (revealedLenRef.current === 0) return\n if (revealedLenRef.current >= targetText.length) return\n if (cancelRef.current != null) return\n\n setState((s) => (s.isRevealing ? s : { ...s, isRevealing: true }))\n cancelRef.current = scheduleAnimationFrame((ts) => tickRef.current?.(ts))\n }, [targetText, isLive])\n\n useEffect(() => {\n if (!isLive) stopTicking()\n }, [isLive, stopTicking])\n\n // 标签页切到后台时,浏览器会暂停/严重限流 requestAnimationFrame——内容其实\n // 还在正常从服务端到达,只是\"播放\"这个动作被浏览器挂起了,回来一看像是\n // \"卡住了\";就算恢复调度,积压的这一大段还是会按限速慢慢播,感觉必须一直\n // 盯着才正常。用户不在看的这段时间里播不播、播多快根本没有观众,没有理由\n // 让它按平时的速度慢慢追——标签页重新可见时直接整段贴平当前已到达内容,\n // 之后到达的新内容再正常进入播放。\n useEffect(() => {\n if (typeof document === \"undefined\") return\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"visible\") flushNow()\n }\n document.addEventListener(\"visibilitychange\", handleVisibilityChange)\n return () => document.removeEventListener(\"visibilitychange\", handleVisibilityChange)\n }, [flushNow])\n\n useEffect(() => stopTicking, [stopTicking])\n\n return { displayedText: state.displayedText, isRevealing: state.isRevealing, flushNow }\n}\n","import { CheckCircle2, ChevronRight, PencilLine, Play, Sparkles } from \"lucide-react\"\nimport { useMemo, useState } from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport type { ChatMessage } from \"@blade-hq/agent-client/internal\"\nimport { useChatEnvironment } from \"../runtime/environment\"\nimport { parsePlanMessages } from \"./parse-plan-messages\"\n\ninterface Props {\n messages: ChatMessage[]\n sessionStatus?: string\n onConfirmPlan?: (action: \"execute\" | \"revise\", text?: string) => void\n isHistorical?: boolean\n sessionId?: string\n}\n\ntype SummaryState =\n | { kind: \"complete\"; label: string }\n | { kind: \"failed\"; label: string }\n | { kind: \"interrupted\"; label: string }\n | { kind: \"progress\"; label: string; dots: string }\n\nexport function PlanSummaryCard({\n messages,\n sessionStatus,\n onConfirmPlan,\n isHistorical = false,\n sessionId,\n}: Props) {\n const data = useMemo(() => parsePlanMessages(messages), [messages])\n const openPlanPanelAction = useChatEnvironment().openPlanPanel\n const summaryState = useMemo(() => getSummaryState(data, sessionStatus), [data, sessionStatus])\n const stepCount = useMemo(() => countPlanSteps(data.plan), [data.plan])\n const isWaitingForInput = sessionStatus === \"waiting_for_input\"\n const canConfirm =\n Boolean(onConfirmPlan) &&\n isWaitingForInput &&\n data.lastPauseTool === \"ExitPlanMode\"\n\n const openPlanPanel = openPlanPanelAction && sessionId ? () => openPlanPanelAction(sessionId) : undefined\n\n return (\n <div className=\"flex w-full flex-col gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.55)] p-4\">\n <button\n type=\"button\"\n onClick={isHistorical ? undefined : openPlanPanel}\n disabled={isHistorical || !openPlanPanel}\n className=\"flex w-full flex-col gap-4 text-left transition-colors hover:text-[hsl(var(--foreground))]\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]\">\n <Sparkles size={12} />\n <span>规划摘要</span>\n </div>\n <div className=\"truncate text-base font-medium text-[hsl(var(--foreground))]\">\n {data.intent || \"当前规划\"}\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs\">\n {summaryState.kind === \"progress\" ? (\n <>\n <span className=\"rounded-full bg-[hsl(var(--accent))] px-2.5 py-1 text-[hsl(var(--foreground))]\">\n {summaryState.label}\n </span>\n <span className=\"font-mono tracking-[0.25em] text-[hsl(var(--muted-foreground))]\">\n {summaryState.dots}\n </span>\n </>\n ) : (\n <span\n className={cn(\n \"rounded-full px-2.5 py-1\",\n summaryState.kind === \"complete\" &&\n \"bg-[hsl(var(--primary)/0.12)] text-[hsl(var(--primary))]\",\n summaryState.kind === \"failed\" &&\n \"bg-[hsl(var(--destructive)/0.12)] text-[hsl(var(--destructive))]\",\n summaryState.kind === \"interrupted\" &&\n \"bg-[hsl(var(--swf-warning-soft))] text-[hsl(var(--swf-warning))]\",\n )}\n >\n {summaryState.label}\n </span>\n )}\n </div>\n </div>\n {!isHistorical && <ChevronRight\n size={16}\n className=\"mt-1 shrink-0 text-[hsl(var(--muted-foreground))]\"\n aria-hidden=\"true\"\n />}\n </div>\n\n {summaryState.kind === \"complete\" && (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]\">\n <span className=\"rounded-full border border-[hsl(var(--border))] px-2.5 py-1\">\n {data.selectedSkills.length} 个技能\n </span>\n <span className=\"rounded-full border border-[hsl(var(--border))] px-2.5 py-1\">\n {stepCount} 个步骤\n </span>\n {!isHistorical && <span className=\"inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))]\">\n <CheckCircle2 size={12} />\n 右侧查看详情\n </span>}\n </div>\n )}\n </button>\n\n {canConfirm && <PlanConfirmationPanel onConfirmPlan={onConfirmPlan} />}\n </div>\n )\n}\n\nfunction PlanConfirmationPanel({\n onConfirmPlan,\n}: {\n onConfirmPlan?: (action: \"execute\" | \"revise\", text?: string) => void\n}) {\n const [isEditing, setIsEditing] = useState(false)\n const [revisionText, setRevisionText] = useState(\"\")\n\n const submitRevision = () => {\n const trimmed = revisionText.trim()\n if (!trimmed) return\n onConfirmPlan?.(\"revise\", trimmed)\n setRevisionText(\"\")\n setIsEditing(false)\n }\n\n return (\n <div className=\"space-y-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background)/0.45)] p-3\">\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => onConfirmPlan?.(\"execute\")}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-[hsl(var(--primary))] px-3 py-2 text-sm font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90\"\n >\n <Play size={14} />\n 开始执行\n </button>\n <button\n type=\"button\"\n onClick={() => setIsEditing((value) => !value)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-[hsl(var(--border))] px-3 py-2 text-sm text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]\"\n >\n <PencilLine size={14} />\n 修改\n </button>\n </div>\n\n {isEditing && (\n <div className=\"space-y-2\">\n <textarea\n value={revisionText}\n onChange={(event) => setRevisionText(event.target.value)}\n placeholder=\"输入修改建议...\"\n className=\"min-h-24 w-full resize-y rounded-lg border border-[hsl(var(--border))] bg-transparent px-3 py-2 text-sm text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground))]\"\n />\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n disabled={!revisionText.trim()}\n onClick={submitRevision}\n className=\"rounded-lg bg-[hsl(var(--primary))] px-3 py-1.5 text-xs font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:opacity-30\"\n >\n 提交修改意见\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nfunction getSummaryState(\n data: ReturnType<typeof parsePlanMessages>,\n sessionStatus?: string,\n): SummaryState {\n if (sessionStatus === \"failed\") {\n return { kind: \"failed\", label: \"出错\" }\n }\n if (sessionStatus === \"interrupted\") {\n return { kind: \"interrupted\", label: \"已中断\" }\n }\n if (data.parseError) {\n return { kind: \"failed\", label: \"解析失败\" }\n }\n if (data.hasPlanContent || data.plan != null) {\n return { kind: \"complete\", label: \"已生成\" }\n }\n if (data.selectedSkills.length > 0) {\n return { kind: \"progress\", label: \"技能分析中\", dots: \"●●○\" }\n }\n if (data.searchResults.length > 0) {\n return { kind: \"progress\", label: \"技能发现中\", dots: \"●○○\" }\n }\n return { kind: \"progress\", label: \"规划准备中\", dots: \"○○○\" }\n}\n\nfunction countPlanSteps(plan: ReturnType<typeof parsePlanMessages>[\"plan\"]): number {\n if (!plan) return 0\n\n const countNode = (node: (typeof plan.root)[\"children\"][number] | typeof plan.root): number => {\n const children = Array.isArray(node.children) ? node.children : []\n return 1 + children.reduce((total, child) => total + countNode(child), 0)\n }\n\n if (plan.root.id === \"plan-root\") {\n const children = Array.isArray(plan.root.children) ? plan.root.children : []\n return children.reduce((total, child) => total + countNode(child), 0)\n }\n\n return countNode(plan.root)\n}\n","\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '→') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent\n atNewLine = false,\n hasContent = false,\n typeIndex,\n typeQuantity,\n typeList,\n type,\n flowIndent,\n blockIndent;\n\n if (state.listener !== null) {\n state.listener('open', state);\n }\n\n state.tag = null;\n state.anchor = null;\n state.kind = null;\n state.result = null;\n\n allowBlockStyles = allowBlockScalars = allowBlockCollections =\n CONTEXT_BLOCK_OUT === nodeContext ||\n CONTEXT_BLOCK_IN === nodeContext;\n\n if (allowToSeek) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"!<?> [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for !<?> tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn’t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out\n// c = flow-in ⇒ ns-plain-safe-in\n// c = block-key ⇒ ns-plain-safe-out\n// c = flow-key ⇒ ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” )\n// | ( /* An ns-char preceding */ “#” )\n// | ( “:” /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “\"”\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | “%” | “@” | “`”)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// • No ending newline => unaffected; already using strip \"-\" chomping.\n// • Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines—\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-”\n // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#”\n // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,”\n // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]”\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n","import { load } from \"js-yaml\"\nimport type { PlanNode } from \"./types\"\n\ninterface PlanStep {\n label: string\n skill?: string\n id?: string\n status?: string\n children?: PlanStep[]\n}\n\ninterface PlanDocument {\n title: string\n objective: string\n steps: PlanStep[]\n notes?: string[]\n}\n\ninterface ParsedPlanResult {\n plan: { root: PlanNode; notes: string[] } | null\n error: string | null\n}\n\nexport type PlanStatusMap = Record<string, PlanNode[\"status\"]>\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0\n}\n\nfunction isPlanStep(value: unknown): value is PlanStep {\n if (!value || typeof value !== \"object\") return false\n const step = value as Record<string, unknown>\n if (!isNonEmptyString(step.label)) return false\n if (\"skill\" in step && step.skill !== undefined && !isNonEmptyString(step.skill)) return false\n if (\"children\" in step && !Array.isArray(step.children)) return false\n\n const children = Array.isArray(step.children) ? step.children : []\n if (children.length > 0 && !isNonEmptyString(step.skill)) return false\n return children.every((child) => isPlanStep(child))\n}\n\nfunction isPlanDocument(value: unknown): value is PlanDocument {\n if (!value || typeof value !== \"object\") return false\n const doc = value as Record<string, unknown>\n if (!isNonEmptyString(doc.title) || !isNonEmptyString(doc.objective)) return false\n if (!Array.isArray(doc.steps) || doc.steps.length === 0) return false\n if (!doc.steps.every((step) => isPlanStep(step))) return false\n if (\"notes\" in doc) {\n if (!Array.isArray(doc.notes)) return false\n if (!doc.notes.every((note) => isNonEmptyString(note))) return false\n }\n return true\n}\n\nfunction getPlanDocumentError(value: unknown): string {\n if (!value || typeof value !== \"object\") return \"PLAN.yaml 顶层结构必须是对象\"\n\n const doc = value as Record<string, unknown>\n if (!isNonEmptyString(doc.title)) return \"PLAN.yaml 缺少非空 title\"\n if (!isNonEmptyString(doc.objective)) return \"PLAN.yaml 缺少非空 objective\"\n if (!Array.isArray(doc.steps) || doc.steps.length === 0) return \"PLAN.yaml 缺少非空 steps\"\n if (!doc.steps.every((step) => isPlanStep(step))) {\n return \"PLAN.yaml 步骤结构无效,请检查 label / skill / children\"\n }\n if (\"notes\" in doc) {\n if (!Array.isArray(doc.notes) || !doc.notes.every((note) => isNonEmptyString(note))) {\n return \"PLAN.yaml notes 必须是非空字符串列表\"\n }\n }\n return \"PLAN.yaml 结构无效\"\n}\n\nfunction toPlanStatus(value: unknown): PlanNode[\"status\"] {\n if (!isNonEmptyString(value)) return \"pending\"\n const normalized = value.trim().toLowerCase()\n return normalized === \"pending\" || normalized === \"running\" || normalized === \"done\" || normalized === \"failed\"\n ? normalized\n : \"pending\"\n}\n\nexport function parsePlanTree(content: string): { root: PlanNode; notes: string[] } | null {\n return parsePlanTreeResult(content).plan\n}\n\nexport function applyPlanStatusesById(root: PlanNode, statuses: PlanStatusMap): PlanNode {\n const nextStatus = statuses[root.id] ?? root.status\n const children = Array.isArray(root.children) ? root.children : []\n return {\n ...root,\n status: nextStatus,\n children: children.map((child) => applyPlanStatusesById(child, statuses)),\n }\n}\n\nexport function parsePlanTreeResult(content: string): ParsedPlanResult {\n if (!content.trim()) {\n return { plan: null, error: null }\n }\n\n let parsed: unknown\n try {\n parsed = load(content)\n } catch (error) {\n return {\n plan: null,\n error: error instanceof Error ? `PLAN.yaml YAML 语法错误:${error.message}` : \"PLAN.yaml YAML 语法错误\",\n }\n }\n\n if (!isPlanDocument(parsed)) {\n return { plan: null, error: getPlanDocumentError(parsed) }\n }\n\n const createNode = (step: PlanStep, depth: number, fallbackId: string): PlanNode => {\n const children = Array.isArray(step.children) ? step.children : []\n return {\n id: isNonEmptyString(step.id) ? step.id.trim() : fallbackId,\n label: step.label.trim(),\n skillRef: isNonEmptyString(step.skill) ? step.skill.trim() : null,\n status: toPlanStatus(step.status),\n children: children.map((child, index) => createNode(child, depth + 1, `${fallbackId}.${index + 1}`)),\n depth,\n }\n }\n\n const root: PlanNode = {\n id: \"plan-root\",\n label: parsed.title.trim(),\n skillRef: null,\n status: \"pending\",\n children: parsed.steps.map((step, index) => createNode(step, 1, `${index + 1}`)),\n depth: 0,\n }\n\n const notes = [parsed.objective.trim(), ...(parsed.notes ?? []).map((note) => note.trim())]\n\n return { plan: { root, notes }, error: null }\n}\n","import type { ChatMessage } from \"@blade-hq/agent-client/internal\"\nimport { parseAskUserQuestion } from \"../AskUserQuestionBlock\"\nimport { formatToolName } from \"../display-utils\"\nimport { applyPlanStatusesById, parsePlanTreeResult, type PlanStatusMap } from \"./parse-plan-tree\"\nimport type { PlanData, SkillInfo } from \"./types\"\n\nfunction resultAsString(result: unknown): string | null {\n if (typeof result === \"string\") return result\n return null\n}\n\nconst PAUSE_TOOLS = new Set([\"AskUserQuestion\", \"ExitPlanMode\"])\nconst READ_FILE_TOOLS = new Set([\"Read\"])\nconst PLAN_WRITE_TOOLS = new Set([\"Write\"])\nconst PLAN_EDIT_TOOLS = new Set([\"Edit\"])\n\nfunction isPlanYamlPath(value: unknown): value is string {\n return typeof value === \"string\" && (value === \"PLAN.yaml\" || value.endsWith(\"/PLAN.yaml\"))\n}\n\nfunction getToolPath(args: Record<string, unknown>): unknown {\n return args.file_path ?? args.path\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\nfunction applyReplaceEdit(\n content: string,\n oldText: string,\n newText: string,\n replaceAll: boolean,\n): string | null {\n if (!oldText) {\n return null\n }\n if (content.includes(oldText)) {\n return replaceAll ? content.split(oldText).join(newText) : content.replace(oldText, newText)\n }\n\n const pattern = oldText\n .split(/(\\s+)/u)\n .filter((part) => part.length > 0)\n .map((part) => (/\\s+/u.test(part) ? \"\\\\s+\" : escapeRegExp(part)))\n .join(\"\")\n if (!pattern) {\n return null\n }\n const matches = [...content.matchAll(new RegExp(pattern, \"gu\"))]\n if (matches.length !== 1) {\n return null\n }\n const match = matches[0]\n const start = match.index\n const end = start + match[0].length\n return `${content.slice(0, start)}${newText}${content.slice(end)}`\n}\n\nfunction getSkillId(payload: { skill_id?: string; name?: string } | null | undefined): string {\n if (!payload) {\n return \"\"\n }\n if (typeof payload.skill_id === \"string\" && payload.skill_id) {\n return payload.skill_id\n }\n if (typeof payload.name === \"string\" && payload.name) {\n return payload.name\n }\n return \"\"\n}\n\nfunction getSkillDisplayName(\n payload: { display_name?: string; skill_id?: string; name?: string } | null | undefined,\n): string | undefined {\n if (!payload || typeof payload.display_name !== \"string\") {\n return undefined\n }\n const displayName = payload.display_name.trim()\n if (!displayName) {\n return undefined\n }\n const skillId = getSkillId(payload)\n return displayName === skillId ? undefined : displayName\n}\n\nfunction parseModeChange(message: ChatMessage): { from: string; to: string } | null {\n if (message.kind !== \"mode_change\" || typeof message.content !== \"string\") {\n return null\n }\n try {\n const parsed = JSON.parse(message.content) as { from?: unknown; to?: unknown }\n if (typeof parsed.from === \"string\" && typeof parsed.to === \"string\") {\n return { from: parsed.from, to: parsed.to }\n }\n } catch {}\n return null\n}\n\nfunction isPlanningBoundaryMessage(message: ChatMessage): boolean {\n const modeChange = parseModeChange(message)\n if (!modeChange) {\n return false\n }\n return modeChange.to === \"planning\" || modeChange.from === \"planning\"\n}\n\n/**\n * Extract structured plan data from planning phase messages.\n *\n * Expects messages between planning-mode mode_change markers containing:\n * - ReadSkill tool calls (技能调研:成功结果 = 选定技能,歧义 candidates = 候选列表)\n * - Write tool call to PLAN.yaml with plan YAML\n */\nexport function parsePlanMessages(allMessages: ChatMessage[]): PlanData {\n const messages = Array.isArray(allMessages) ? allMessages : []\n let intent = \"\"\n for (const msg of messages) {\n if (!msg.tool_calls) continue\n const readSkillTc = msg.tool_calls.find((tc) => tc.name === \"ReadSkill\")\n if (readSkillTc) {\n try {\n intent = JSON.parse(readSkillTc.arguments).skill ?? \"\"\n } catch {}\n if (intent) break\n }\n }\n\n const plannerMsgs = messages.filter(\n (message) => !isPlanningBoundaryMessage(message),\n )\n const searchResults: SkillInfo[] = []\n const searchMap = new Map<string, SkillInfo>()\n const selectedSkills: SkillInfo[] = []\n const selectedSet = new Set<string>()\n const askQuestions: PlanData[\"askQuestions\"] = []\n const readFiles: PlanData[\"readFiles\"] = []\n let lastPauseTool: PlanData[\"lastPauseTool\"] = null\n let planContent = \"\"\n let planContentPriority = 0\n let latestStatuses: PlanStatusMap = {}\n\n const setPlanContent = (nextContent: unknown, priority: number) => {\n if (typeof nextContent !== \"string\" || !nextContent.trim()) {\n return\n }\n if (priority < planContentPriority) {\n return\n }\n planContent = nextContent\n planContentPriority = priority\n }\n\n const applyPlanEdit = (args: Record<string, unknown>) => {\n if (Array.isArray(args.edits)) {\n for (const rawEdit of args.edits) {\n if (!rawEdit || typeof rawEdit !== \"object\" || Array.isArray(rawEdit)) {\n continue\n }\n const edit = rawEdit as Record<string, unknown>\n const oldText = typeof edit.old_text === \"string\" ? edit.old_text : \"\"\n const newText = typeof edit.new_text === \"string\" ? edit.new_text : \"\"\n if (!planContent) {\n continue\n }\n planContent = applyReplaceEdit(planContent, oldText, newText, edit.all === true) ?? planContent\n }\n return\n }\n\n const oldString = typeof args.old_string === \"string\" ? args.old_string : \"\"\n const newString = typeof args.new_string === \"string\" ? args.new_string : \"\"\n if (!planContent || !oldString || !planContent.includes(oldString)) {\n return\n }\n planContent = planContent.replace(oldString, newString)\n }\n\n const maybeParsePlanStatus = (msg: ChatMessage) => {\n if (msg.kind !== \"plan_status\") return\n if (typeof msg.content !== \"string\" || !msg.content.trim()) return\n try {\n const data = JSON.parse(msg.content) as { plan_yaml?: unknown; statuses?: unknown }\n setPlanContent(data.plan_yaml, 3)\n if (data.statuses && typeof data.statuses === \"object\" && !Array.isArray(data.statuses)) {\n latestStatuses = Object.fromEntries(\n Object.entries(data.statuses)\n .filter((entry): entry is [string, string] => typeof entry[0] === \"string\" && typeof entry[1] === \"string\")\n .map(([stepId, status]) => [stepId, normalizePlanStatus(status)]),\n )\n }\n } catch {}\n }\n\n for (const msg of plannerMsgs) {\n maybeParsePlanStatus(msg)\n if (!msg.tool_calls) continue\n for (const tc of msg.tool_calls) {\n if (formatToolName(tc.name) === \"ReadSkill\" && resultAsString(tc.result)) {\n try {\n const data = JSON.parse(resultAsString(tc.result)!) as {\n skill_id?: string\n name?: string\n display_name?: string\n description?: string\n content?: string\n candidates?: Array<{\n skill_id?: string\n name?: string\n display_name?: string\n description?: string\n }>\n }\n if (Array.isArray(data.candidates)) {\n for (const r of data.candidates) {\n const skillId = getSkillId(r)\n if (!skillId || searchMap.has(skillId)) continue\n const skill: SkillInfo = {\n skillId,\n displayName: getSkillDisplayName(r),\n description: r.description ?? \"\",\n }\n searchMap.set(skillId, skill)\n searchResults.push(skill)\n }\n continue\n }\n const skillId = getSkillId(data)\n if (!skillId || selectedSet.has(skillId)) continue\n let existing = searchMap.get(skillId)\n if (!existing) {\n existing = {\n skillId,\n displayName: getSkillDisplayName(data),\n description: data.description ?? \"\",\n }\n searchMap.set(skillId, existing)\n searchResults.push(existing)\n }\n existing.displayName ??= getSkillDisplayName(data)\n existing.content = data.content\n existing.references = extractRefs(data.content ?? \"\")\n selectedSkills.push(existing)\n selectedSet.add(skillId)\n } catch {}\n }\n if (tc.name === \"AskUserQuestion\" && resultAsString(tc.result)) {\n const data = parseAskUserQuestion(resultAsString(tc.result))\n if (data) {\n askQuestions.push({ toolCallId: tc.id, data })\n }\n }\n if (READ_FILE_TOOLS.has(tc.name) && tc.arguments) {\n try {\n const args = JSON.parse(tc.arguments) as Record<string, unknown>\n const path = getToolPath(args)\n if (typeof path === \"string\" && path) {\n readFiles.push({ path, status: tc.status ?? \"done\" })\n }\n } catch {}\n }\n if (\n PLAN_WRITE_TOOLS.has(tc.name) &&\n tc.arguments &&\n tc.status === \"done\" &&\n !(typeof tc.result === \"string\" && tc.result.startsWith(\"错误\"))\n ) {\n try {\n const args = JSON.parse(tc.arguments) as {\n file_path?: unknown\n path?: unknown\n content?: unknown\n }\n if (isPlanYamlPath(getToolPath(args as Record<string, unknown>)) && typeof args.content === \"string\") {\n setPlanContent(args.content, 1)\n }\n } catch {}\n }\n if (\n PLAN_EDIT_TOOLS.has(tc.name) &&\n tc.arguments &&\n tc.status === \"done\" &&\n !(typeof tc.result === \"string\" && tc.result.startsWith(\"错误\"))\n ) {\n try {\n const args = JSON.parse(tc.arguments) as {\n file_path?: unknown\n path?: unknown\n old_string?: unknown\n new_string?: unknown\n }\n if (isPlanYamlPath(args.path) || isPlanYamlPath(args.file_path)) {\n applyPlanEdit(args as Record<string, unknown>)\n }\n } catch {}\n }\n if (PAUSE_TOOLS.has(tc.name) && tc.status === \"done\") {\n lastPauseTool = tc.name as PlanData[\"lastPauseTool\"]\n }\n if (tc.name === \"ExitPlanMode\" && resultAsString(tc.result)) {\n try {\n const data = JSON.parse(resultAsString(tc.result)!) as { plan?: unknown }\n setPlanContent(data.plan, 2)\n } catch {}\n }\n }\n }\n\n const { plan: parsedPlan, error: parseError } = parsePlanTreeResult(planContent)\n const plan =\n parsedPlan == null\n ? null\n : {\n ...parsedPlan,\n root: applyPlanStatusesById(parsedPlan.root, latestStatuses),\n }\n\n return {\n intent,\n searchResults,\n selectedSkills,\n plan,\n hasPlanContent: planContent.trim().length > 0,\n parseError,\n askQuestions,\n readFiles,\n lastPauseTool,\n }\n}\n\nfunction normalizePlanStatus(value: string): \"pending\" | \"running\" | \"done\" | \"failed\" {\n const normalized = value.trim().toLowerCase()\n return normalized === \"running\" || normalized === \"done\" || normalized === \"failed\"\n ? normalized\n : \"pending\"\n}\n\nfunction extractRefs(content: string): string[] {\n const seen = new Set<string>()\n const refs: string[] = []\n for (const m of content.matchAll(/\\[\\[([^\\]]+)\\]\\]/g)) {\n const ref = m[1].trim()\n if (ref && !seen.has(ref)) {\n seen.add(ref)\n refs.push(ref)\n }\n }\n return refs\n}\n","import type { ChatMessage } from \"@blade-hq/agent-client/internal\"\n\nfunction parseModeChange(message: ChatMessage): { from: string; to: string } | null {\n if (message.kind !== \"mode_change\" || typeof message.content !== \"string\") {\n return null\n }\n try {\n const parsed = JSON.parse(message.content) as { from?: unknown; to?: unknown }\n if (typeof parsed.from === \"string\" && typeof parsed.to === \"string\") {\n return { from: parsed.from, to: parsed.to }\n }\n } catch {}\n return null\n}\n\nfunction isPlanningEnter(message: ChatMessage): boolean {\n const modeChange = parseModeChange(message)\n return modeChange?.to === \"planning\"\n}\n\nfunction isPlanningExit(message: ChatMessage): boolean {\n const modeChange = parseModeChange(message)\n return modeChange?.from === \"planning\"\n}\n\nexport function extractLatestPlanMessages(messages: ChatMessage[]): ChatMessage[] {\n const safeMessages = Array.isArray(messages) ? messages : []\n let enterIndex = -1\n let exitIndex = -1\n\n for (let i = safeMessages.length - 1; i >= 0; i -= 1) {\n const message = safeMessages[i]\n if (isPlanningExit(message) && exitIndex === -1) {\n exitIndex = i\n continue\n }\n if (isPlanningEnter(message)) {\n enterIndex = i\n break\n }\n }\n\n if (enterIndex === -1) {\n return []\n }\n\n return safeMessages\n .slice(enterIndex + 1)\n .filter((message, offset) => {\n const absoluteIndex = enterIndex + 1 + offset\n if (isPlanningEnter(message) || isPlanningExit(message)) {\n return false\n }\n if (exitIndex !== -1 && absoluteIndex > exitIndex) {\n return message.kind === \"plan_status\"\n }\n return true\n })\n}\n\n/** Keep each card within its submission while retaining the phase's skill context. */\nexport function extractPlanMessagesForTurn(messages: ChatMessage[], turnLastMessage: ChatMessage): ChatMessage[] {\n const turnIndex = messages.indexOf(turnLastMessage)\n if (turnIndex === -1) return []\n let enterIndex = -1\n for (let index = turnIndex; index >= 0; index -= 1) {\n if (isPlanningEnter(messages[index])) {\n enterIndex = index\n break\n }\n }\n if (enterIndex === -1) return []\n\n const nextBoundaryIndex = messages.findIndex((message, index) =>\n index > turnIndex && (isPlanningEnter(message) || message.role === \"user\"),\n )\n const endIndex = nextBoundaryIndex === -1 ? messages.length : nextBoundaryIndex\n return extractLatestPlanMessages(messages.slice(enterIndex, endIndex))\n}\n","import { ArrowRight, Sparkles } from \"lucide-react\"\nimport type { ResultFeedback as SavedResultFeedback } from \"@blade-hq/agent-client/internal\"\nimport type { PostChatFollowup } from \"@blade-hq/agent-client/internal\"\nimport { useEffect, useRef } from \"react\"\nimport { useFollowupInteraction } from \"./followup-interaction\"\nimport { useComposerBridge } from \"./runtime/environment\"\nimport { FinalArtifactCards } from \"./FinalArtifactCards\"\nimport { ResultFeedback } from \"./ResultFeedback\"\n\ninterface Props {\n sessionId: string\n followup: PostChatFollowup | null\n isViewer: boolean\n savedFeedback?: SavedResultFeedback\n onFeedbackSaved?: (feedback: SavedResultFeedback) => void\n}\n\nexport function PostChatFollowupBlock({\n sessionId,\n followup,\n isViewer,\n savedFeedback,\n onFeedbackSaved,\n}: Props) {\n const composer = useComposerBridge(sessionId)\n const emit = useFollowupInteraction()\n const reportedSuggestions = useRef(false)\n const adopted = useRef(new Set<number>())\n const artifacts = followup?.final_artifacts ?? []\n const assistantEntryId = followup?.assistant_entry_id ?? \"\"\n const suggestionCount = followup?.suggestions.length ?? 0\n\n useEffect(() => {\n if (reportedSuggestions.current || suggestionCount === 0) return\n reportedSuggestions.current = true\n emit({ type: \"suggestions_shown\", sessionId, assistantEntryId, count: suggestionCount })\n }, [assistantEntryId, emit, sessionId, suggestionCount])\n\n if (\n !followup ||\n (!followup.recaption &&\n followup.suggestions.length === 0 &&\n artifacts.length === 0 &&\n !followup.feedback_eligible)\n )\n return null\n\n return (\n <div part=\"followup\" className=\"blade-chat-followup flex w-fit max-w-full flex-col gap-4 rounded-xl border border-[hsl(var(--border)/0.75)] bg-[hsl(var(--muted)/0.28)] px-3 py-3 sm:min-w-[340px] sm:max-w-[680px]\">\n {followup.recaption ? (\n <section aria-label=\"本轮小结\" className=\"flex flex-col gap-2\">\n <div className=\"mb-1 flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]\">\n <Sparkles size={14} aria-hidden=\"true\" />\n 本轮小结\n </div>\n <p className=\"text-[13px] leading-5 text-[hsl(var(--foreground)/0.9)]\">\n {followup.recaption}\n </p>\n {artifacts.length > 0 ? (\n <FinalArtifactCards\n artifacts={artifacts}\n sessionId={sessionId}\n assistantEntryId={assistantEntryId}\n />\n ) : null}\n </section>\n ) : null}\n {!followup.recaption && artifacts.length > 0 ? (\n <section aria-label=\"本轮小结\">\n <FinalArtifactCards\n artifacts={artifacts}\n sessionId={sessionId}\n assistantEntryId={assistantEntryId}\n />\n </section>\n ) : null}\n {followup.suggestions.length > 0 ? (\n <section className=\"flex flex-col items-start gap-1.5\" aria-label=\"下一步建议\">\n <div className=\"text-xs font-medium text-[hsl(var(--muted-foreground))]\">下一步可以</div>\n <div className=\"grid w-fit max-w-full gap-1.5 sm:max-w-[680px]\">\n {followup.suggestions.map((suggestion, suggestionIndex) => (\n <button\n key={suggestion}\n type=\"button\"\n disabled={isViewer}\n onClick={() => {\n if (!adopted.current.has(suggestionIndex)) {\n adopted.current.add(suggestionIndex)\n emit({ type: \"suggestion_adopted\", sessionId, assistantEntryId, suggestionIndex })\n }\n composer.appendText(suggestion, true)\n }}\n part=\"followup-action\"\n className=\"blade-chat-followup-action group flex w-full items-center gap-2.5 rounded-[14px] bg-[hsl(var(--muted)/0.62)] px-3.5 py-2 text-left text-[13px] font-normal leading-5 text-[hsl(var(--foreground)/0.92)] transition-colors hover:bg-[hsl(var(--muted)/0.88)] disabled:cursor-default disabled:opacity-60\"\n >\n <span className=\"min-w-0\">{suggestion}</span>\n <ArrowRight\n size={14}\n strokeWidth={1.75}\n className=\"ml-auto shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-hover:translate-x-0.5\"\n aria-hidden=\"true\"\n />\n </button>\n ))}\n </div>\n </section>\n ) : null}\n <ResultFeedback\n sessionId={sessionId}\n followup={followup}\n isViewer={isViewer}\n savedFeedback={savedFeedback}\n onSaved={onFeedbackSaved}\n />\n </div>\n )\n}\n","import { ArrowUpRight, ChevronDown, Globe } from \"lucide-react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport type { FinalArtifact } from \"@blade-hq/agent-client/internal\"\nimport { DeliveryCard } from \"./FileDeliveryCards\"\nimport { useBladeHost } from \"../context\"\nimport { useFollowupInteraction } from \"./followup-interaction\"\nimport { isLoopbackUrl } from \"./lib/loopback\"\n\nfunction basename(path: string): string {\n return path.split(\"/\").filter(Boolean).pop() || path\n}\n\nfunction hostOf(url: string): string {\n try {\n const parsed = new URL(url)\n return parsed.host || url\n } catch {\n return url\n }\n}\n\nfunction LinkCard({\n url,\n label,\n sessionId,\n onOpen,\n}: {\n url: string\n label: string\n sessionId: string\n onOpen: () => void\n}) {\n const bladeHost = useBladeHost()\n const host = hostOf(url)\n // 本机地址只有宿主能打开(内置 Web 用沙盒浏览器);宿主不支持时按普通链接打开\n const local = isLoopbackUrl(url) && Boolean(bladeHost.openPreview)\n const content = (\n <>\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center text-[hsl(var(--primary))]\">\n <Globe size={15} aria-hidden=\"true\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-xs font-medium leading-5\">{label || host}</span>\n </span>\n <ArrowUpRight\n size={13}\n className=\"absolute right-2 shrink-0 text-[hsl(var(--muted-foreground))] opacity-0 transition-[opacity,transform] group-hover/link:translate-x-0.5 group-hover/link:opacity-100 group-focus-visible/link:opacity-100\"\n aria-hidden=\"true\"\n />\n </>\n )\n\n if (local) {\n return (\n <button\n type=\"button\"\n onClick={() => {\n onOpen()\n void bladeHost.openPreview?.({ sessionId, url })\n }}\n data-artifact-kind=\"website\"\n className=\"group/link relative flex w-full max-w-full items-center gap-1.5 self-start rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] py-1.5 pl-2 pr-2.5 text-left text-[hsl(var(--card-foreground))] shadow-sm transition-colors hover:border-[hsl(var(--primary)/0.45)] hover:bg-[hsl(var(--accent)/0.45)] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n title={`${label || host}\\n${url}`}\n >\n {content}\n </button>\n )\n }\n\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={onOpen}\n data-artifact-kind=\"website\"\n className=\"group/link relative flex w-full max-w-full items-center gap-1.5 self-start rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] py-1.5 pl-2 pr-2.5 text-[hsl(var(--card-foreground))] shadow-sm transition-colors hover:border-[hsl(var(--primary)/0.45)] hover:bg-[hsl(var(--accent)/0.45)] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n title={`${label || host}\\n${url}`}\n >\n {content}\n </a>\n )\n}\n\n/** 会话小结里的产物卡片:本轮交付的文件和网址,点击直接打开。 */\nexport function FinalArtifactCards({\n artifacts,\n sessionId,\n assistantEntryId,\n}: {\n artifacts: FinalArtifact[]\n sessionId: string\n assistantEntryId: string\n}) {\n const [expanded, setExpanded] = useState(false)\n const hasMore = artifacts.length > 3\n const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3)\n const emit = useFollowupInteraction()\n const reportedShown = useRef(new Set<number>())\n const reportedOpened = useRef(new Set<number>())\n const visibleCount = visibleArtifacts.length\n\n useEffect(() => {\n for (let artifactIndex = 0; artifactIndex < visibleCount; artifactIndex += 1) {\n const artifact = artifacts[artifactIndex]\n if (!artifact || reportedShown.current.has(artifactIndex)) continue\n reportedShown.current.add(artifactIndex)\n emit({ type: \"artifact_shown\", sessionId, assistantEntryId, artifactIndex, artifactKind: artifact.kind })\n }\n }, [artifacts, assistantEntryId, emit, sessionId, visibleCount])\n\n const reportOpened = (artifactIndex: number, artifactKind: FinalArtifact[\"kind\"]) => {\n if (reportedOpened.current.has(artifactIndex)) return\n reportedOpened.current.add(artifactIndex)\n emit({ type: \"artifact_opened\", sessionId, assistantEntryId, artifactIndex, artifactKind })\n }\n const columnCount = Math.min(artifacts.length, 3)\n const gridWidth = columnCount * 180 + Math.max(0, columnCount - 1) * 6\n\n if (artifacts.length === 0) return null\n\n return (\n <div className=\"flex max-w-full flex-col gap-1.5\">\n <div\n style={{\n width: `min(100%, ${gridWidth}px)`,\n gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,\n }}\n className={\n expanded && hasMore\n ? \"grid max-h-[144px] max-w-full gap-1.5 overflow-y-auto pr-1\"\n : \"grid max-w-full gap-1.5\"\n }\n >\n {visibleArtifacts.map((artifact, artifactIndex) =>\n artifact.kind === \"link\" ? (\n <LinkCard\n key={`${artifact.kind}:${artifactIndex}`}\n url={artifact.target}\n label={artifact.label}\n sessionId={sessionId}\n onOpen={() => reportOpened(artifactIndex, \"link\")}\n />\n ) : (\n <DeliveryCard\n key={`${artifact.kind}:${artifactIndex}`}\n path={artifact.target}\n name={basename(artifact.target)}\n displayName={artifact.label || undefined}\n sessionId={sessionId}\n compact\n onOpen={() => reportOpened(artifactIndex, artifact.kind)}\n onDownloadStarted={() =>\n emit({ type: \"artifact_download_started\", sessionId, assistantEntryId, artifactIndex, artifactKind: \"file\" })\n }\n onDownloadSucceeded={() =>\n emit({ type: \"artifact_download_succeeded\", sessionId, assistantEntryId, artifactIndex, artifactKind: \"file\" })\n }\n />\n ),\n )}\n </div>\n {hasMore ? (\n <button\n type=\"button\"\n onClick={() => setExpanded((current) => !current)}\n className=\"flex w-fit items-center gap-0.5 text-[11px] leading-4 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none\"\n aria-expanded={expanded}\n >\n <span>{expanded ? \"收起\" : `展开 ${artifacts.length - 3} 个`}</span>\n <ChevronDown\n size={13}\n className={expanded ? \"rotate-180 transition-transform\" : \"transition-transform\"}\n aria-hidden=\"true\"\n />\n </button>\n ) : null}\n </div>\n )\n}\n","import { AlertTriangle } from \"lucide-react\"\nimport { Component, type ErrorInfo, type ReactNode } from \"react\"\n\ninterface Props {\n label: string\n details?: string\n resetKey?: string\n children: ReactNode\n}\n\ninterface State {\n componentStack: string\n error: Error | null\n}\n\nfunction getFirstComponentName(componentStack: string): string | null {\n const match = componentStack.match(/\\n\\s+at\\s+([^\\s(]+)/)\n return match?.[1] ?? null\n}\n\nexport class RenderErrorBoundary extends Component<Props, State> {\n state: State = {\n componentStack: \"\",\n error: null,\n }\n\n static getDerivedStateFromError(error: Error): State {\n return {\n componentStack: \"\",\n error,\n }\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n const componentStack = info.componentStack ?? \"\"\n console.error(`${this.props.label} render error:`, error, info)\n this.setState({ componentStack })\n }\n\n componentDidUpdate(prevProps: Props) {\n if (this.state.error && prevProps.resetKey !== this.props.resetKey) {\n this.setState({ componentStack: \"\", error: null })\n }\n }\n\n render() {\n const { children, details, label } = this.props\n const { componentStack, error } = this.state\n\n if (!error) {\n return children\n }\n\n const componentName = getFirstComponentName(componentStack)\n\n return (\n <div className=\"blade-chat-render-error rounded-xl border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-4 py-3 text-sm text-[hsl(var(--foreground))]\">\n <div className=\"flex items-start gap-2\">\n <AlertTriangle className=\"mt-0.5 h-4 w-4 shrink-0 text-[hsl(var(--swf-warning))]\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"font-medium\">{label}渲染失败</div>\n <div className=\"mt-1 break-words text-xs leading-5 text-[hsl(var(--secondary-foreground))]\">\n {componentName ? `组件:${componentName}。` : null}\n {error.message || \"发生了未预期的渲染错误。\"}\n </div>\n {details ? (\n <div className=\"mt-1 truncate text-xs text-[hsl(var(--muted-foreground))]\">{details}</div>\n ) : null}\n </div>\n </div>\n </div>\n )\n }\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\nexport interface TurnNavItem {\n id: string\n title: string\n}\n\ninterface TurnNavRailProps {\n items: TurnNavItem[]\n activeTurnId: string | null\n onSelectTurn: (turnId: string) => void\n loadingTurnId?: string | null\n error?: string | null\n failedTurnId?: string | null\n}\n\nconst PANEL_MAX_HEIGHT = 448\nconst PANEL_MARGIN = 16\n\nfunction clippingAncestor(element: HTMLElement | null): HTMLElement | null {\n for (let node = element?.parentElement ?? null; node; node = node.parentElement) {\n if (getComputedStyle(node).overflowY !== \"visible\") return node\n }\n return null\n}\n\nconst EDGE_ZONE = 0.3\nconst SPEED_PER_FRAME = 0.7\nconst ACCEL_PER_FRAME = 0.018\nconst EDGE_BOOST = 0.4\n\nexport function TurnNavRail({\n items,\n activeTurnId,\n onSelectTurn,\n loadingTurnId = null,\n error = null,\n failedTurnId = null,\n}: TurnNavRailProps) {\n const [hoveredTurnId, setHoveredTurnId] = useState<string | null>(null)\n const [panelOpen, setPanelOpen] = useState(false)\n const listRef = useRef<HTMLDivElement | null>(null)\n\n const markerRef = useRef<HTMLDivElement | null>(null)\n const edgeRatioRef = useRef(0.5)\n const velocityRef = useRef(0)\n const rafRef = useRef<number | null>(null)\n\n useEffect(() => {\n if (!panelOpen || hoveredTurnId == null) return\n const list = listRef.current\n if (!list) return\n const row = Array.from(list.querySelectorAll<HTMLElement>(\"[data-turn-id]\")).find(\n (el) => el.dataset.turnId === hoveredTurnId,\n )\n row?.scrollIntoView({ block: \"nearest\" })\n }, [panelOpen, hoveredTurnId])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: items 不是 effect 里读的值,而是\"目录变了\"的信号——全量目录异步到位时活动刻度会被挤到视口外,必须重新居中。(agent-react 那份轨道组件同样依赖这两个值。)\n useEffect(() => {\n const rail = markerRef.current\n if (!rail || !activeTurnId) return\n const activeEl = Array.from(rail.querySelectorAll<HTMLElement>(\"[data-nav-id]\")).find(\n (el) => el.dataset.navId === activeTurnId,\n )\n if (!activeEl) return\n const railHeight = rail.clientHeight\n const maxScroll = Math.max(0, rail.scrollHeight - railHeight)\n const railRect = rail.getBoundingClientRect()\n const elRect = activeEl.getBoundingClientRect()\n const elTop = elRect.top - railRect.top + rail.scrollTop\n const elHeight = elRect.height\n const target = Math.min(Math.max(0, elTop - (railHeight - elHeight) / 2), maxScroll)\n if (Math.abs(rail.scrollTop - target) > 1) {\n rail.scrollTo({ top: target, behavior: \"auto\" })\n }\n }, [activeTurnId, items])\n\n const clampPanel = useCallback(() => {\n const list = listRef.current\n const rail = markerRef.current\n const container = clippingAncestor(rail)\n if (!list || !container || !rail) return\n const containerRect = container.getBoundingClientRect()\n const railRect = rail.getBoundingClientRect()\n if (!railRect.height) return\n const center = railRect.top + railRect.height / 2\n const available =\n 2 * Math.min(center - containerRect.top, containerRect.bottom - center) - PANEL_MARGIN\n list.style.maxHeight =\n available > 0 ? `${Math.round(Math.min(available, PANEL_MAX_HEIGHT))}px` : \"\"\n }, [])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: items 只是\"目录变了,重新量一次\"的信号。\n useLayoutEffect(() => {\n if (!panelOpen) return\n clampPanel()\n }, [panelOpen, items, clampPanel])\n\n useEffect(() => {\n if (!panelOpen) return\n const container = clippingAncestor(markerRef.current)\n if (!container || typeof ResizeObserver === \"undefined\") return\n const observer = new ResizeObserver(() => clampPanel())\n observer.observe(container)\n return () => observer.disconnect()\n }, [panelOpen, clampPanel])\n\n const stopAutoScroll = useCallback(() => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n velocityRef.current = 0\n edgeRatioRef.current = 0.5\n }, [])\n\n const tick = useCallback(() => {\n const el = markerRef.current\n if (el) {\n const ratio = edgeRatioRef.current\n const inTop = ratio < EDGE_ZONE\n const inBottom = ratio > 1 - EDGE_ZONE\n const depth = inTop\n ? 1 - Math.min(1, Math.max(0, ratio)) / EDGE_ZONE\n : inBottom\n ? (Math.min(1, Math.max(0, ratio)) - (1 - EDGE_ZONE)) / EDGE_ZONE\n : 0\n const active = inTop || inBottom\n const target = active ? (inTop ? -1 : 1) * SPEED_PER_FRAME * (1 + depth * EDGE_BOOST) : 0\n velocityRef.current += Math.max(-ACCEL_PER_FRAME, Math.min(ACCEL_PER_FRAME, target - velocityRef.current))\n if (el.scrollHeight > el.clientHeight) {\n const maxTop = el.scrollHeight - el.clientHeight\n el.scrollTop += velocityRef.current\n if (el.scrollTop <= 0) {\n el.scrollTop = 0\n if (velocityRef.current < 0) velocityRef.current = 0\n } else if (el.scrollTop >= maxTop) {\n el.scrollTop = maxTop\n if (velocityRef.current > 0) velocityRef.current = 0\n }\n } else {\n velocityRef.current = 0\n }\n }\n rafRef.current = requestAnimationFrame(tick)\n }, [])\n\n const startAutoScroll = useCallback(() => {\n stopAutoScroll()\n rafRef.current = requestAnimationFrame(tick)\n }, [stopAutoScroll, tick])\n\n const handleMarkerMouseMove = useCallback((event: React.MouseEvent) => {\n const el = markerRef.current\n if (!el) return\n const rect = el.getBoundingClientRect()\n edgeRatioRef.current = Math.min(1, Math.max(0, (event.clientY - rect.top) / rect.height))\n }, [])\n\n useEffect(\n () => () => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n },\n [],\n )\n\n if (items.length < 2) {\n return null\n }\n\n return (\n <nav\n aria-label=\"回合导航\"\n className=\"absolute right-2 top-1/2 z-30 hidden -translate-y-1/2 md:block\"\n onMouseEnter={() => setPanelOpen(true)}\n onFocus={() => setPanelOpen(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setPanelOpen(false)\n }}\n onMouseLeave={() => {\n stopAutoScroll()\n setPanelOpen(false)\n setHoveredTurnId(null)\n }}\n >\n <div className=\"flex flex-col items-end\">\n <div\n ref={markerRef}\n onMouseEnter={startAutoScroll}\n onMouseMove={handleMarkerMouseMove}\n onMouseLeave={stopAutoScroll}\n className={cn(\n \"flex max-h-80 flex-col overflow-y-hidden py-1.5 pr-1.5\",\n )}\n style={{\n WebkitMaskImage:\n \"linear-gradient(to bottom, transparent, black 10%, black 90%, transparent)\",\n maskImage:\n \"linear-gradient(to bottom, transparent, black 10%, black 90%, transparent)\",\n }}\n >\n <span aria-hidden className=\"mt-auto shrink-0\" />\n {items.map((item, index) => {\n const isActive = item.id === activeTurnId\n\n return (\n <button\n key={item.id}\n type=\"button\"\n data-nav-id={item.id}\n onClick={() => onSelectTurn(item.id)}\n onMouseEnter={() => setHoveredTurnId(item.id)}\n aria-current={isActive ? \"true\" : undefined}\n aria-label={item.title || `第 ${index + 1} 轮`}\n className=\"flex h-3.5 shrink-0 items-center\"\n >\n <span\n className={cn(\n \"block rounded-full transition-colors\",\n isActive\n ? \"h-1 w-5 bg-[hsl(var(--foreground))]\"\n : cn(\n \"h-0.5 w-3 bg-[hsl(var(--muted-foreground)/0.35)]\",\n item.id === hoveredTurnId &&\n \"h-1 w-5 bg-[hsl(var(--muted-foreground)/0.7)]\",\n ),\n )}\n />\n </button>\n )\n })}\n <span aria-hidden className=\"mb-auto shrink-0\" />\n </div>\n {error ? (\n <div\n role=\"alert\"\n className=\"absolute right-full top-1/2 mr-2 flex -translate-y-1/2 items-center gap-2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]\"\n >\n <span>{error}</span>\n {failedTurnId ? (\n <button\n type=\"button\"\n className=\"cursor-pointer text-[hsl(var(--primary))] underline\"\n onClick={() => onSelectTurn(failedTurnId)}\n >\n 重试\n </button>\n ) : null}\n </div>\n ) : loadingTurnId ? (\n <output className=\"absolute right-full top-1/2 mr-2 -translate-y-1/2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]\">\n 正在定位到这条发言…\n </output>\n ) : null}\n {panelOpen ? (\n <div className=\"absolute right-full top-1/2 -translate-y-1/2 pr-2\">\n <div\n ref={listRef}\n className=\"flex max-h-[min(28rem,60vh)] w-80 flex-col overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]\"\n >\n {items.map((item, index) => {\n const isActive = item.id === activeTurnId\n const isHovered = item.id === hoveredTurnId\n\n return (\n <button\n key={item.id}\n type=\"button\"\n data-turn-id={item.id}\n onClick={() => onSelectTurn(item.id)}\n onMouseEnter={() => setHoveredTurnId(item.id)}\n className={cn(\n \"shrink-0 truncate px-3 py-1.5 text-left text-xs text-[hsl(var(--popover-foreground))] transition-colors\",\n isHovered\n ? \"bg-[hsl(var(--accent))]\"\n : isActive\n ? \"bg-[hsl(var(--accent)/0.5)]\"\n : \"hover:bg-[hsl(var(--accent))]\",\n )}\n >\n {item.title || `第 ${index + 1} 轮`}\n </button>\n )\n })}\n </div>\n </div>\n ) : null}\n </div>\n </nav>\n )\n}\n","export const ENTRY_SCROLL_MARGIN_PX = 24\n\nexport function calculateStickyAwareMargin(statusHeight = 0, statusBottomGap = 0) {\n return ENTRY_SCROLL_MARGIN_PX + Math.max(0, statusHeight) + Math.max(0, statusBottomGap)\n}\n\nexport function normalizeScrollEntryKey(value: string | null | undefined): string | null {\n const text = value?.trim()\n return text ? text : null\n}\n\nexport function calculateAnchoredScrollTop({\n scrollTop,\n containerTop,\n targetTop,\n margin = ENTRY_SCROLL_MARGIN_PX,\n}: {\n scrollTop: number\n containerTop: number\n targetTop: number\n margin?: number\n}) {\n return Math.max(0, scrollTop + targetTop - containerTop - margin)\n}\n\nexport function calculateTrailingSpacerHeight({\n targetScrollTop,\n scrollHeight,\n clientHeight,\n currentScrollTop = 0,\n}: {\n targetScrollTop: number\n scrollHeight: number\n clientHeight: number\n /** 当前滚动位置:空白不能收到把它挤出可滚动范围,否则浏览器会把页面拽回去。 */\n currentScrollTop?: number\n}) {\n // 与 agent-react/MessageList.tsx 保持同名同签名;这里不能先把负的可滚动\n // 高度夹成 0,否则内容不足一屏时会漏算“填满视口”所需的空白。\n //\n // 两处 +1:use-stick-to-bottom 内部把\"底部\"定义成\n // `scrollHeight - 1 - clientHeight`(见它源码 state.targetScrollTop 的\n // getter),比我们这里\"scrollHeight - clientHeight\"少 1px。我们把\n // scrollTop 钉在自己算出来的 targetScrollTop 上之后,它内部有个不受\n // isAtBottom 影响、每次内容 resize 都会跑一次的防御性 clamp\n // (`if (scrollTop > targetScrollTop) scrollTop = targetScrollTop`),\n // 少这 1px 就会让这个 clamp 每次都判定\"我们的位置比它认为的底部还低\",\n // 把 scrollTop 硬掰回去 1px,我们下一帧又纠正回来——高频的 ±1px 跳动,\n // 就是这次要修的那种\"抖动\"。多算这 1px 空白,让它自己算出来的\"底部\"\n // 跟我们的目标位置完全对齐,这个 clamp 就不会再触发。\n const anchorNeed = Math.max(0, targetScrollTop + clientHeight - scrollHeight + 1)\n const keepCurrentReachable = Math.max(0, currentScrollTop + clientHeight - scrollHeight + 1)\n return Math.max(anchorNeed, keepCurrentReachable)\n}\n\n/** 交还跟随时允许的位置误差:顶置落位有取整误差,太严格会漏掉正常情况。 */\nexport const PIN_HANDOVER_TOLERANCE_PX = 24\n\n/**\n * 尾部空白收完时是否把“跟随到底”交还给滚动库。\n * 只有用户还停在顶置位置(或更靠下)才交还;他自己往上翻去看前文时不打扰。\n */\nexport function shouldHandOverToFollow({\n currentScrollTop,\n targetScrollTop,\n tolerance = PIN_HANDOVER_TOLERANCE_PX,\n}: {\n currentScrollTop: number\n targetScrollTop: number\n tolerance?: number\n}) {\n return currentScrollTop >= targetScrollTop - tolerance\n}\n\nexport const NEW_TURN_SCROLL_DURATION_MS = 320\n/** 距离小于这个像素数时看不出动画,直接落位。 */\nexport const NEW_TURN_SCROLL_MIN_DISTANCE_PX = 8\n/** 距离超过这么多屏时直接跳过去:长距离滚动动画只会让人更晕。 */\nexport const NEW_TURN_SCROLL_MAX_SCREENS = 3\n/** 滚动位置偏离动画写入值超过这么多像素,就认定是用户在自己滚。 */\nexport const MANUAL_SCROLL_TOLERANCE_PX = 2\n\nexport function shouldAnimateNewTurnScroll({\n fromScrollTop,\n targetScrollTop,\n clientHeight,\n prefersReducedMotion = false,\n}: {\n fromScrollTop: number\n targetScrollTop: number\n clientHeight: number\n prefersReducedMotion?: boolean\n}) {\n if (prefersReducedMotion) return false\n const distance = Math.abs(targetScrollTop - fromScrollTop)\n if (distance < NEW_TURN_SCROLL_MIN_DISTANCE_PX) return false\n return distance <= Math.max(clientHeight, 1) * NEW_TURN_SCROLL_MAX_SCREENS\n}\n\nexport function calculateAnimatedScrollTop({\n fromScrollTop,\n targetScrollTop,\n elapsedMs,\n durationMs = NEW_TURN_SCROLL_DURATION_MS,\n}: {\n fromScrollTop: number\n targetScrollTop: number\n elapsedMs: number\n durationMs?: number\n}) {\n if (durationMs <= 0) return targetScrollTop\n const progress = Math.min(1, Math.max(0, elapsedMs / durationMs))\n const eased = 1 - (1 - progress) ** 3\n return fromScrollTop + (targetScrollTop - fromScrollTop) * eased\n}\n\n","import type { MessageContent, QueueOperationResult } from \"@blade-hq/agent-client/internal\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { type ChatSendExtras, sendToSession } from \"./actions\"\nimport { useSessionHandle, useSessionSource, useSessionState } from \"./session-source\"\n\nexport function useChatActions(sessionId: string) {\n const source = useSessionSource()\n const session = useSessionHandle(sessionId)\n const isStreaming = useSessionState(sessionId, (state) => state.isStreaming)\n const [isStopping, setIsStopping] = useState(false)\n const [queueNotice, setQueueNotice] = useState<string | null>(null)\n const [pendingQueueItemId, setPendingQueueItemId] = useState<string | null>(null)\n const previousSessionIdRef = useRef(sessionId)\n\n const send = useCallback(\n (\n msg: MessageContent,\n targetMode?: string,\n askuserAnswer?: Record<string, unknown>,\n options?: ChatSendExtras,\n ): Promise<boolean> =>\n source.whenReady\n ? source.whenReady(sessionId, (ready) => sendToSession(ready, msg, targetMode, askuserAnswer, options))\n : session\n ? sendToSession(session, msg, targetMode, askuserAnswer, options)\n : Promise.resolve(false),\n [session, sessionId, source],\n )\n\n const withQueue = useCallback(\n async (\n itemId: string | null,\n run: (target: NonNullable<typeof session>) => Promise<QueueOperationResult>,\n ): Promise<boolean> => {\n setQueueNotice(null)\n setPendingQueueItemId(itemId)\n try {\n if (!session) {\n setQueueNotice(\"会话还没有连接好,请稍后重试\")\n return false\n }\n const result = await run(session)\n if (result.conflict) {\n if (!result.snapshot) void session.refreshQueue()\n setQueueNotice(result.message ?? \"队列已在服务端更新,请重试\")\n } else if (!result.ok) {\n setQueueNotice(result.message ?? \"队列操作失败\")\n }\n return result.ok\n } catch (error) {\n setQueueNotice(error instanceof Error && error.message ? error.message : \"队列操作失败\")\n return false\n } finally {\n setPendingQueueItemId(null)\n }\n },\n [session],\n )\n\n const queueMessage = useCallback(\n (content: string) => withQueue(null, (target) => target.queueMessage(content)),\n [withQueue],\n )\n const updateQueuedMessage = useCallback(\n (itemId: string, expectedVersion: number, content: string) =>\n withQueue(itemId, (target) => target.updateQueuedMessage(itemId, expectedVersion, content)),\n [withQueue],\n )\n const reorderQueuedMessages = useCallback(\n (expectedRevision: number, orderedIds: string[]) =>\n withQueue(null, (target) => target.reorderQueuedMessages(expectedRevision, orderedIds)),\n [withQueue],\n )\n const cancelQueuedMessage = useCallback(\n (itemId: string, expectedVersion?: number) =>\n withQueue(itemId, (target) => target.cancelQueuedMessage(itemId, expectedVersion)),\n [withQueue],\n )\n const deliverQueuedMessage = useCallback(\n (itemId: string, expectedVersion: number) =>\n withQueue(itemId, (target) => target.deliverQueuedMessage(itemId, expectedVersion)),\n [withQueue],\n )\n const resumeQueue = useCallback(() => withQueue(null, (target) => target.resumeQueue()), [withQueue])\n\n const stop = useCallback(async () => {\n if (isStopping || !session) return\n setIsStopping(true)\n try {\n if (source.whenReady) await source.whenReady(sessionId, (ready) => ready.stop())\n else await session.stop()\n } catch (error) {\n console.error(\"[chat] stop request failed\", error)\n } finally {\n setIsStopping(false)\n }\n }, [isStopping, session, sessionId, source])\n\n useEffect(() => {\n if (previousSessionIdRef.current !== sessionId) {\n previousSessionIdRef.current = sessionId\n setIsStopping(false)\n setQueueNotice(null)\n setPendingQueueItemId(null)\n return\n }\n if (!isStreaming) setIsStopping(false)\n }, [isStreaming, sessionId])\n\n return {\n isStopping,\n send,\n stop,\n queueNotice,\n pendingQueueItemId,\n queueMessage,\n updateQueuedMessage,\n reorderQueuedMessages,\n cancelQueuedMessage,\n deliverQueuedMessage,\n resumeQueue,\n }\n}\n","import { DEFAULT_REPLAY_SPEED, type ReplaySpeed } from \"@blade-hq/agent-client/internal\"\nimport { useCallback } from \"react\"\nimport { notifyChat, useChatEnvironment } from \"./environment\"\nimport { useSessionHandle, useSessionState } from \"./session-source\"\n\nexport interface UseSessionReplayResult {\n isReplay: boolean\n /** 能不能改回放(owner 专属)。只读身份仍然看得到\"在回放\",但不能操作。 */\n canControl: boolean\n speed: ReplaySpeed\n setSpeed: (speed: ReplaySpeed) => Promise<void>\n exitToAutonomous: () => Promise<void>\n}\n\n/**\n * 回放会话的状态与控制,只服务于回放条(不接管「输入对不上录制内容」的处理)。\n *\n * 状态与控制都来自 AgentSession(`state.replay`、`setReplaySpeed` / `exitReplay`,控制请求在会话实例里\n * 串行执行,晚到的旧响应不会把已经退出的会话又显示成回放中)。\n */\nexport function useSessionReplay(sessionId: string | null | undefined): UseSessionReplayResult {\n const environment = useChatEnvironment()\n const session = useSessionHandle(sessionId)\n const replay = useSessionState(sessionId, (state) => state.replay)\n const viewerRole = useSessionState(sessionId, (state) => state.viewerRole)\n const isReplay = replay?.isReplay ?? false\n const canControl = viewerRole !== \"viewer\"\n\n const setSpeed = useCallback(\n async (next: ReplaySpeed) => {\n if (!session || !isReplay || !canControl) return\n try {\n await session.setReplaySpeed(next)\n } catch (error) {\n notifyChat(environment, \"error\", error instanceof Error ? error.message : \"调整回放速度失败\")\n }\n },\n [environment, session, isReplay, canControl],\n )\n\n const exitToAutonomous = useCallback(async () => {\n if (!session || !isReplay || !canControl) return\n try {\n await session.exitReplay()\n notifyChat(environment, \"success\", \"已退出回放,接下来会真的运行\")\n } catch (error) {\n notifyChat(environment, \"error\", error instanceof Error ? error.message : \"退出回放失败\")\n }\n }, [environment, session, isReplay, canControl])\n\n return {\n isReplay,\n canControl,\n speed: replay?.speed ?? DEFAULT_REPLAY_SPEED,\n setSpeed,\n exitToAutonomous,\n }\n}\n","import { ReplayBar } from \"../components/ReplayBar\"\nimport { useSessionReplay } from \"./runtime/use-session-replay\"\n\n/**\n * 回放会话的状态条:说明\"现在是在重现之前的对话\",并给出倍速和退出。\n *\n * 没有它的话,带方案的回放会话(软件工厂、Solution 会话)看起来和普通对话一模一样——\n * 既不知道自己在回放,也退不出来。只读身份也显示(控件禁用)。\n */\nexport function SessionReplayBar({\n sessionId,\n className,\n onExit,\n}: {\n sessionId: string\n className?: string\n onExit?: () => void\n}) {\n const { isReplay, canControl, speed, setSpeed, exitToAutonomous } = useSessionReplay(sessionId)\n return (\n <ReplayBar\n isReplay={isReplay}\n speed={speed}\n canControl={canControl}\n onSpeedChange={(next) => void setSpeed(next)}\n onExit={onExit ?? (() => void exitToAutonomous())}\n className={className}\n />\n )\n}\n","import type { BladeClient, SessionPluginActivation } from \"@blade-hq/agent-client/internal\"\nimport { useEffect, useState } from \"react\"\nimport { PluginConnectorList } from \"./PluginConnectorList\"\nimport { useSessionPluginActivation } from \"./use-session-plugin-activation\"\n\nexport interface SessionPluginSelectorProps {\n client: BladeClient\n sessionId: string\n className?: string\n side?: \"top\" | \"bottom\"\n onChange?: (plugin: SessionPluginActivation) => void\n}\n\n/** Shared selector for AgentChat and the built-in Web; no external query provider required. */\nexport function SessionPluginSelector(props: SessionPluginSelectorProps) {\n return <PluginSelectorState key={props.sessionId} {...props} />\n}\n\nfunction PluginSelectorState({ client, sessionId, className, side = \"bottom\", onChange }: SessionPluginSelectorProps) {\n const [open, setOpen] = useState(false)\n\n return (\n <div className={`relative text-xs ${className ?? \"\"}`}>\n <button\n type=\"button\"\n disabled={!sessionId}\n aria-expanded={open}\n onClick={() => setOpen(!open)}\n className=\"rounded-full border border-[hsl(var(--border))] px-2.5 py-1\"\n >\n 会话插件\n </button>\n {open ? <PluginSelectorList client={client} sessionId={sessionId} side={side} onChange={onChange} /> : null}\n </div>\n )\n}\n\nfunction PluginSelectorList({\n client,\n sessionId,\n side,\n onChange,\n}: {\n client: BladeClient\n sessionId: string\n side: \"top\" | \"bottom\"\n onChange?: (plugin: SessionPluginActivation) => void\n}) {\n const controller = useSessionPluginActivation({ client, sessionId, onChange })\n const { reload } = controller\n\n useEffect(() => {\n reload()\n }, [reload])\n\n return (\n <div\n className={`absolute left-0 z-40 my-2 max-h-72 w-72 max-w-[calc(100vw-2rem)] overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-[hsl(var(--popover-foreground))] shadow-lg ${\n side === \"top\" ? \"bottom-full\" : \"top-full\"\n }`}\n >\n {controller.listError ? (\n <button type=\"button\" onClick={reload}>\n 插件列表暂不可用,点击重试\n </button>\n ) : null}\n <PluginConnectorList\n client={client}\n sessionId={sessionId}\n items={controller.items}\n inFlight={controller.inFlight}\n busy={controller.busy}\n mutationError={controller.mutationError}\n onToggle={controller.toggle}\n onRetry={controller.retry}\n onEditConfig={controller.editConfig}\n configuring={controller.configuring}\n onConfigSaved={controller.onConfigSaved}\n onConfigClose={controller.onConfigClose}\n emptyText=\"尚未安装插件\"\n />\n </div>\n )\n}\n","import { chatErrorForDisplay } from \"@blade-hq/agent-client/internal\"\nimport { CircleAlert } from \"lucide-react\"\nimport { useEffect, useMemo, useState } from \"react\"\nimport { ChatCustomizationProvider, type ChatPresentationProps } from \"../chat/customization\"\nimport { MessageList } from \"../chat/MessageList\"\nimport { useLlmChat, type LlmChatOptions } from \"../hooks/use-llm-chat\"\nimport { cn } from \"../lib/utils\"\nimport { ChatInput } from \"./ChatInput\"\nimport {\n LlmAdvancedSettingsBar,\n readOverride,\n writeOverride,\n type LlmAdvancedSettings,\n type LlmOverride,\n} from \"./LlmAdvancedSettings\"\n\n/** 纯 LLM 模式的操作句柄,对应智能体模式的 session.insertText() / send()。 */\nexport interface LlmChatHandle {\n /** 把文本放进输入框交给用户确认,不直接发出去。 */\n insertText: (text: string) => void\n send: (text: string) => Promise<boolean>\n /** 清空这段对话。 */\n reset: () => void\n}\n\nexport interface LlmChatProps extends LlmChatOptions, ChatPresentationProps {\n /** 拿到操作句柄:业务界面把选中的数据塞进输入框,或直接发一句。 */\n onReady?: (handle: LlmChatHandle) => void\n /**\n * 打开输入框上方的「高级设置」,让用户自己改模型服务地址(默认还能改模型名)。\n * 不传就一个节点都不渲染。传 `true` 用默认配置,或用对象细调。\n */\n advanced?: boolean | LlmAdvancedSettings\n /** 用户改了覆盖值时回调,方便宿主自己也记一份。 */\n onOverrideChange?: (override: LlmOverride) => void\n}\n\n/**\n * 纯 LLM 模式的聊天界面:不建会话、不连实时通道、也不要求登录 Blade,\n * 只按 **OpenAI Chat Completions** 标准协议跟模型服务一问一答。\n *\n * 默认形态是把 `baseURL` 指向自己后端的透传路径,由后端补密钥再转发,浏览器不持有密钥。\n */\nexport function LlmChat({\n classNames,\n renderers,\n slots,\n placeholder,\n theme,\n onReady,\n advanced,\n onOverrideChange,\n ...options\n}: LlmChatProps) {\n const [override, setOverride] = useState<LlmOverride>(() => readOverride(advanced, options.baseURL))\n const effective = { ...options, ...override }\n const { messages, isStreaming, error, send, stop, reset } = useLlmChat(effective)\n const [inputText, setInputText] = useState(\"\")\n const [stopRequested, setStopRequested] = useState(false)\n const [isRevealing, setIsRevealing] = useState(false)\n const isStreamingDisplay = isStreaming || isRevealing\n\n const handle = useMemo<LlmChatHandle>(\n () => ({\n insertText: (text) => setInputText((prev) => (prev ? `${prev}\\n${text}` : text)),\n send,\n reset,\n }),\n [send, reset],\n )\n useEffect(() => {\n onReady?.(handle)\n }, [handle, onReady])\n\n const customization = useMemo(() => ({ classNames, renderers }), [classNames, renderers])\n\n return (\n <ChatCustomizationProvider value={customization}>\n <div\n data-theme={theme}\n part=\"root\"\n className={cn(\"blade-chat flex min-h-0 flex-1 flex-col overflow-hidden\", classNames?.root)}\n >\n {error ? (\n <div\n part=\"error-bar\"\n className=\"blade-chat-error-bar flex items-start gap-2 border-b border-[hsl(var(--swf-danger)/0.3)] bg-[hsl(var(--swf-danger-soft))] px-4 py-3 text-sm text-[hsl(var(--swf-danger))]\"\n >\n <CircleAlert size={16} className=\"mt-0.5 shrink-0\" />\n <span className=\"min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]\">\n {chatErrorForDisplay(error)}\n </span>\n </div>\n ) : null}\n {slots?.header}\n <MessageList\n sessionId=\"\"\n messages={messages}\n isStreaming={isStreaming}\n customization={customization}\n emptyState={slots?.emptyState}\n isStopping={stopRequested && isStreamingDisplay}\n onRevealingChange={setIsRevealing}\n />\n {advanced ? (\n <LlmAdvancedSettingsBar\n settings={advanced}\n defaults={{ baseURL: options.baseURL, model: options.model }}\n override={override}\n onChange={(next) => {\n setOverride(next)\n writeOverride(advanced, options.baseURL, next)\n onOverrideChange?.(next)\n }}\n />\n ) : null}\n <ChatInput\n value={inputText}\n onValueChange={setInputText}\n onSend={async (text) => {\n setStopRequested(false)\n if (!text.trim() || isStreaming) return false\n void send(text)\n return true\n }}\n onStop={() => {\n setStopRequested(true)\n stop()\n }}\n isStreaming={isStreamingDisplay}\n isStopping={stopRequested && isStreamingDisplay}\n placeholder={placeholder}\n className={classNames?.chatInputRoot}\n innerClassName={classNames?.chatInputInner}\n />\n {slots?.footer}\n </div>\n </ChatCustomizationProvider>\n )\n}\n","import type { ChatMessage, ToolCallInfo } from \"@blade-hq/agent-client\"\nimport { useCallback, useMemo, useRef, useState } from \"react\"\n\n/** OpenAI 标准的工具声明,原样发给模型服务。 */\nexport interface ChatCompletionTool {\n type: \"function\"\n function: {\n name: string\n description?: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface LlmToolCall {\n id: string\n name: string\n /** 模型生成的 JSON 字符串,是不可信输入,用之前自己校验。 */\n arguments: string\n}\n\nexport interface LlmChatOptions {\n /** OpenAI 兼容根地址,如 `/api/llm`(自己后端的透传路径)或 `http://host:30000/v1`。 */\n baseURL: string\n model: string\n /**\n * 直连模型服务时才需要。默认形态是让 `baseURL` 指向自己的后端,由后端补密钥转发,\n * 浏览器不持有密钥。\n */\n apiKey?: string\n headers?: Record<string, string>\n /** 系统提示词,合成到消息最前面。 */\n system?: string\n /** 每次带上最近多少轮,默认 12。越长越贵,也越容易超上下文。 */\n historyTurns?: number\n temperature?: number\n /** 透传给模型服务的额外字段。 */\n extraBody?: Record<string, unknown>\n tools?: ChatCompletionTool[]\n /** 执行模型请求的工具,返回值会被序列化后回喂给模型。 */\n onToolCall?: (call: LlmToolCall) => Promise<unknown>\n /** 工具最多来回几轮,默认 4,防止模型绕圈烧 token。 */\n maxToolRounds?: number\n fetchImpl?: typeof fetch\n}\n\nexport interface UseLlmChatResult {\n messages: ChatMessage[]\n isStreaming: boolean\n /** 出错原因;下一次发送会清掉。 */\n error: string | null\n send: (text: string) => Promise<boolean>\n stop: () => void\n reset: () => void\n}\n\ninterface OpenAiToolCall {\n id: string\n type: \"function\"\n function: { name: string; arguments: string }\n}\n\ntype OpenAiMessage =\n | { role: \"user\" | \"assistant\"; content: string; tool_calls?: OpenAiToolCall[] }\n | { role: \"tool\"; tool_call_id: string; content: string }\n\ninterface AssistantTiming {\n startedAt: number\n durationMs?: number\n status?: \"failed\" | \"interrupted\"\n}\n\nconst DEFAULT_HISTORY_TURNS = 12\nconst DEFAULT_MAX_TOOL_ROUNDS = 4\n\nlet syntheticIdSeq = 0\n\n/**\n * 纯 LLM 对话的状态机,协议就是 **OpenAI Chat Completions**——任何兼容实现都能直接接,\n * 不需要为这个组件专门写后端。\n *\n * 工具调用走 OpenAI 标准的多轮流程:模型返回 tool_calls → 调 onToolCall 执行 →\n * 结果作为 role:\"tool\" 消息回喂 → 再请求一次。\n */\nexport function useLlmChat(options: LlmChatOptions): UseLlmChatResult {\n const [history, setHistory] = useState<OpenAiMessage[]>([])\n const [streamingText, setStreamingText] = useState<string | null>(null)\n const [streamingCalls, setStreamingCalls] = useState<OpenAiToolCall[]>([])\n const [failedToolIds, setFailedToolIds] = useState<string[]>([])\n const [error, setError] = useState<string | null>(null)\n const [isStreaming, setIsStreaming] = useState(false)\n const abortRef = useRef<AbortController | null>(null)\n const activeStartedAtRef = useRef<number | null>(null)\n const assistantTimingsRef = useRef(new WeakMap<OpenAiMessage, AssistantTiming>())\n const generationRef = useRef(0)\n const historyRef = useRef<OpenAiMessage[]>([])\n const optionsRef = useRef(options)\n optionsRef.current = options\n historyRef.current = history\n\n const stop = useCallback(() => {\n abortRef.current?.abort()\n abortRef.current = null\n }, [])\n\n const reset = useCallback(() => {\n generationRef.current += 1\n stop()\n setHistory([])\n setStreamingText(null)\n setStreamingCalls([])\n setFailedToolIds([])\n setError(null)\n setIsStreaming(false)\n activeStartedAtRef.current = null\n assistantTimingsRef.current = new WeakMap()\n }, [stop])\n\n const send = useCallback(async (text: string): Promise<boolean> => {\n const content = text.trim()\n if (!content || abortRef.current) return false\n const opts = optionsRef.current\n const maxRounds = opts.maxToolRounds ?? DEFAULT_MAX_TOOL_ROUNDS\n const startedAt = Date.now()\n activeStartedAtRef.current = startedAt\n\n const commit = (message: OpenAiMessage) => {\n historyRef.current = [...historyRef.current, message]\n setHistory(historyRef.current)\n }\n const latestAssistantTiming = { current: null as AssistantTiming | null }\n const commitAssistant = (message: OpenAiMessage) => {\n const timing: AssistantTiming = { startedAt }\n assistantTimingsRef.current.set(message, timing)\n latestAssistantTiming.current = timing\n commit(message)\n return timing\n }\n const finishTiming = (timing: AssistantTiming) => {\n timing.durationMs = Math.max(0, Date.now() - timing.startedAt)\n }\n\n setError(null)\n setIsStreaming(true)\n setStreamingText(\"\")\n setStreamingCalls([])\n commit({ role: \"user\", content })\n let partial = \"\"\n\n const controller = new AbortController()\n abortRef.current = controller\n const generation = generationRef.current\n try {\n for (let round = 0; ; round += 1) {\n const result = await streamOnce(opts, historyRef.current, controller.signal, {\n onText: (chunk) => {\n partial += chunk\n setStreamingText((prev) => `${prev ?? \"\"}${chunk}`)\n },\n onToolCalls: (calls) => setStreamingCalls(calls),\n })\n\n const assistant: OpenAiMessage = {\n role: \"assistant\",\n content: result.content,\n ...(result.toolCalls.length ? { tool_calls: result.toolCalls } : {}),\n }\n setStreamingText(null)\n setStreamingCalls([])\n const assistantTiming = commitAssistant(assistant)\n\n if (!result.toolCalls.length) {\n finishTiming(assistantTiming)\n return true\n }\n const bail = (reason: string) => {\n for (const call of result.toolCalls) {\n commit({ role: \"tool\", tool_call_id: call.id, content: JSON.stringify({ error: reason }) })\n }\n setFailedToolIds((prev) => [...prev, ...result.toolCalls.map((call) => call.id)])\n }\n if (!opts.onToolCall) {\n bail(\"这个应用没有提供工具执行入口\")\n finishTiming(assistantTiming)\n return true\n }\n if (round >= maxRounds) {\n bail(`工具调用已达上限 ${maxRounds} 轮,没有执行`)\n setError(`工具调用超过 ${maxRounds} 轮仍未给出结论,已停下。`)\n finishTiming(assistantTiming)\n return false\n }\n\n for (const call of result.toolCalls) {\n let output: string\n try {\n const value = await opts.onToolCall({\n id: call.id,\n name: call.function.name,\n arguments: call.function.arguments,\n })\n output = typeof value === \"string\" ? value : JSON.stringify(value ?? null)\n } catch (err) {\n output = JSON.stringify({ error: err instanceof Error ? err.message : String(err) })\n setFailedToolIds((prev) => [...prev, call.id])\n }\n commit({ role: \"tool\", tool_call_id: call.id, content: output })\n }\n setStreamingText(\"\")\n }\n } catch (err) {\n setStreamingText(null)\n setStreamingCalls([])\n if (controller.signal.aborted) {\n if (generation !== generationRef.current) return false\n const timing = commitAssistant({\n role: \"assistant\",\n content: partial ? `${partial}(已停止)` : \"(已停止)\",\n })\n timing.status = \"interrupted\"\n finishTiming(timing)\n return false\n }\n if (partial && generation === generationRef.current) {\n const timing = commitAssistant({ role: \"assistant\", content: partial })\n timing.status = \"failed\"\n finishTiming(timing)\n } else if (latestAssistantTiming.current) {\n latestAssistantTiming.current.status = \"failed\"\n finishTiming(latestAssistantTiming.current)\n }\n setError(err instanceof Error && err.message ? err.message : \"对话失败,请重试\")\n return false\n } finally {\n if (abortRef.current === controller) abortRef.current = null\n activeStartedAtRef.current = null\n setIsStreaming(false)\n }\n }, [])\n\n const messages = useMemo(\n () =>\n toChatMessages(\n history,\n streamingText,\n streamingCalls,\n failedToolIds,\n assistantTimingsRef.current,\n activeStartedAtRef.current,\n ),\n [history, streamingText, streamingCalls, failedToolIds],\n )\n\n return { messages, isStreaming, error, send, stop, reset }\n}\n\ninterface StreamResult {\n content: string\n toolCalls: OpenAiToolCall[]\n}\n\nasync function streamOnce(\n options: LlmChatOptions,\n history: OpenAiMessage[],\n signal: AbortSignal,\n handlers: { onText: (chunk: string) => void; onToolCalls: (calls: OpenAiToolCall[]) => void },\n): Promise<StreamResult> {\n const {\n baseURL,\n model,\n apiKey,\n headers,\n system,\n historyTurns = DEFAULT_HISTORY_TURNS,\n temperature,\n extraBody,\n tools,\n fetchImpl,\n } = options\n\n const trimmed = trimHistory(history, historyTurns)\n const payload = {\n model,\n stream: true,\n messages: system ? [{ role: \"system\", content: system }, ...trimmed] : trimmed,\n ...(tools?.length ? { tools } : {}),\n ...(temperature === undefined ? {} : { temperature }),\n ...extraBody,\n }\n\n const doFetch = fetchImpl ?? globalThis.fetch\n const url = `${baseURL.replace(/\\/$/, \"\")}/chat/completions`\n let response: Response\n try {\n response = await doFetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),\n ...headers,\n },\n body: JSON.stringify(payload),\n signal,\n })\n } catch (err) {\n if (signal.aborted) throw err\n // 浏览器给的原始信息是 \"Failed to fetch\",看不出是哪台服务连不上。\n // 地址填错是最常见的故障,必须把地址显示出来。\n throw new Error(`连不上模型服务 ${url}:${err instanceof Error ? err.message : String(err)}`)\n }\n if (!response.ok) {\n throw new Error(await describeHttpError(response))\n }\n if (!response.body) {\n throw new Error(\"模型服务没有返回流式响应\")\n }\n\n let content = \"\"\n const calls: OpenAiToolCall[] = []\n for await (const chunk of readSse(response.body, signal)) {\n if (chunk.error) {\n throw new Error(chunk.error)\n }\n if (chunk.text) {\n content += chunk.text\n handlers.onText(chunk.text)\n }\n if (chunk.toolCallDeltas) {\n for (const delta of chunk.toolCallDeltas) {\n const index = delta.index ?? 0\n const existing = calls[index] ?? { id: \"\", type: \"function\" as const, function: { name: \"\", arguments: \"\" } }\n calls[index] = {\n id: delta.id ?? existing.id,\n type: \"function\",\n function: {\n name: delta.function?.name ?? existing.function.name,\n arguments: `${existing.function.arguments}${delta.function?.arguments ?? \"\"}`,\n },\n }\n }\n handlers.onToolCalls(calls.filter(Boolean).map((call) => ({ ...call })))\n }\n }\n const normalized = calls\n .filter(Boolean)\n .filter((call) => call.function.name)\n .map((call) => {\n if (call.id) return call\n syntheticIdSeq += 1\n return { ...call, id: `call_auto_${syntheticIdSeq}` }\n })\n return { content, toolCalls: normalized }\n}\n\nfunction trimHistory(history: OpenAiMessage[], historyTurns: number): OpenAiMessage[] {\n const userIndexes = history.reduce<number[]>((acc, msg, i) => {\n if (msg.role === \"user\") acc.push(i)\n return acc\n }, [])\n if (userIndexes.length <= historyTurns) return history\n return history.slice(userIndexes[userIndexes.length - historyTurns])\n}\n\nasync function describeHttpError(response: Response): Promise<string> {\n const raw = await response.text().catch(() => \"\")\n try {\n const parsed = JSON.parse(raw) as { error?: { message?: string } | string; detail?: unknown }\n const message =\n typeof parsed.error === \"string\"\n ? parsed.error\n : (parsed.error?.message ??\n (typeof parsed.detail === \"string\" ? parsed.detail : undefined))\n if (message) return `模型服务返回 ${response.status}:${message}`\n } catch {\n }\n const snippet = raw.trim().slice(0, 120)\n return snippet ? `模型服务返回 ${response.status}:${snippet}` : `模型服务返回 ${response.status}`\n}\n\ninterface StreamChunk {\n text?: string\n toolCallDeltas?: Array<{\n index?: number\n id?: string\n function?: { name?: string; arguments?: string }\n }>\n error?: string\n}\n\nasync function* readSse(\n stream: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n): AsyncGenerator<StreamChunk> {\n const reader = stream.getReader()\n const decoder = new TextDecoder()\n let buffer = \"\"\n try {\n while (!signal.aborted) {\n const { done, value } = await reader.read()\n if (done) {\n const tail = parseSse(buffer)\n if (tail && tail !== \"done\") yield tail\n break\n }\n buffer = `${buffer}${decoder.decode(value, { stream: true })}`.replace(/\\r\\n/g, \"\\n\")\n let boundary = buffer.indexOf(\"\\n\\n\")\n while (boundary !== -1) {\n const chunk = parseSse(buffer.slice(0, boundary))\n buffer = buffer.slice(boundary + 2)\n if (chunk === \"done\") return\n if (chunk) yield chunk\n boundary = buffer.indexOf(\"\\n\\n\")\n }\n }\n } finally {\n reader.cancel().catch(() => {})\n }\n}\n\nfunction parseSse(raw: string): StreamChunk | \"done\" | null {\n const dataLines: string[] = []\n for (const line of raw.split(\"\\n\")) {\n if (line.startsWith(\"data:\")) dataLines.push(line.slice(5).trim())\n }\n if (!dataLines.length) return null\n const data = dataLines.join(\"\\n\")\n if (data === \"[DONE]\") return \"done\"\n let parsed: {\n choices?: Array<{ delta?: { content?: string; tool_calls?: StreamChunk[\"toolCallDeltas\"] } }>\n error?: { message?: string } | string\n }\n try {\n parsed = JSON.parse(data)\n } catch {\n return null\n }\n if (parsed.error) {\n const message = typeof parsed.error === \"string\" ? parsed.error : parsed.error.message\n return { error: message || \"模型服务返回了错误\" }\n }\n const delta = parsed.choices?.[0]?.delta\n if (!delta) return null\n return { text: delta.content, toolCallDeltas: delta.tool_calls }\n}\n\nfunction toChatMessages(\n history: OpenAiMessage[],\n streamingText: string | null,\n streamingCalls: OpenAiToolCall[],\n failedToolIds: string[],\n assistantTimings: WeakMap<OpenAiMessage, AssistantTiming>,\n activeStartedAt: number | null,\n): ChatMessage[] {\n const results = new Map<string, string>()\n for (const msg of history) {\n if (msg.role === \"tool\") results.set(msg.tool_call_id, msg.content)\n }\n\n const messages: ChatMessage[] = []\n for (const msg of history) {\n if (msg.role === \"tool\") continue\n if (msg.role === \"user\") {\n messages.push({ role: \"user\", content: msg.content, status: \"completed\" })\n continue\n }\n const timing = assistantTimings.get(msg)\n messages.push({\n role: \"assistant\",\n content: msg.content,\n status: timing?.status ?? \"completed\",\n ...(timing ? { timestamp: new Date(timing.startedAt).toISOString() } : {}),\n ...(timing?.durationMs === undefined ? {} : { duration_ms: timing.durationMs }),\n ...(msg.tool_calls?.length\n ? { tool_calls: msg.tool_calls.map((call) => toToolCallInfo(call, results, failedToolIds)) }\n : {}),\n })\n }\n\n if (streamingText !== null) {\n messages.push({\n role: \"assistant\",\n content: streamingText,\n status: \"streaming\",\n ...(activeStartedAt === null\n ? {}\n : { timestamp: new Date(activeStartedAt).toISOString() }),\n ...(streamingCalls.length\n ? { tool_calls: streamingCalls.map((call) => toToolCallInfo(call, results, failedToolIds)) }\n : {}),\n })\n }\n return messages\n}\n\nfunction toToolCallInfo(\n call: OpenAiToolCall,\n results: Map<string, string>,\n failedToolIds: string[],\n): ToolCallInfo {\n const result = results.get(call.id)\n const failed = failedToolIds.includes(call.id)\n return {\n id: call.id,\n name: call.function.name,\n arguments: call.function.arguments,\n ...(result === undefined ? {} : { result }),\n status: result === undefined ? \"pending\" : failed ? \"error\" : \"done\",\n }\n}\n","import { Settings2 } from \"lucide-react\"\nimport { useState } from \"react\"\n\n/** 纯 LLM 模式的高级设置:让用户自己改模型服务地址。 */\nexport interface LlmAdvancedSettings {\n /** 允许改模型服务地址,默认允许。 */\n baseURL?: boolean\n /** 允许改模型名,默认允许。 */\n model?: boolean\n /**\n * 允许在界面上填密钥,默认**不允许**。\n * 打开意味着密钥存在浏览器里,只适合受控内网、演示,或密钥本身就属于当前用户的场景。\n */\n apiKey?: boolean\n /** 覆盖值存哪:`local` 记住用户的选择(默认),`memory` 只在本次会话有效。 */\n storage?: \"local\" | \"memory\"\n /** localStorage 的键,默认按组件拿到的 baseURL 生成。 */\n storageKey?: string\n}\n\nexport interface LlmOverride {\n baseURL?: string\n model?: string\n apiKey?: string\n}\n\nconst FIELDS: Array<{ id: keyof LlmOverride; label: string; placeholder: string; secret?: boolean }> = [\n { id: \"baseURL\", label: \"模型服务地址\", placeholder: \"http://内网地址/v1\" },\n { id: \"model\", label: \"模型\", placeholder: \"模型名称\" },\n { id: \"apiKey\", label: \"密钥\", placeholder: \"留空表示不改\", secret: true },\n]\n\nexport function normalizeAdvanced(\n value: boolean | LlmAdvancedSettings | undefined,\n): Required<Pick<LlmAdvancedSettings, \"baseURL\" | \"model\" | \"apiKey\" | \"storage\">> | null {\n if (!value) return null\n const config = value === true ? {} : value\n return {\n baseURL: config.baseURL ?? true,\n model: config.model ?? true,\n apiKey: config.apiKey ?? false,\n storage: config.storage ?? \"local\",\n }\n}\n\nfunction storageKeyFor(settings: boolean | LlmAdvancedSettings | undefined, baseURL: string): string {\n const explicit = typeof settings === \"object\" ? settings.storageKey : undefined\n return `blade-llm-override:${explicit ?? baseURL}`\n}\n\nexport function readOverride(\n settings: boolean | LlmAdvancedSettings | undefined,\n baseURL: string,\n): LlmOverride {\n const normalized = normalizeAdvanced(settings)\n if (!normalized || normalized.storage !== \"local\" || typeof localStorage === \"undefined\") return {}\n try {\n const raw = localStorage.getItem(storageKeyFor(settings, baseURL))\n if (!raw) return {}\n const stored = JSON.parse(raw) as LlmOverride\n return Object.fromEntries(\n Object.entries(stored).filter(([key]) => normalized[key as keyof LlmOverride]),\n ) as LlmOverride\n } catch {\n return {}\n }\n}\n\nfunction writeOverride(\n settings: boolean | LlmAdvancedSettings | undefined,\n baseURL: string,\n override: LlmOverride,\n): void {\n const normalized = normalizeAdvanced(settings)\n if (!normalized || normalized.storage !== \"local\" || typeof localStorage === \"undefined\") return\n try {\n const key = storageKeyFor(settings, baseURL)\n if (Object.keys(override).length === 0) localStorage.removeItem(key)\n else localStorage.setItem(key, JSON.stringify(override))\n } catch {\n }\n}\n\ninterface Props {\n settings: boolean | LlmAdvancedSettings\n defaults: { baseURL: string; model: string }\n override: LlmOverride\n onChange: (next: LlmOverride) => void\n}\n\n/**\n * 输入框上方的一行「高级设置」:默认收起,展开后可以改模型服务地址与模型。\n * 只有调用方显式打开才渲染——不传 advanced 时这里一个节点都不会出现。\n */\nexport function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }: Props) {\n const normalized = normalizeAdvanced(settings)\n const [open, setOpen] = useState(false)\n const [draft, setDraft] = useState<LlmOverride>(override)\n if (!normalized) return null\n\n const fields = FIELDS.filter((field) => normalized[field.id])\n const dirty = Object.keys(override).length > 0\n\n return (\n <div className=\"blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs\">\n <button\n type=\"button\"\n onClick={() => {\n setDraft(override)\n setOpen((value) => !value)\n }}\n className=\"flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]\"\n >\n <Settings2 size={13} />\n 高级设置\n {dirty && <span className=\"text-[hsl(var(--primary))]\">(已自定义)</span>}\n </button>\n {open && (\n <div className=\"mt-2 flex flex-col gap-2\">\n {fields.map((field) => (\n <label key={field.id} className=\"flex flex-col gap-1\">\n <span className=\"text-[hsl(var(--muted-foreground))]\">{field.label}</span>\n <input\n type={field.secret ? \"password\" : \"text\"}\n value={draft[field.id] ?? \"\"}\n placeholder={\n field.id === \"apiKey\"\n ? field.placeholder\n : (defaults[field.id as \"baseURL\" | \"model\"] || field.placeholder)\n }\n onChange={(event) => setDraft({ ...draft, [field.id]: event.target.value })}\n className=\"rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-2 py-1 text-xs text-[hsl(var(--foreground))] outline-none\"\n />\n </label>\n ))}\n {normalized.apiKey && (\n <p className=\"text-[hsl(var(--muted-foreground))]\">\n 密钥会存在这台浏览器里。只在你信得过这台机器时填。\n </p>\n )}\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n const next = Object.fromEntries(\n Object.entries(draft).filter(([, value]) => String(value ?? \"\").trim() !== \"\"),\n ) as LlmOverride\n onChange(next)\n setOpen(false)\n }}\n className=\"rounded-md bg-[hsl(var(--primary))] px-2.5 py-1 font-medium text-[hsl(var(--primary-foreground))]\"\n >\n 保存\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setDraft({})\n onChange({})\n setOpen(false)\n }}\n className=\"rounded-md border border-[hsl(var(--border))] px-2.5 py-1 text-[hsl(var(--foreground))]\"\n >\n 恢复默认\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport { writeOverride }\n","import { AgentChat, type AgentChatProps } from \"./AgentChat\"\nimport { LlmChat, type LlmChatHandle } from \"./LlmChat\"\nimport type { LlmAdvancedSettings, LlmOverride } from \"./LlmAdvancedSettings\"\nimport type { LlmChatOptions } from \"../hooks/use-llm-chat\"\n\nexport type {\n AssistantTextRendererProps,\n AskUserQuestionRendererProps,\n ChatViewClassNames,\n ChatViewRenderers,\n ChatViewSlots,\n PlanUpdateRendererProps,\n UserMessageRendererProps,\n} from \"../chat/customization\"\nexport type { FollowupInteractionEvent } from \"../chat/followup-interaction\"\n\nexport interface ChatViewProps extends AgentChatProps {\n /** 挂哪个下层组件。默认 `agent`——不传就是接 Blade 智能体会话的原有行为。 */\n mode?: \"agent\" | \"llm\"\n /** `mode=\"llm\"` 时的模型服务配置;`advanced` 打开输入框上方的「高级设置」。 */\n llm?: LlmChatOptions & {\n advanced?: boolean | LlmAdvancedSettings\n onOverrideChange?: (override: LlmOverride) => void\n }\n /** `mode=\"llm\"` 时拿到操作句柄;智能体模式请用 `onSessionReady`。 */\n onLlmReady?: (handle: LlmChatHandle) => void\n}\n\n/**\n * 聊天界面。默认接 Blade 智能体会话,`mode=\"llm\"` 时改接标准 OpenAI 对话接口。\n *\n * 这一层只做分流:两种模式各自是独立组件,已经确定要哪一种的可以直接用\n * `<AgentChat>` 或 `<LlmChat>`。\n */\nexport function ChatView(props: ChatViewProps) {\n const { mode, llm, onLlmReady, ...rest } = props\n if (mode === \"llm\") {\n if (!llm) {\n throw new Error('ChatView: mode=\"llm\" 需要同时传 llm={{ baseURL, model }}')\n }\n return (\n <LlmChat\n {...llm}\n classNames={rest.classNames}\n renderers={rest.renderers}\n slots={rest.slots}\n placeholder={rest.placeholder}\n theme={rest.theme}\n onReady={onLlmReady}\n />\n )\n }\n return <AgentChat {...rest} />\n}\n","import { useRef, useState } from \"react\"\nimport { Dialog, DialogContent, DialogDescription, DialogTitle } from \"@blade-hq/ui/composites/dialog\"\nimport { useBladeClient } from \"../context\"\nimport { useAsyncValue } from \"../chat/lib/use-async-value\"\n\n/** Shared permission decision for any session-file UI. The server checks again on submission. */\nexport function useTopicAssetSubmissionAccess(sessionId: string | null) {\n const client = useBladeClient()\n return useAsyncValue(sessionId, async (signal) => {\n if (!sessionId) return null\n const [session, groups] = await Promise.all([\n client.sessions.getSession(sessionId, { signal }),\n client.chatGroups.list(),\n ])\n if (!session.chat_group_id || session.viewer_role === \"viewer\") return null\n const group = groups.find((item) => item.id === session.chat_group_id)\n return group && (group.role === \"owner\" || group.role === \"editor\") ? group : null\n })\n}\n\nexport interface TopicAssetSubmitDialogProps {\n sessionId: string\n topicId: string\n path: string\n onClose: () => void\n onSubmitted?: () => void\n}\n\n/** Copy an existing sandbox file into the topic; never move or rewrite the draft. */\nexport function TopicAssetSubmitDialog({ sessionId, topicId, path, onClose, onSubmitted }: TopicAssetSubmitDialogProps) {\n const client = useBladeClient()\n const [folder, setFolder] = useState(\"\")\n const [message, setMessage] = useState(\"\")\n const [error, setError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n const submitting = useRef(false)\n const [revision, setRevision] = useState(0)\n const assets = useAsyncValue(`${sessionId}:${topicId}:${revision}`, async () => {\n const [session, groups, result] = await Promise.all([\n client.sessions.getSession(sessionId), client.chatGroups.list(), client.chatGroups.listAssets(topicId),\n ])\n const role = groups.find((item) => item.id === topicId)?.role\n if (session.chat_group_id !== topicId || session.viewer_role === \"viewer\") throw new Error(\"这个会话不能提交到该工作空间\")\n if (role !== \"owner\" && role !== \"editor\") throw new Error(\"你在这个工作空间没有提交权限\")\n const folders = new Set<string>()\n for (const asset of result.items) {\n if (asset.is_dir) folders.add(asset.path)\n const parts = asset.path.split(\"/\")\n for (let i = 1; i < parts.length; i += 1) folders.add(parts.slice(0, i).join(\"/\"))\n }\n return [...folders].sort((a, b) => a.localeCompare(b))\n })\n const submit = async () => {\n if (submitting.current || !assets.data) return\n submitting.current = true\n setBusy(true)\n setError(null)\n try {\n const name = path.split(\"/\").at(-1) ?? path\n await client.chatGroups.submitSessionAsset({ session_id: sessionId, path, target_path: folder ? `${folder}/${name}` : name, message: message.trim() })\n onSubmitted?.()\n onClose()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : \"提交失败,请重试\")\n } finally {\n submitting.current = false\n setBusy(false)\n }\n }\n return <Dialog open onOpenChange={(open) => { if (!open && !busy) onClose() }}>\n <DialogContent className=\"max-w-md\">\n <DialogTitle>提交到资产</DialogTitle>\n <DialogDescription>将文件复制到工作空间供成员使用,工作区原文件会保留。同名资产会被替换。</DialogDescription>\n <form onSubmit={(event) => { event.preventDefault(); void submit() }} className=\"flex flex-col gap-4\">\n <p className=\"break-all text-sm text-secondary-foreground\">{path}</p>\n <label className=\"flex flex-col gap-1 text-sm\">目标文件夹\n <select aria-label=\"目标文件夹\" value={folder} onChange={(event) => setFolder(event.target.value)} disabled={busy || !assets.data} className=\"rounded-md border border-border bg-background p-2\">\n <option value=\"\">资产根目录</option>\n {assets.data?.map((item) => <option key={item} value={item}>{item}</option>)}\n </select>\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">说明(可选)\n <textarea aria-label=\"提交说明\" value={message} onChange={(event) => setMessage(event.target.value)} maxLength={1000} disabled={busy} className=\"min-h-20 rounded-md border border-border bg-background p-2\" />\n </label>\n {assets.error ? <div role=\"alert\" className=\"text-sm text-muted-foreground\">{assets.error instanceof Error ? assets.error.message : \"资产加载失败\"} <button type=\"button\" onClick={() => setRevision((n) => n + 1)} className=\"underline\">重试</button></div> : !assets.data ? <output className=\"text-sm text-muted-foreground\">正在加载资产…</output> : null}\n {error ? <p role=\"alert\" className=\"text-sm text-muted-foreground\">{error}</p> : null}\n <div className=\"flex justify-end gap-2\">\n <button type=\"button\" disabled={busy} onClick={onClose} className=\"rounded-md border border-border px-3 py-2 text-sm\">取消</button>\n <button type=\"submit\" disabled={busy || !assets.data} className=\"rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-50\">{busy ? \"提交中…\" : \"提交\"}</button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","jsx","jsxs","useEffect","useMemo","useRef","useState","useCallback","useEffect","useMemo","useState","chatErrorForDisplay","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useEffect","useMemo","useRef","createContext","useContext","createContext","useContext","Fragment","jsx","jsxs","useMemo","useRef","useEffect","createContext","useCallback","useContext","useEffect","useRef","useState","useRef","useState","Fragment","jsx","jsxs","useRef","isSending","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","extractTextAttachments","getTextContent","normalizeMessageContent","map","chatErrorForDisplay","isBackgroundWakeMessage","jsx","jsxs","memo","useCallback","useEffect","useMemo","useRef","useState","getFileParts","getImageParts","getTextContent","collectInlineToolUiCards","isWorkflowRunToolName","jsx","createContext","memo","useCallback","useContext","useEffect","useMemo","useRef","useState","useMemo","jsx","Component","useMemo","Fragment","jsx","jsxs","createContext","useContext","memo","useRef","useEffect","useCallback","useMemo","useState","createContext","useContext","useMemo","useState","Fragment","jsx","jsxs","useState","useMemo","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","jsx","useEffect","useMemo","useState","useEffect","useMemo","useRef","useState","jsx","jsxs","useRef","useEffect","useState","useMemo","text","Fragment","jsx","jsxs","useMemo","useState","useEffect","customToolCall","useMemo","useState","useEffect","useMemo","useState","useEffect","useRef","useState","useEffect","useState","load","jsx","jsxs","Fragment","jsx","jsxs","useRef","useEffect","useState","useEffect","useState","jsx","jsxs","Fragment","jsx","jsxs","getFileIcon","lower","jsx","jsxs","jsx","jsxs","useEffect","useState","lower","Fragment","jsx","jsxs","useMemo","useState","useEffect","Fragment","jsx","jsxs","useState","useMemo","map","childMessages","jsx","jsxs","getImageParts","getFileParts","useMemo","isWorkflowRunToolName","useState","useRef","useEffect","collectInlineToolUiCards","getTextContent","memo","useCallback","useCallback","useEffect","useRef","persistentId","jsx","jsxs","useCallback","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useCallback","jsx","jsxs","getTextContent","normalizeMessageContent","extractTextAttachments","isBackgroundWakeMessage","chatErrorForDisplay","useRef","useEffect","useMemo","useCallback","useState","isBackgroundWakeMessage","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","useCallback","useMemo","useRef","useState","isAtBottom","escapedFromLock","createContext","useContext","useEffect","useLayoutEffect","useMemo","useRef","createContext","useLayoutEffect","useEffect","useRef","useMemo","targetScrollTop","StickToBottom","useContext","getTextContent","isHiddenInternalMessage","normalizeMessageContent","useCallback","useEffect","useLayoutEffect","useRef","useState","latestUserSpeechEntryId","load","seq","useCallback","useEffect","useRef","useState","handle","useMemo","useState","exception","map","schema","type","extend","str","string","parseModeChange","skillId","Fragment","jsx","jsxs","useMemo","useState","parseModeChange","useEffect","useRef","useEffect","useRef","useState","Fragment","jsx","jsxs","basename","useState","useRef","useEffect","jsx","jsxs","useRef","useEffect","jsx","jsxs","useCallback","useEffect","useLayoutEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useCallback","useLayoutEffect","MANUAL_SCROLL_TOLERANCE_PX","prefersReducedMotion","Fragment","jsx","jsxs","prefersReducedMotion","useMemo","useRef","useEffect","useState","useCallback","useLayoutEffect","MANUAL_SCROLL_TOLERANCE_PX","isBackgroundWakeMessage","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","useEffect","DEFAULT_REPLAY_SPEED","useCallback","useCallback","DEFAULT_REPLAY_SPEED","jsx","Fragment","jsx","jsxs","useMemo","useState","useCallback","useEffect","chatErrorForDisplay","useEffect","useState","jsx","jsxs","useState","useEffect","Fragment","jsx","jsxs","useState","useEffect","useRef","useMemo","chatErrorForDisplay","useEffect","useMemo","useState","useCallback","useMemo","useRef","useState","snippet","useState","jsx","jsxs","jsx","jsxs","useState","useMemo","useEffect","chatErrorForDisplay","jsx","useRef","useState","jsx","jsxs","useState","useRef"]}