langchain_agentx_stream_ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -0
- package/dist/AskUserQuestionToolBody-CyuNy_k5.d.ts +33 -0
- package/dist/MarkdownBlock-3iEW0Ubm.d.ts +100 -0
- package/dist/chunk-4RIOBLGB.js +666 -0
- package/dist/chunk-4RIOBLGB.js.map +1 -0
- package/dist/chunk-DP7V33X7.js +13 -0
- package/dist/chunk-DP7V33X7.js.map +1 -0
- package/dist/chunk-G2KYJCMM.js +5171 -0
- package/dist/chunk-G2KYJCMM.js.map +1 -0
- package/dist/chunk-MHK53ZHC.js +972 -0
- package/dist/chunk-MHK53ZHC.js.map +1 -0
- package/dist/chunk-W6QQHTJ4.js +785 -0
- package/dist/chunk-W6QQHTJ4.js.map +1 -0
- package/dist/chunk-WM6Y6APP.js +411 -0
- package/dist/chunk-WM6Y6APP.js.map +1 -0
- package/dist/default.css +1364 -0
- package/dist/index.d.ts +650 -0
- package/dist/index.js +743 -0
- package/dist/index.js.map +1 -0
- package/dist/multi-session-CviqerRl.d.ts +494 -0
- package/dist/multi-session.d.ts +7 -0
- package/dist/multi-session.js +21 -0
- package/dist/multi-session.js.map +1 -0
- package/dist/nodes-DqhaBW7M.d.ts +195 -0
- package/dist/sessionViewOptions-DLSFRQwZ.d.ts +158 -0
- package/dist/tools-presentation.d.ts +14 -0
- package/dist/tools-presentation.js +37 -0
- package/dist/tools-presentation.js.map +1 -0
- package/dist/tools.d.ts +21 -0
- package/dist/tools.js +43 -0
- package/dist/tools.js.map +1 -0
- package/dist/types-aXj5TYSP.d.ts +33 -0
- package/dist/virtual.d.ts +36 -0
- package/dist/virtual.js +19 -0
- package/dist/virtual.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/view/nodes/ReasoningNode.tsx","../src/view/tools/presentation/StreamingMarkdown.tsx","../src/view/nodes/TextNode.tsx","../src/view/nodes/ToolCallNode.tsx","../src/view/nodes/StepNode.tsx","../src/view/nodes/ErrorNode.tsx","../src/view/nodes/UnknownNode.tsx","../src/view/nodes/PermissionNode.tsx","../src/view/nodes/MemorySavedNode.tsx","../src/view/NodeRegistry.ts","../src/view/defaultRegistry.ts","../src/core/sessionStore.ts","../src/core/dedupe.ts","../src/view/MultiAgentSession.tsx"],"sourcesContent":["/**\n * 职责:ReasoningNode — 对齐 CC AssistantTextMessage / CLI assistant_message。\n * 正文前加 BLACK_CIRCLE(●);streaming 时圆点闪烁;正常字色、不折叠。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n/** 对齐 CC constants/figures.ts BLACK_CIRCLE · CLI assistant_message._BLACK_CIRCLE */\nexport const REASONING_DOT = '●';\n\nexport interface ReasoningBubbleProps {\n nodeId: string;\n}\n\nexport function ReasoningBubble({ nodeId }: ReasoningBubbleProps) {\n const node = useNodeTyped(nodeId, 'reasoning');\n if (!node) return null;\n\n const text = node.accumulated.trim();\n if (!text) return null;\n\n return (\n <div className=\"lax-reasoning-bubble\" data-status={node.status} data-round-id={node.roundId}>\n <div className=\"lax-reasoning-bubble__body\">\n <span className=\"lax-reasoning-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <span className=\"lax-reasoning-bubble__content\">{node.accumulated}</span>\n </div>\n </div>\n );\n}\n","/**\n * StreamingMarkdown.tsx — 流式 markdown 渲染(对齐 CC)\n *\n * CC 实现参考(C:\\git_code\\claude-code-main-ghuntley-03-31\\src\\components\\Markdown.tsx):\n * - 使用 marked.lexer() 解析,更精确的边界跟踪\n * - 模块级 token 缓存(MRU 策略)\n * - 基于 tokens 的精确边界判断\n * - 流式过程中就渲染 markdown\n *\n * 性能优化(对齐 CC):\n * - 快速路径:纯文本跳过 marked.lexer() 调用\n * - Token 缓存:模块级 Map,LRU 淘汰\n * - 边界跟踪:O(unstable length) 而不是 O(full text)\n *\n * 链路位置:TextNode 流式内容渲染\n */\nimport React, { useRef, useMemo, useState } from 'react';\nimport { marked, type Token, type Tokens } from 'marked';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\n// =============================================================================\n// 模块级 Token 缓存(对齐 CC)\n// =============================================================================\n// marked.lexer 是虚拟滚动时的热点成本(~3ms 每条消息)\n// useMemo 无法在 unmount → remount 后存活,导致滚动回历史消息时重新解析\n// 消息在历史中不可变:相同内容 → 相同 tokens\n// 使用内容哈希作为 key,避免保留完整内容字符串(避免 RSS 回归)\nconst TOKEN_CACHE_MAX = 500;\nconst tokenCache = new Map<string, Token[]>();\n\n// =============================================================================\n// 快速路径检测(对齐 CC)\n// =============================================================================\n// 检测 markdown 语法标记。如果没有,跳过 ~3ms 的 marked.lexer 调用\n// 单次正则匹配,而不是 10 次 indexOf 调用\nconst MD_SYNTAX_RE = /[#*`|\\[>\\\\\\-~]|\\n\\n|^\\d+\\. |\\n\\d+\\. /;\n\nfunction hasMarkdownSyntax(s: string): boolean {\n // 检查前 500 字符 — markdown 语法通常在前面(标题、代码块、列表)\n return MD_SYNTAX_RE.test(s.length > 500 ? s.slice(0, 500) : s);\n}\n\n// =============================================================================\n// 内容哈希(用于缓存 key)\n// =============================================================================\nfunction hashContent(content: string): string {\n let hash = 5381;\n for (let i = 0; i < content.length; i++) {\n hash = ((hash << 5) + hash + content.charCodeAt(i)) & 0xffffffff;\n }\n return hash.toString(36);\n}\n\n// =============================================================================\n// Cached Lexer(对齐 CC)\n// =============================================================================\nfunction cachedLexer(content: string): Token[] {\n // 快速路径:纯文本 → 单个 paragraph token\n // 跳过 marked.lexer 的完整 GFM 解析(~3ms)\n if (!hasMarkdownSyntax(content)) {\n return [{\n type: 'paragraph',\n raw: content,\n text: content,\n tokens: [{\n type: 'text',\n raw: content,\n text: content\n }]\n } as Token];\n }\n\n const key = hashContent(content);\n const hit = tokenCache.get(key);\n\n if (hit) {\n // 提升 MRU — 没有 LRU,滚动回早期消息会驱逐正在查看的条目\n tokenCache.delete(key);\n tokenCache.set(key, hit);\n return hit;\n }\n\n const tokens = marked.lexer(content);\n\n if (tokenCache.size >= TOKEN_CACHE_MAX) {\n // LRU-ish: 删除最旧的。Map 保留插入顺序。\n const first = tokenCache.keys().next().value;\n if (first !== undefined) tokenCache.delete(first);\n }\n\n tokenCache.set(key, tokens);\n return tokens;\n}\n\n// =============================================================================\n// Markdown 组件配置(复用)\n// =============================================================================\nconst MARKDOWN_COMPONENTS = {\n code({ node, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '');\n const codeContent = String(children).replace(/\\n$/, '');\n const inline = !className;\n\n if (!inline && match) {\n return (\n <CodeBlock language={match[1]} content={codeContent} />\n );\n }\n\n return (\n <code className=\"lax-markdown__inline-code\" {...props}>\n {children}\n </code>\n );\n },\n h1({ children }: any) { return <h1 className=\"lax-markdown__heading lax-markdown__h1\">{children}</h1>; },\n h2({ children }: any) { return <h2 className=\"lax-markdown__heading lax-markdown__h2\">{children}</h2>; },\n h3({ children }: any) { return <h3 className=\"lax-markdown__heading lax-markdown__h3\">{children}</h3>; },\n h4({ children }: any) { return <h4 className=\"lax-markdown__heading lax-markdown__h4\">{children}</h4>; },\n h5({ children }: any) { return <h5 className=\"lax-markdown__heading lax-markdown__h5\">{children}</h5>; },\n h6({ children }: any) { return <h6 className=\"lax-markdown__heading lax-markdown__h6\">{children}</h6>; },\n p({ children }: any) { return <p className=\"lax-markdown__paragraph\">{children}</p>; },\n ul({ children }: any) { return <ul className=\"lax-markdown__list lax-markdown__ul\">{children}</ul>; },\n ol({ children }: any) { return <ol className=\"lax-markdown__list lax-markdown__ol\">{children}</ol>; },\n li({ children }: any) { return <li className=\"lax-markdown__li\">{children}</li>; },\n a({ children, href }: any) {\n return (\n <a href={href} className=\"lax-markdown__link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n },\n blockquote({ children }: any) { return <blockquote className=\"lax-markdown__blockquote\">{children}</blockquote>; },\n table({ children }: any) {\n return (\n <div className=\"lax-markdown__table-wrapper\">\n <table className=\"lax-markdown__table\">{children}</table>\n </div>\n );\n },\n thead({ children }: any) { return <thead className=\"lax-markdown__thead\">{children}</thead>; },\n tbody({ children }: any) { return <tbody className=\"lax-markdown__tbody\">{children}</tbody>; },\n tr({ children }: any) { return <tr className=\"lax-markdown__tr\">{children}</tr>; },\n th({ children }: any) { return <th className=\"lax-markdown__th\">{children}</th>; },\n td({ children }: any) { return <td className=\"lax-markdown__td\">{children}</td>; },\n hr() { return <hr className=\"lax-markdown__hr\" />; },\n strong({ children }: any) { return <strong className=\"lax-markdown__strong\">{children}</strong>; },\n em({ children }: any) { return <em className=\"lax-markdown__em\">{children}</em>; },\n};\n\n// =============================================================================\n// 代码块组件(带拷贝功能)\n// =============================================================================\ninterface CodeBlockProps {\n language: string;\n content: string;\n}\n\nfunction CodeBlock({ language, content }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n };\n\n return (\n <div className=\"lax-code-block\">\n <div className=\"lax-code-block__header\">\n <span className=\"lax-code-block__lang\">{language || 'code'}</span>\n <button\n type=\"button\"\n className={`lax-code-block__copy ${copied ? 'lax-code-block__copy--copied' : ''}`}\n onClick={handleCopy}\n title={copied ? '已拷贝!' : '拷贝代码'}\n >\n {copied ? (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n <span>已拷贝</span>\n </>\n ) : (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span>拷贝</span>\n </>\n )}\n </button>\n </div>\n <SyntaxHighlighter\n language={language}\n style={oneDark}\n customStyle={{\n margin: 0,\n padding: 0,\n background: 'transparent',\n }}\n showLineNumbers={false}\n wrapLongLines={true}\n >\n {content}\n </SyntaxHighlighter>\n </div>\n );\n}\n\n// =============================================================================\n// Markdown 渲染器(Memoized)\n// =============================================================================\ninterface MarkdownRendererProps {\n content: string;\n}\n\nfunction MarkdownRenderer({ content }: MarkdownRendererProps) {\n if (!content.trim()) {\n return null;\n }\n\n const elements = useMemo(() => {\n const hash = hashContent(content);\n\n // 快速路径:检测 markdown 语法\n if (!hasMarkdownSyntax(content)) {\n return (\n <p key={hash.toString(36)} className=\"lax-markdown__paragraph\">\n {content}\n </p>\n );\n }\n\n // 完整 markdown 渲染\n return (\n <ReactMarkdown\n key={hash.toString(36)}\n remarkPlugins={[remarkGfm]}\n components={MARKDOWN_COMPONENTS}\n >\n {content}\n </ReactMarkdown>\n );\n }, [content]);\n\n return <>{elements}</>;\n}\n\n// =============================================================================\n// StreamingMarkdown 组件(对齐 CC)\n// =============================================================================\n/**\n * 流式过程中渲染 markdown(对齐 CC):\n * - 使用 marked.lexer() 解析不稳定部分\n * - 基于 tokens 精确判断块边界\n * - 稳定前缀 memo 化,不重新解析\n */\nexport interface StreamingMarkdownProps {\n children: string;\n}\n\nexport function StreamingMarkdown({ children }: StreamingMarkdownProps) {\n // React Compiler: 这个组件在 render 时读写 stablePrefixRef.current\n // 边界只前进(单调递增),所以 ref mutation 是幂等的,在 StrictMode 双渲染下安全\n // 但 Compiler 无法证明这一点,memo 会破坏算法(导致边界不更新)。Opt out。\n 'use no memo';\n\n // 边界跟踪 ref - 记录已确认稳定的前缀长度\n const stablePrefixRef = useRef('');\n\n // 如果内容被替换(非增量更新),重置边界\n if (!children.startsWith(stablePrefixRef.current)) {\n stablePrefixRef.current = '';\n }\n\n // 只从当前边界开始解析 — O(unstable length),不是 O(full text)\n const boundary = stablePrefixRef.current.length;\n const tokens = cachedLexer(children.substring(boundary));\n\n // 最后一个非 space token 是增长中的块;之前的都是最终的\n let lastContentIdx = tokens.length - 1;\n while (lastContentIdx >= 0 && tokens[lastContentIdx]!.type === 'space') {\n lastContentIdx--;\n }\n\n let advance = 0;\n for (let i = 0; i < lastContentIdx; i++) {\n advance += tokens[i]!.raw.length;\n }\n\n if (advance > 0) {\n stablePrefixRef.current = children.substring(0, boundary + advance);\n }\n\n const stablePrefix = stablePrefixRef.current;\n const unstableSuffix = children.substring(stablePrefix.length);\n\n return (\n <div className=\"lax-markdown\">\n {/* 稳定前缀:使用内容哈希作为 key,React 会复用已有渲染 */}\n {stablePrefix && (\n <MarkdownRenderer key={`stable-${hashContent(stablePrefix)}`} content={stablePrefix} />\n )}\n {/* 不稳定后缀:每次重新渲染 */}\n {unstableSuffix && (\n <MarkdownRenderer key={`unstable-${hashContent(unstableSuffix)}`} content={unstableSuffix} />\n )}\n </div>\n );\n}\n","/**\n * 职责:默认 TextNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n *\n * 渲染策略(对齐 CC):\n * - Streaming 时显示纯文本(避免高频 markdown 解析)\n * - Done 时使用边界跟踪优化的流式 markdown 渲染\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n// 内置流式 markdown 渲染\nimport { StreamingMarkdown } from '../tools/presentation/StreamingMarkdown';\nimport { REASONING_DOT } from './ReasoningNode';\n\nexport interface TextBubbleProps {\n nodeId: string;\n}\n\nexport function TextBubble({ nodeId }: TextBubbleProps) {\n const node = useNodeTyped(nodeId, 'text');\n if (!node) return null;\n\n // 使用流式 markdown 渲染(对齐 CC:流式过程中就渲染 markdown)\n return (\n <div className=\"lax-text-bubble\" data-status={node.status}>\n <div className=\"lax-text-bubble__body\">\n <span className=\"lax-text-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <div className=\"lax-text-bubble__content lax-text-bubble__content--markdown\">\n <StreamingMarkdown>\n {node.accumulated}\n </StreamingMarkdown>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * 职责:默认 ToolCallNode 主舞台 widget(V3 Shell + resolveToolBody)。\n * 链路位置:NodeRegistry → Timeline。\n * 当前裁剪范围:T4.6 内嵌 permission 等待态(permissionUiMode 控制)。\n */\nimport { useEffect, useState } from 'react';\n\nimport {\n useSessionViewOptions,\n useToolDisplayOptions,\n} from '../../core/context/SessionContext';\nimport { useNodeTyped, usePendingPermissionForTool } from '../../core/hooks';\nimport { resolveEffectiveToolBodyMode } from '../sessionViewOptions';\nimport { formatToolTitle } from '../tools/formatToolTitle';\nimport { resolveToolBody } from '../tools/resolveToolBody';\nimport { ToolCallShell } from '../tools/ToolCallShell';\nimport type { ToolDisplayProps } from '../tools/types';\n\nexport interface ToolCallCardProps {\n nodeId: string;\n layout?: 'default' | 'grouped';\n}\n\nexport function ToolCallCard({ nodeId, layout = 'default' }: ToolCallCardProps) {\n const node = useNodeTyped(nodeId, 'tool_call');\n const { registry, defaultBodyMode } = useToolDisplayOptions();\n const viewOptions = useSessionViewOptions();\n const pendingPermission = usePendingPermissionForTool(node?.toolName ?? '');\n const effectiveDefault = resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode);\n const [bodyMode, setBodyMode] = useState(effectiveDefault);\n\n useEffect(() => {\n setBodyMode(resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode));\n }, [viewOptions.displayMode, viewOptions.verbose, defaultBodyMode]);\n\n if (!node) return null;\n\n // 内部工具(Task* 等)不在 Timeline 显示(对齐 CC renderToolUseMessage 返回 null)\n if (node.hidden) return null;\n\n const details = node.details;\n const inputStream = details?.inputStream ?? node.inputDelta;\n const result = node.result;\n const displayBody = result?.display ?? null;\n const hasSubagentProgress = (node.subagentProgress?.length ?? 0) > 0;\n const showBody =\n hasSubagentProgress || !(node.status === 'running' && result == null);\n\n const BodyComponent = resolveToolBody(node.toolName, displayBody, registry);\n const title = formatToolTitle(\n node.toolName,\n details?.input ?? node.input,\n displayBody,\n result?.summary,\n result?.meta,\n );\n\n const bodyProps: ToolDisplayProps = {\n nodeId,\n toolName: node.toolName,\n status: node.status,\n input: details?.input ?? node.input,\n inputStream,\n result,\n progress: node.progress ?? undefined,\n subagentProgress: node.subagentProgress,\n subagentSessions: node.subagentSessions,\n bodyMode,\n onBodyModeChange: setBodyMode,\n };\n\n const errorMessage = result?.error?.message ?? null;\n const permissionWait =\n viewOptions.permissionUiMode !== 'standalone' && node.status === 'running'\n ? pendingPermission\n : undefined;\n\n return (\n <ToolCallShell\n status={node.status}\n title={title}\n progress={node.progress ?? undefined}\n errorMessage={errorMessage}\n layout={layout}\n permissionWait={permissionWait}\n permissionUiMode={viewOptions.permissionUiMode}\n >\n {showBody ? (\n <div className=\"lax-tool-shell__body\">\n <BodyComponent {...bodyProps} />\n </div>\n ) : null}\n\n </ToolCallShell>\n );\n}\n","/**\n * 职责:默认 StepNode 折叠详情 widget。\n * 链路位置:NodeRegistry;MVP 折叠展示。\n * 当前裁剪范围:简单 label/status;不含复杂编排 UI。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface StepCardProps {\n nodeId: string;\n}\n\nexport function StepCard({ nodeId }: StepCardProps) {\n const node = useNodeTyped(nodeId, 'step');\n if (!node) return null;\n return (\n <details className=\"lax-step-card\" data-status={node.status}>\n <summary className=\"lax-step-card__summary\">{node.label}</summary>\n </details>\n );\n}\n","/**\n * 职责:默认 ErrorNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 message/type;不打断流。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface ErrorCardProps {\n nodeId: string;\n}\n\nexport function ErrorCard({ nodeId }: ErrorCardProps) {\n const node = useNodeTyped(nodeId, 'error');\n if (!node) return null;\n return (\n <div className=\"lax-error-card\" role=\"alert\">\n <div className=\"lax-error-card__message\">{node.message}</div>\n {node.errorType ? (\n <div className=\"lax-error-card__type\">{node.errorType}</div>\n ) : null}\n </div>\n );\n}\n","/**\n * 职责:未知 event_type 兜底 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 eventType 与原始 data JSON。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface UnknownCardProps {\n nodeId: string;\n}\n\nexport function UnknownCard({ nodeId }: UnknownCardProps) {\n const node = useNodeTyped(nodeId, 'unknown');\n if (!node) return null;\n return (\n <div className=\"lax-unknown-card\">\n <div className=\"lax-unknown-card__type\">Unknown: {node.eventType}</div>\n <pre className=\"lax-unknown-card__data\">\n {JSON.stringify(node.rawData, null, 2)}\n </pre>\n </div>\n );\n}\n","/**\n * 职责:默认 PermissionNode 主舞台 widget(V2-D)。\n * 链路位置:NodeRegistry → Timeline;Allow/Deny 经 InteractionBus 回写业务 HTTP。\n * 当前裁剪范围:pending 态按钮;不含 suggestions 列表与 HITL 表单。\n */\nimport { useState } from 'react';\n\nimport { useInteractionBus } from '../../core/context/InteractionContext';\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface PermissionCardProps {\n nodeId: string;\n}\n\nexport function PermissionCard({ nodeId }: PermissionCardProps) {\n const node = useNodeTyped(nodeId, 'permission');\n const bus = useInteractionBus();\n const [resolvedLocally, setResolvedLocally] = useState(false);\n\n if (!node) return null;\n\n const pending = node.status === 'pending' && !resolvedLocally;\n\n const onAllow = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: true });\n setResolvedLocally(true);\n };\n\n const onDeny = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: false });\n setResolvedLocally(true);\n };\n\n return (\n <div\n className=\"lax-permission-card\"\n data-status={pending ? 'pending' : 'resolved'}\n data-request-id={node.requestId}\n >\n <div className=\"lax-permission-card__header\">\n <span className=\"lax-permission-card__label\">Permission</span>\n <span className=\"lax-permission-card__tool\">{node.toolName}</span>\n </div>\n <div className=\"lax-permission-card__message\">{node.message}</div>\n {node.askPrompt && node.askPrompt !== node.message ? (\n <div className=\"lax-permission-card__prompt\">{node.askPrompt}</div>\n ) : null}\n {pending ? (\n <div className=\"lax-permission-card__actions\">\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\n Allow\n </button>\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\n Deny\n </button>\n </div>\n ) : (\n <div className=\"lax-permission-card__resolved\">Resolved</div>\n )}\n </div>\n );\n}\n","/**\n * 职责:MEMORY_SAVED 摘要节点 widget — \"Saved N memories\" 一行折叠展示。\n *\n * 链路位置:\n * NodeRegistry → TimelineItem → 主舞台。\n *\n * 当前裁剪范围:\n * 默认折叠态;writtenPaths 非空时可展开列出路径。\n * 不解析路径语义(绝对 / 相对 / index 文件),由后端 SDK 契约保证。\n *\n * CLI 对照:\n * langchain_agentx_cli/screens/repl.py MemorySavedSummary 一行渲染。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface MemorySavedRowProps {\n nodeId: string;\n}\n\nexport function MemorySavedRow({ nodeId }: MemorySavedRowProps) {\n const node = useNodeTyped(nodeId, 'memory_saved');\n if (!node) return null;\n const hasPaths = node.writtenPaths.length > 0;\n return (\n <details\n className=\"lax-memory-saved\"\n data-testid=\"lax-memory-saved\"\n data-node-id={nodeId}\n >\n <summary className=\"lax-memory-saved__summary\">\n <span className=\"lax-memory-saved__icon\" aria-hidden=\"true\">\n 💾\n </span>\n <span className=\"lax-memory-saved__hint\">{node.displayHint}</span>\n </summary>\n {hasPaths ? (\n <ul className=\"lax-memory-saved__paths\">\n {node.writtenPaths.map((p) => (\n <li key={p} className=\"lax-memory-saved__path\">\n <code>{p}</code>\n </li>\n ))}\n </ul>\n ) : null}\n </details>\n );\n}\n","/**\n * 职责:kind → React widget 映射,支持 override/register 扩展。\n * 链路位置:Timeline 按节点 kind 查找 widget;业务通过 override 替换。\n * 当前裁剪范围:8 类内置 kind + 自定义 register;无插件系统。\n */\nimport type { ComponentType } from 'react';\n\nimport type { SessionNodeKind } from '../types/nodes';\nimport { TextBubble } from './nodes/TextNode';\nimport { ReasoningBubble } from './nodes/ReasoningNode';\nimport { ToolCallCard } from './nodes/ToolCallNode';\nimport { StepCard } from './nodes/StepNode';\nimport { ErrorCard } from './nodes/ErrorNode';\nimport { UnknownCard } from './nodes/UnknownNode';\nimport { PermissionCard } from './nodes/PermissionNode';\nimport { MemorySavedRow } from './nodes/MemorySavedNode';\n\nconst DEFAULT_WIDGETS = new Map<string, NodeWidget>([\n ['text', TextBubble],\n ['reasoning', ReasoningBubble],\n ['tool_call', ToolCallCard],\n ['step', StepCard],\n ['error', ErrorCard],\n ['unknown', UnknownCard],\n ['permission', PermissionCard],\n ['memory_saved', MemorySavedRow],\n]);\n\nexport interface NodeWidgetProps {\n nodeId: string;\n}\n\nexport type NodeWidget = ComponentType<NodeWidgetProps>;\n\nexport class NodeRegistry {\n private readonly widgets: Map<string, NodeWidget>;\n\n constructor(widgets: Map<string, NodeWidget>) {\n this.widgets = widgets;\n }\n\n static default(): NodeRegistry {\n return new NodeRegistry(new Map(DEFAULT_WIDGETS));\n }\n\n override(kind: SessionNodeKind | string, widget: NodeWidget): NodeRegistry {\n const next = new Map(this.widgets);\n next.set(kind, widget);\n return new NodeRegistry(next);\n }\n\n register(kind: string, widget: NodeWidget): NodeRegistry {\n return this.override(kind, widget);\n }\n\n get(kind: string): NodeWidget | undefined {\n return this.widgets.get(kind);\n }\n\n has(kind: string): boolean {\n return this.widgets.has(kind);\n }\n}\n","/**\n * 职责:默认 registry 工厂别名,供 AgentSession 内部使用。\n * 链路位置:AgentSession 未传 registry 时的 fallback。\n * 当前裁剪范围:委托 NodeRegistry.default()。\n */\nimport { NodeRegistry } from './NodeRegistry';\n\nexport function createDefaultRegistry(): NodeRegistry {\n return NodeRegistry.default();\n}\n","/**\n * 职责:多会话顶层 store,按 sessionId 路由事件到独立 SessionTree。\n * 链路位置:MultiAgentSession 消费;业务也可直接 createMultiSessionStore。\n * 当前裁剪范围:进程内 LRU(默认 10);不含 Source 生命周期管理。\n */\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport { createEmptyTree, type ReducerError, type SessionTree } from '../types/tree';\nimport { replayEvents } from './replay';\nimport { reduceTree, type ReduceOptions } from './reducer';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport type { SessionStoreState } from './store';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface SessionSlice {\n tree: SessionTree;\n eventCount: number;\n}\n\nexport interface MultiSessionStoreOptions {\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n /** 初始活跃 session;默认 null */\n activeSessionId?: string | null;\n}\n\nexport interface MultiSessionStoreState {\n sessions: Record<string, SessionSlice>;\n activeSessionId: string | null;\n order: string[];\n applyEvent: (sessionId: string, event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (sessionId: string, events: LangchainAgentEvent[]) => void;\n setActiveSessionId: (id: string | null) => void;\n removeSession: (id: string) => void;\n replaySession: (sessionId: string, events: LangchainAgentEvent[]) => void;\n ensureSession: (sessionId: string, initialEvents?: LangchainAgentEvent[]) => void;\n getSessionTree: (sessionId: string) => SessionTree | undefined;\n}\n\nconst DEFAULT_MAX_SESSIONS = 10;\n\nfunction touchOrder(order: string[], sessionId: string): string[] {\n return [...order.filter((id) => id !== sessionId), sessionId];\n}\n\nfunction safeReduce(\n tree: SessionTree,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): SessionTree {\n try {\n return reduceTree(tree, event, eventIndex, options);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] reducer error:', err);\n }\n const reducerError: ReducerError = {\n eventIndex,\n eventType: event.event_type,\n message,\n stack,\n };\n return {\n ...tree,\n internalErrors: [...tree.internalErrors, reducerError],\n };\n }\n}\n\nfunction evictSessions(\n sessions: Record<string, SessionSlice>,\n order: string[],\n maxSessions: number,\n activeSessionId: string | null,\n): { sessions: Record<string, SessionSlice>; order: string[] } {\n let nextSessions = { ...sessions };\n let nextOrder = [...order];\n while (nextOrder.length > maxSessions) {\n const candidate = nextOrder.find((id) => id !== activeSessionId) ?? nextOrder[0];\n if (!candidate) break;\n const { [candidate]: _removed, ...rest } = nextSessions;\n nextSessions = rest;\n nextOrder = nextOrder.filter((id) => id !== candidate);\n }\n return { sessions: nextSessions, order: nextOrder };\n}\n\nexport function createMultiSessionStore(\n options?: MultiSessionStoreOptions,\n): StoreApi<MultiSessionStoreState> {\n const maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;\n const reduceOpts: ReduceOptions = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const replayOpts = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const seenBySession = new Map<string, Set<string>>();\n\n function getSeenSet(sessionId: string): Set<string> {\n let set = seenBySession.get(sessionId);\n if (!set) {\n set = new Set<string>();\n seenBySession.set(sessionId, set);\n }\n return set;\n }\n\n return createStore<MultiSessionStoreState>((set, get) => ({\n sessions: {},\n activeSessionId: options?.activeSessionId ?? null,\n order: [],\n\n getSessionTree(sessionId) {\n return get().sessions[sessionId]?.tree;\n },\n\n ensureSession(sessionId, initialEvents) {\n const state = get();\n if (state.sessions[sessionId]) return;\n\n const tree =\n initialEvents && initialEvents.length > 0\n ? replayEvents(initialEvents, replayOpts)\n : createEmptyTree();\n const slice: SessionSlice = {\n tree,\n eventCount: initialEvents?.length ?? 0,\n };\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n\n set({\n sessions,\n order,\n activeSessionId: state.activeSessionId ?? sessionId,\n });\n },\n\n applyEvent(sessionId, event, ctx) {\n const sseEventId = ctx?.sseEventId;\n const seen = getSeenSet(sessionId);\n if (shouldSkipDuplicateEvent(seen, sseEventId)) return;\n\n const state = get();\n let slice = state.sessions[sessionId];\n if (!slice) {\n get().ensureSession(sessionId);\n slice = get().sessions[sessionId]!;\n }\n const reduced = safeReduce(slice.tree, event, slice.eventCount, reduceOpts);\n const nextTree: SessionTree =\n sseEventId\n ? { ...reduced, meta: { ...reduced.meta, lastEventId: sseEventId } }\n : reduced;\n const nextSlice: SessionSlice = {\n tree: nextTree,\n eventCount: slice.eventCount + 1,\n };\n markEventIdSeen(seen, sseEventId);\n let sessions = { ...state.sessions, [sessionId]: nextSlice };\n let order = touchOrder(state.order, sessionId);\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n\n applyEvents(sessionId, events) {\n for (const event of events) {\n get().applyEvent(sessionId, event);\n }\n },\n\n setActiveSessionId(id) {\n set({ activeSessionId: id });\n },\n\n removeSession(sessionId) {\n const state = get();\n if (!state.sessions[sessionId]) return;\n seenBySession.delete(sessionId);\n const { [sessionId]: _removed, ...sessions } = state.sessions;\n const order = state.order.filter((id) => id !== sessionId);\n const activeSessionId =\n state.activeSessionId === sessionId\n ? (order[order.length - 1] ?? null)\n : state.activeSessionId;\n set({ sessions, order, activeSessionId });\n },\n\n replaySession(sessionId, events) {\n const tree = replayEvents(events, replayOpts);\n const slice: SessionSlice = { tree, eventCount: events.length };\n const state = get();\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n }));\n}\n\nexport type MultiSessionStore = StoreApi<MultiSessionStoreState>;\n\n/** 将 MultiSessionStore 活跃会话投影为 SessionStore,供 Timeline hooks 复用。 */\nexport function createActiveSessionBridge(multiStore: MultiSessionStore): StoreApi<SessionStoreState> {\n type BridgeState = Pick<SessionStoreState, 'tree' | 'eventCount' | 'applyEvent' | 'applyEvents' | 'reset'>;\n\n const bridge = createStore<BridgeState>(() => ({\n tree: createEmptyTree(),\n eventCount: 0,\n applyEvent(event, ctx) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvent(id, event, ctx);\n },\n applyEvents(events) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvents(id, events);\n },\n reset() {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().replaySession(id, []);\n },\n }));\n\n const sync = (): void => {\n const { activeSessionId, sessions } = multiStore.getState();\n const slice = activeSessionId ? sessions[activeSessionId] : undefined;\n bridge.setState({\n tree: slice?.tree ?? createEmptyTree(),\n eventCount: slice?.eventCount ?? 0,\n });\n };\n\n multiStore.subscribe(sync);\n sync();\n return bridge as StoreApi<SessionStoreState>;\n}\n","/**\n * 职责:SSE 事件 id 幂等去重(M4 续传重叠帧)。\n * 链路位置:SessionStore / MultiSessionStore applyEvent 前置检查。\n * 当前裁剪范围:按 sseEventId 字符串去重;无 id 时始终应用。\n */\n\nexport function shouldSkipDuplicateEvent(\n seenEventIds: ReadonlySet<string>,\n sseEventId: string | undefined,\n): boolean {\n if (!sseEventId) return false;\n return seenEventIds.has(sseEventId);\n}\n\nexport function markEventIdSeen(\n seenEventIds: Set<string>,\n sseEventId: string | undefined,\n): void {\n if (sseEventId) seenEventIds.add(sseEventId);\n}\n","/**\n * 职责:多会话顶层容器,每 session 独立 Source + initialEvents,共享 MultiSessionStore。\n * 链路位置:业务多 Tab / 双路 SSE;Timeline 只渲染 activeSessionId 对应树。\n * 当前裁剪范围:薄封装;Source 生命周期由本组件管理;LRU 默认 10。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport {\n createMultiSessionStore,\n createActiveSessionBridge,\n type MultiSessionStore,\n} from '../core/sessionStore';\nimport {\n MultiSessionStoreContext,\n SessionStoreContext,\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../core/context/SessionContext';\nimport type { Source } from '../transport/types';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError } from '../types/tree';\nimport { createDefaultRegistry } from './defaultRegistry';\nimport type { NodeRegistry } from './NodeRegistry';\nimport { SessionTimeline } from './SessionTimeline';\nimport { InteractionBusContext } from '../core/context/InteractionContext';\nimport type { InteractionBus } from '../core/interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../core/interaction/InteractionBus';\nimport { useInternalErrors, useSessionStatus } from '../core/hooks';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from './tools/registry';\nimport type { ToolBodyMode } from './tools/types';\nimport type { MarkdownRenderer } from '../core/context/MarkdownRendererContext';\nimport { MarkdownRendererContext } from '../core/context/MarkdownRendererContext';\nimport type { PermissionUiMode } from './sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from './sessionViewOptions';\n\nexport interface MultiSessionSourceConfig {\n sessionId: string;\n source: Source;\n /** EventBuffer ingest 快照或历史事件;挂载时 replay 后再接 source 续流(M3) */\n initialEvents?: LangchainAgentEvent[];\n}\n\nexport interface MultiAgentSessionProps {\n sessions: MultiSessionSourceConfig[];\n /** 受控活跃 session */\n activeSessionId?: string | null;\n /** 非受控默认活跃 session */\n defaultActiveSessionId?: string | null;\n onActiveSessionChange?: (sessionId: string | null) => void;\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n registry?: NodeRegistry;\n onError?: (error: Error, sessionId: string) => void;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n interactionBus?: InteractionBus;\n toolDisplayRegistry?: ToolDisplayRegistry;\n defaultBodyMode?: ToolBodyMode;\n groupParallelTools?: boolean;\n permissionUiMode?: PermissionUiMode;\n markdownRenderer?: MarkdownRenderer;\n children?: ReactNode;\n}\n\nfunction DebugPanel() {\n const status = useSessionStatus();\n const errors = useInternalErrors();\n if (errors.length === 0) return null;\n return (\n <div className=\"lax-debug-panel\" data-testid=\"lax-debug-panel\">\n <div>status: {status}</div>\n <ul>\n {errors.map((err: ReducerError, i: number) => (\n <li key={`${err.eventIndex}-${i}`}>\n [{err.eventType}] {err.message}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\nexport function MultiAgentSession({\n sessions,\n activeSessionId: controlledActiveId,\n defaultActiveSessionId,\n onActiveSessionChange,\n maxSessions,\n tierOverrides,\n debug = false,\n registry,\n onError,\n virtualized = false,\n virtualizeThreshold,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n groupParallelTools = false,\n permissionUiMode = 'standalone',\n markdownRenderer,\n children,\n}: MultiAgentSessionProps) {\n const multiStoreRef = useRef<MultiSessionStore | null>(null);\n const bridgeRef = useRef<ReturnType<typeof createActiveSessionBridge> | null>(null);\n\n if (multiStoreRef.current === null) {\n const defaultId =\n defaultActiveSessionId ??\n controlledActiveId ??\n sessions[0]?.sessionId ??\n null;\n multiStoreRef.current = createMultiSessionStore({\n maxSessions,\n tierOverrides,\n debug,\n activeSessionId: defaultId,\n });\n bridgeRef.current = createActiveSessionBridge(multiStoreRef.current);\n for (const cfg of sessions) {\n multiStoreRef.current.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n }\n }\n\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n verboseReasoning: debug,\n }),\n [groupParallelTools, permissionUiMode, debug],\n );\n\n useEffect(() => {\n if (controlledActiveId === undefined) return;\n multiStoreRef.current!.getState().setActiveSessionId(controlledActiveId);\n }, [controlledActiveId]);\n\n useEffect(() => {\n if (!onActiveSessionChange) return;\n return multiStoreRef.current!.subscribe((state) => {\n onActiveSessionChange(state.activeSessionId);\n });\n }, [onActiveSessionChange]);\n\n useEffect(() => {\n const multiStore = multiStoreRef.current!;\n const controllers = sessions.map((cfg) => {\n const controller = new AbortController();\n multiStore.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n void cfg.source.start((event, ctx) => {\n multiStore.getState().applyEvent(cfg.sessionId, event, ctx);\n }, controller.signal).catch((err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error, cfg.sessionId);\n });\n return controller;\n });\n return () => {\n for (const c of controllers) c.abort();\n };\n }, [sessions, onError]);\n\n return (\n <MultiSessionStoreContext.Provider value={multiStoreRef.current!}>\n <SessionStoreContext.Provider value={bridgeRef.current!}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div className=\"lax-agent-session lax-multi-agent-session\" data-testid=\"lax-multi-agent-session\">\n {children ?? (\n <SessionTimeline\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n )}\n {debug ? <DebugPanel /> : null}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </SessionStoreContext.Provider>\n </MultiSessionStoreContext.Provider>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","useState","jsx","useState","jsx","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","useEffect","useMemo","useRef","jsx","jsxs","useRef","useMemo","useEffect"]}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import {
|
|
2
|
+
truncatePreview
|
|
3
|
+
} from "./chunk-DP7V33X7.js";
|
|
4
|
+
import {
|
|
5
|
+
Agent,
|
|
6
|
+
AskUserQuestion,
|
|
7
|
+
Bash,
|
|
8
|
+
Edit,
|
|
9
|
+
Glob,
|
|
10
|
+
Grep,
|
|
11
|
+
Read,
|
|
12
|
+
Skill,
|
|
13
|
+
WebFetch,
|
|
14
|
+
WebSearch,
|
|
15
|
+
Write,
|
|
16
|
+
asDisplayRecord,
|
|
17
|
+
asInputRecord,
|
|
18
|
+
formatAgentTitle,
|
|
19
|
+
numField,
|
|
20
|
+
strField
|
|
21
|
+
} from "./chunk-MHK53ZHC.js";
|
|
22
|
+
import {
|
|
23
|
+
TruncatedContent,
|
|
24
|
+
displayPath,
|
|
25
|
+
formatBashTitle,
|
|
26
|
+
formatPatternTitle
|
|
27
|
+
} from "./chunk-4RIOBLGB.js";
|
|
28
|
+
|
|
29
|
+
// src/view/tools/ask_user_question/formatAskUserQuestionTitle.ts
|
|
30
|
+
function firstQuestion(display, input) {
|
|
31
|
+
const items = display?.questions;
|
|
32
|
+
if (Array.isArray(items) && items.length > 0) {
|
|
33
|
+
const first = items[0];
|
|
34
|
+
if (first != null && typeof first === "object") {
|
|
35
|
+
const row = first;
|
|
36
|
+
return {
|
|
37
|
+
header: String(row.header ?? "").trim(),
|
|
38
|
+
question: String(row.question ?? "").trim()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const questions = input.questions;
|
|
43
|
+
if (Array.isArray(questions) && questions.length > 0) {
|
|
44
|
+
const first = questions[0];
|
|
45
|
+
if (first != null && typeof first === "object") {
|
|
46
|
+
const row = first;
|
|
47
|
+
return {
|
|
48
|
+
header: String(row.header ?? "").trim(),
|
|
49
|
+
question: String(row.question ?? "").trim()
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { header: "", question: "" };
|
|
54
|
+
}
|
|
55
|
+
function formatAskUserQuestionTitle(input, display, _summary) {
|
|
56
|
+
const d = asDisplayRecord(display);
|
|
57
|
+
const inp = asInputRecord(input);
|
|
58
|
+
const { header, question } = firstQuestion(d, inp);
|
|
59
|
+
if (question) {
|
|
60
|
+
const label = header ? `[${header}] ${question}` : question;
|
|
61
|
+
return truncatePreview(label, 100);
|
|
62
|
+
}
|
|
63
|
+
const answered = numField(d ?? {}, "answered_count");
|
|
64
|
+
if (answered != null) return `Ask user (${answered} answered)`;
|
|
65
|
+
return "Ask user";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/view/tools/edit/formatEditTitle.ts
|
|
69
|
+
function editAction(input) {
|
|
70
|
+
const inp = asInputRecord(input);
|
|
71
|
+
if (Array.isArray(inp.edits) && inp.edits.length > 0) return "Update";
|
|
72
|
+
if ("old_string" in inp && inp.old_string === "") return "Create";
|
|
73
|
+
return "Update";
|
|
74
|
+
}
|
|
75
|
+
function formatEditTitle(input, display, _summary) {
|
|
76
|
+
const inp = asInputRecord(input);
|
|
77
|
+
const d = display != null && typeof display === "object" && !Array.isArray(display) ? display : null;
|
|
78
|
+
const path = displayPath(
|
|
79
|
+
strField(d ?? {}, "file_path") || strField(inp, "file_path")
|
|
80
|
+
);
|
|
81
|
+
const action = editAction(inp);
|
|
82
|
+
if (!path) return action;
|
|
83
|
+
return `${action}(${path})`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/view/tools/glob/formatGlobTitle.ts
|
|
87
|
+
function formatGlobTitle(input, display, _summary) {
|
|
88
|
+
const d = asDisplayRecord(display);
|
|
89
|
+
const inp = asInputRecord(input);
|
|
90
|
+
const pattern = strField(d ?? {}, "pattern") || strField(inp, "pattern");
|
|
91
|
+
if (!pattern) return "Search";
|
|
92
|
+
const path = strField(inp, "path") || void 0;
|
|
93
|
+
const suffix = formatPatternTitle(pattern, path);
|
|
94
|
+
const numFiles = numField(d ?? {}, "num_files");
|
|
95
|
+
const countHint = numFiles != null ? ` \xB7 ${numFiles} files` : "";
|
|
96
|
+
return `Search(${suffix}${countHint})`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/view/tools/grep/formatGrepTitle.ts
|
|
100
|
+
function formatGrepTitle(input, display, _summary) {
|
|
101
|
+
const d = asDisplayRecord(display);
|
|
102
|
+
const inp = asInputRecord(input);
|
|
103
|
+
const pattern = strField(d ?? {}, "pattern") || strField(inp, "pattern");
|
|
104
|
+
if (!pattern) return "Search";
|
|
105
|
+
const path = strField(inp, "path") || void 0;
|
|
106
|
+
const suffix = formatPatternTitle(pattern, path);
|
|
107
|
+
const numMatches = numField(d ?? {}, "num_matches");
|
|
108
|
+
const countHint = numMatches != null ? ` \xB7 ${numMatches} matches` : "";
|
|
109
|
+
return `Search(${suffix}${countHint})`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/view/tools/read/formatReadTitle.ts
|
|
113
|
+
var LINES_RANGE_RE = /lines (\d+)-(\d+) of (\d+)/;
|
|
114
|
+
var READ_LINES_RE = /Read (\d+) lines from/;
|
|
115
|
+
function titleSuffixFromDisplay(display) {
|
|
116
|
+
const d = asDisplayRecord(display);
|
|
117
|
+
if (!d) return "";
|
|
118
|
+
if (d.type === "text") {
|
|
119
|
+
const start = numField(d, "line_start");
|
|
120
|
+
const end = numField(d, "line_end");
|
|
121
|
+
if (start != null && end != null) {
|
|
122
|
+
return ` \xB7 lines ${start}-${end}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (d.type === "pdf") {
|
|
126
|
+
const ps = numField(d, "page_start");
|
|
127
|
+
const pe = numField(d, "page_end");
|
|
128
|
+
if (ps != null && pe != null) {
|
|
129
|
+
return ` \xB7 pages ${ps}-${pe}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return "";
|
|
133
|
+
}
|
|
134
|
+
function titleSuffixFromSummary(summary, input) {
|
|
135
|
+
const matchRange = summary.match(LINES_RANGE_RE);
|
|
136
|
+
if (matchRange) {
|
|
137
|
+
return ` \xB7 lines ${matchRange[1]}-${matchRange[2]}`;
|
|
138
|
+
}
|
|
139
|
+
const inp = asInputRecord(input);
|
|
140
|
+
const offset = numField(inp, "offset");
|
|
141
|
+
const limit = numField(inp, "limit");
|
|
142
|
+
if (offset != null && limit != null) {
|
|
143
|
+
return ` \xB7 lines ${offset}-${offset + limit - 1}`;
|
|
144
|
+
}
|
|
145
|
+
const matchLines = summary.match(READ_LINES_RE);
|
|
146
|
+
if (matchLines) {
|
|
147
|
+
return ` \xB7 ${matchLines[1]} lines`;
|
|
148
|
+
}
|
|
149
|
+
return "";
|
|
150
|
+
}
|
|
151
|
+
function formatReadTitle(input, display, summary) {
|
|
152
|
+
const d = asDisplayRecord(display);
|
|
153
|
+
const inp = asInputRecord(input);
|
|
154
|
+
const path = displayPath(
|
|
155
|
+
strField(d ?? {}, "file_path") || strField(inp, "file_path") || strField(inp, "path")
|
|
156
|
+
);
|
|
157
|
+
const suffix = titleSuffixFromDisplay(display) || (summary ? titleSuffixFromSummary(summary, input) : "");
|
|
158
|
+
if (!path) {
|
|
159
|
+
return suffix ? `Read(${suffix.trim()})` : "Read";
|
|
160
|
+
}
|
|
161
|
+
return `Read(${path}${suffix})`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/view/tools/skill/formatSkillTitle.ts
|
|
165
|
+
function formatSkillTitle(input, display, _summary) {
|
|
166
|
+
const d = asDisplayRecord(display);
|
|
167
|
+
const inp = asInputRecord(input);
|
|
168
|
+
const name = strField(d ?? {}, "skill_name") || strField(inp, "skill_name");
|
|
169
|
+
if (!name) return "Skill";
|
|
170
|
+
if (d?.source === "commands_DEPRECATED") {
|
|
171
|
+
return `/${name}`;
|
|
172
|
+
}
|
|
173
|
+
return name;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/view/tools/webfetch/formatWebFetchTitle.ts
|
|
177
|
+
function formatWebFetchTitle(input, display, _summary) {
|
|
178
|
+
const d = asDisplayRecord(display);
|
|
179
|
+
const inp = asInputRecord(input);
|
|
180
|
+
const url = strField(d ?? {}, "url") || strField(inp, "url");
|
|
181
|
+
if (!url) return "Fetch";
|
|
182
|
+
const code = numField(d ?? {}, "http_code");
|
|
183
|
+
const title = code != null ? `${url} \xB7 HTTP ${code}` : truncatePreview(url, 100);
|
|
184
|
+
return `Fetch(${title})`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/view/tools/websearch/formatWebSearchTitle.ts
|
|
188
|
+
function formatWebSearchTitle(input, display, _summary) {
|
|
189
|
+
const d = asDisplayRecord(display);
|
|
190
|
+
const inp = asInputRecord(input);
|
|
191
|
+
const query = strField(d ?? {}, "query") || strField(inp, "query");
|
|
192
|
+
if (!query) return "Web Search";
|
|
193
|
+
let queryPart = `"${truncatePreview(query, 100)}"`;
|
|
194
|
+
const hits = numField(d ?? {}, "total_hits");
|
|
195
|
+
if (hits != null) queryPart = `${queryPart} \xB7 ${hits} hits`;
|
|
196
|
+
return `Web Search(${queryPart})`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/view/tools/write/formatWriteTitle.ts
|
|
200
|
+
function formatWriteTitle(input, display, _summary) {
|
|
201
|
+
const inp = asInputRecord(input);
|
|
202
|
+
const d = asDisplayRecord(display);
|
|
203
|
+
const path = displayPath(
|
|
204
|
+
strField(d ?? {}, "file_path") || strField(inp, "file_path")
|
|
205
|
+
);
|
|
206
|
+
if (!path) return "Write";
|
|
207
|
+
return `Write(${path})`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/view/tools/formatToolTitle.ts
|
|
211
|
+
var TITLE_FORMATTERS = {
|
|
212
|
+
[Read]: formatReadTitle,
|
|
213
|
+
[Grep]: formatGrepTitle,
|
|
214
|
+
[Glob]: formatGlobTitle,
|
|
215
|
+
[Edit]: formatEditTitle,
|
|
216
|
+
[Write]: formatWriteTitle,
|
|
217
|
+
[Bash]: formatBashTitle,
|
|
218
|
+
[Agent]: formatAgentTitle,
|
|
219
|
+
[Skill]: formatSkillTitle,
|
|
220
|
+
[WebSearch]: formatWebSearchTitle,
|
|
221
|
+
[WebFetch]: formatWebFetchTitle,
|
|
222
|
+
[AskUserQuestion]: formatAskUserQuestionTitle
|
|
223
|
+
};
|
|
224
|
+
function formatToolTitle(toolName, input, display, summary, meta) {
|
|
225
|
+
const formatter = TITLE_FORMATTERS[toolName];
|
|
226
|
+
if (formatter) {
|
|
227
|
+
return formatter(input, display, summary, meta);
|
|
228
|
+
}
|
|
229
|
+
return toolName;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/view/tools/DefaultToolBody.tsx
|
|
233
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
234
|
+
function formatDisplayJson(display) {
|
|
235
|
+
if (display == null) return "";
|
|
236
|
+
if (typeof display === "string") return display;
|
|
237
|
+
try {
|
|
238
|
+
return JSON.stringify(display, null, 2);
|
|
239
|
+
} catch {
|
|
240
|
+
return String(display);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function extractTextContent(display) {
|
|
244
|
+
if (display == null) return null;
|
|
245
|
+
if (typeof display === "string") return display;
|
|
246
|
+
if (typeof display === "object") {
|
|
247
|
+
const record = display;
|
|
248
|
+
if (typeof record.content === "string") return record.content;
|
|
249
|
+
if (typeof record.text === "string") return record.text;
|
|
250
|
+
}
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
function DefaultToolBody({
|
|
254
|
+
result,
|
|
255
|
+
bodyMode,
|
|
256
|
+
onBodyModeChange
|
|
257
|
+
}) {
|
|
258
|
+
const summary = result?.summary;
|
|
259
|
+
const displayBody = result?.display ?? null;
|
|
260
|
+
const textContent = extractTextContent(displayBody);
|
|
261
|
+
const jsonBody = textContent ?? formatDisplayJson(displayBody);
|
|
262
|
+
return /* @__PURE__ */ jsxs("div", { className: "lax-tool-body lax-tool-body--default", children: [
|
|
263
|
+
summary ? /* @__PURE__ */ jsx("div", { className: "lax-tool-card__summary", children: summary }) : null,
|
|
264
|
+
displayBody != null && displayBody !== "" && jsonBody ? /* @__PURE__ */ jsx("div", { className: "lax-tool-card__display", children: textContent != null ? /* @__PURE__ */ jsx(
|
|
265
|
+
TruncatedContent,
|
|
266
|
+
{
|
|
267
|
+
text: textContent,
|
|
268
|
+
mode: bodyMode,
|
|
269
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
270
|
+
}
|
|
271
|
+
) : /* @__PURE__ */ jsx("pre", { className: "lax-tool-card__display-body", children: jsonBody }) }) : null,
|
|
272
|
+
result?.truncated ? /* @__PURE__ */ jsx("div", { className: "lax-tool-card__truncated", children: "\u7ED3\u679C\u5DF2\u622A\u65AD" }) : null,
|
|
273
|
+
result?.overflow_file ? /* @__PURE__ */ jsxs("div", { className: "lax-tool-card__overflow", children: [
|
|
274
|
+
"\u5B8C\u6574\u8F93\u51FA\uFF1A",
|
|
275
|
+
/* @__PURE__ */ jsx("code", { children: result.overflow_file })
|
|
276
|
+
] }) : null
|
|
277
|
+
] });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/view/tools/resolveToolBody.ts
|
|
281
|
+
var DISPLAY_KIND_ROUTER = /* @__PURE__ */ new Map();
|
|
282
|
+
function getDisplayType(display) {
|
|
283
|
+
if (display == null || typeof display !== "object") return void 0;
|
|
284
|
+
const type = display.type;
|
|
285
|
+
return typeof type === "string" ? type : void 0;
|
|
286
|
+
}
|
|
287
|
+
function resolveToolBody(toolName, display, registry) {
|
|
288
|
+
const byName = registry.resolve(toolName);
|
|
289
|
+
if (byName) return byName;
|
|
290
|
+
const displayType = getDisplayType(display);
|
|
291
|
+
if (displayType) {
|
|
292
|
+
const byKind = DISPLAY_KIND_ROUTER.get(displayType);
|
|
293
|
+
if (byKind) return byKind;
|
|
294
|
+
}
|
|
295
|
+
return DefaultToolBody;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/core/interaction/InteractionBus.ts
|
|
299
|
+
var noopBus = {
|
|
300
|
+
resolvePermission() {
|
|
301
|
+
if (import.meta.env?.DEV) {
|
|
302
|
+
console.warn("[langchain_agentx_stream_ui] resolvePermission without InteractionBus");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
function createInteractionBus(handlers = {}) {
|
|
307
|
+
return {
|
|
308
|
+
resolvePermission(payload) {
|
|
309
|
+
return handlers.onPermissionResolve?.(payload);
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function getNoopInteractionBus() {
|
|
314
|
+
return noopBus;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/core/context/InteractionContext.tsx
|
|
318
|
+
import { createContext, useContext } from "react";
|
|
319
|
+
var InteractionBusContext = createContext(getNoopInteractionBus());
|
|
320
|
+
function useInteractionBus() {
|
|
321
|
+
return useContext(InteractionBusContext);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/view/tools/ToolPermissionWait.tsx
|
|
325
|
+
import { useState } from "react";
|
|
326
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
327
|
+
function ToolPermissionWait({ permission, mode }) {
|
|
328
|
+
const bus = useInteractionBus();
|
|
329
|
+
const [resolvedLocally, setResolvedLocally] = useState(false);
|
|
330
|
+
if (permission.status !== "pending" || resolvedLocally) return null;
|
|
331
|
+
const showActions = mode === "inline" || mode === "both";
|
|
332
|
+
const onAllow = () => {
|
|
333
|
+
void bus.resolvePermission({ requestId: permission.requestId, allow: true });
|
|
334
|
+
setResolvedLocally(true);
|
|
335
|
+
};
|
|
336
|
+
const onDeny = () => {
|
|
337
|
+
void bus.resolvePermission({ requestId: permission.requestId, allow: false });
|
|
338
|
+
setResolvedLocally(true);
|
|
339
|
+
};
|
|
340
|
+
return /* @__PURE__ */ jsxs2("div", { className: "lax-tool-shell__permission-wait", role: "status", children: [
|
|
341
|
+
/* @__PURE__ */ jsx2("div", { className: "lax-tool-shell__permission-wait-text", children: "Waiting for permission\u2026" }),
|
|
342
|
+
permission.message ? /* @__PURE__ */ jsx2("div", { className: "lax-tool-shell__permission-wait-detail", children: permission.message }) : null,
|
|
343
|
+
showActions ? /* @__PURE__ */ jsxs2("div", { className: "lax-tool-shell__permission-actions", children: [
|
|
344
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "lax-permission-card__allow", onClick: onAllow, children: "Allow" }),
|
|
345
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "lax-permission-card__deny", onClick: onDeny, children: "Deny" })
|
|
346
|
+
] }) : null
|
|
347
|
+
] });
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/view/tools/ToolCallShell.tsx
|
|
351
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
352
|
+
function ToolCallShell({
|
|
353
|
+
status,
|
|
354
|
+
title,
|
|
355
|
+
progress,
|
|
356
|
+
errorMessage,
|
|
357
|
+
layout = "default",
|
|
358
|
+
permissionWait,
|
|
359
|
+
permissionUiMode = "standalone",
|
|
360
|
+
children
|
|
361
|
+
}) {
|
|
362
|
+
const bare = !title.trim();
|
|
363
|
+
const waitingForPermission = permissionWait && permissionUiMode !== "standalone" && (status === "running" || status === "failed");
|
|
364
|
+
return /* @__PURE__ */ jsxs3(
|
|
365
|
+
"div",
|
|
366
|
+
{
|
|
367
|
+
className: [
|
|
368
|
+
"lax-tool-card",
|
|
369
|
+
"lax-tool-shell",
|
|
370
|
+
bare ? "lax-tool-shell--bare" : "",
|
|
371
|
+
layout === "grouped" ? "lax-tool-shell--grouped" : "",
|
|
372
|
+
waitingForPermission ? "lax-tool-shell--permission-wait" : ""
|
|
373
|
+
].filter(Boolean).join(" "),
|
|
374
|
+
"data-status": status,
|
|
375
|
+
"data-error-kind": errorMessage ? "error" : waitingForPermission ? "permission" : void 0,
|
|
376
|
+
children: [
|
|
377
|
+
!bare ? /* @__PURE__ */ jsxs3("div", { className: "lax-tool-shell__header lax-tool-card__header", children: [
|
|
378
|
+
/* @__PURE__ */ jsxs3(
|
|
379
|
+
"span",
|
|
380
|
+
{
|
|
381
|
+
className: "lax-tool-shell__status-dot lax-tool-card__status-dot",
|
|
382
|
+
"data-status": status,
|
|
383
|
+
"aria-hidden": true,
|
|
384
|
+
children: [
|
|
385
|
+
"\u25CF",
|
|
386
|
+
" "
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
/* @__PURE__ */ jsx3("span", { className: "lax-tool-shell__title lax-tool-card__name", children: title })
|
|
391
|
+
] }) : null,
|
|
392
|
+
progress ? /* @__PURE__ */ jsx3("div", { className: "lax-tool-shell__progress lax-tool-card__progress", children: progress.message ?? `${progress.current}/${progress.total}` }) : null,
|
|
393
|
+
waitingForPermission && permissionWait ? /* @__PURE__ */ jsx3(ToolPermissionWait, { permission: permissionWait, mode: permissionUiMode }) : null,
|
|
394
|
+
children,
|
|
395
|
+
errorMessage && status === "failed" ? /* @__PURE__ */ jsx3("div", { className: "lax-tool-card__error", role: "alert", children: errorMessage }) : null
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export {
|
|
402
|
+
formatToolTitle,
|
|
403
|
+
DefaultToolBody,
|
|
404
|
+
resolveToolBody,
|
|
405
|
+
createInteractionBus,
|
|
406
|
+
getNoopInteractionBus,
|
|
407
|
+
InteractionBusContext,
|
|
408
|
+
useInteractionBus,
|
|
409
|
+
ToolCallShell
|
|
410
|
+
};
|
|
411
|
+
//# sourceMappingURL=chunk-WM6Y6APP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/view/tools/ask_user_question/formatAskUserQuestionTitle.ts","../src/view/tools/edit/formatEditTitle.ts","../src/view/tools/glob/formatGlobTitle.ts","../src/view/tools/grep/formatGrepTitle.ts","../src/view/tools/read/formatReadTitle.ts","../src/view/tools/skill/formatSkillTitle.ts","../src/view/tools/webfetch/formatWebFetchTitle.ts","../src/view/tools/websearch/formatWebSearchTitle.ts","../src/view/tools/write/formatWriteTitle.ts","../src/view/tools/formatToolTitle.ts","../src/view/tools/DefaultToolBody.tsx","../src/view/tools/resolveToolBody.ts","../src/core/interaction/InteractionBus.ts","../src/core/context/InteractionContext.tsx","../src/view/tools/ToolPermissionWait.tsx","../src/view/tools/ToolCallShell.tsx"],"sourcesContent":["/**\n * formatAskUserQuestionTitle.ts — AskUserQuestion 工具标题\n *\n * 对齐参考:CLI widgets/tools/ask_user_question/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField } from '../displayRecord';\nimport { formatAskUserQuestionsPreview } from '../presentation/askUserHelpers';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nfunction firstQuestion(\n display: Record<string, unknown> | null,\n input: Record<string, unknown>,\n): { header: string; question: string } {\n const items = display?.questions;\n if (Array.isArray(items) && items.length > 0) {\n const first = items[0];\n if (first != null && typeof first === 'object') {\n const row = first as Record<string, unknown>;\n return {\n header: String(row.header ?? '').trim(),\n question: String(row.question ?? '').trim(),\n };\n }\n }\n\n const questions = input.questions;\n if (Array.isArray(questions) && questions.length > 0) {\n const first = questions[0];\n if (first != null && typeof first === 'object') {\n const row = first as Record<string, unknown>;\n return {\n header: String(row.header ?? '').trim(),\n question: String(row.question ?? '').trim(),\n };\n }\n }\n\n return { header: '', question: '' };\n}\n\nexport function formatAskUserQuestionTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const { header, question } = firstQuestion(d, inp);\n\n if (question) {\n const label = header ? `[${header}] ${question}` : question;\n return truncatePreview(label, 100);\n }\n\n const answered = numField(d ?? {}, 'answered_count');\n if (answered != null) return `Ask user (${answered} answered)`;\n\n return 'Ask user';\n}\n\nexport { formatAskUserQuestionsPreview };\n","/**\n * formatEditTitle.ts — edit 工具标题(Update / Create)\n *\n * 对齐参考:CLI widgets/tools/edit/widget.py format_title\n */\nimport { asInputRecord, strField } from '../displayRecord';\nimport { displayPath } from '../presentation/paths';\n\nexport function editAction(input: unknown): 'Update' | 'Create' {\n const inp = asInputRecord(input);\n if (Array.isArray(inp.edits) && inp.edits.length > 0) return 'Update';\n if ('old_string' in inp && inp.old_string === '') return 'Create';\n return 'Update';\n}\n\nexport function formatEditTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const inp = asInputRecord(input);\n const d =\n display != null && typeof display === 'object' && !Array.isArray(display)\n ? (display as Record<string, unknown>)\n : null;\n const path = displayPath(\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\n );\n const action = editAction(inp);\n if (!path) return action;\n return `${action}(${path})`;\n}\n","/**\n * formatGlobTitle.ts — glob 工具标题\n *\n * 对齐参考:CLI widgets/tools/glob/widget.py format_title\n */\nimport { formatPatternTitle } from '../presentation/searchHelpers';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nexport function formatGlobTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\n\n if (!pattern) return 'Search';\n\n const path = strField(inp, 'path') || undefined;\n const suffix = formatPatternTitle(pattern, path);\n const numFiles = numField(d ?? {}, 'num_files');\n const countHint = numFiles != null ? ` · ${numFiles} files` : '';\n\n return `Search(${suffix}${countHint})`;\n}\n","/**\n * formatGrepTitle.ts — grep 工具标题\n *\n * 对齐参考:CLI widgets/tools/grep/widget.py format_title\n */\nimport { formatPatternTitle } from '../presentation/searchHelpers';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nexport function formatGrepTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const pattern = strField(d ?? {}, 'pattern') || strField(inp, 'pattern');\n\n if (!pattern) return 'Search';\n\n const path = strField(inp, 'path') || undefined;\n const suffix = formatPatternTitle(pattern, path);\n const numMatches = numField(d ?? {}, 'num_matches');\n const countHint = numMatches != null ? ` · ${numMatches} matches` : '';\n\n return `Search(${suffix}${countHint})`;\n}\n","/**\n * formatReadTitle.ts — Read 工具标题\n *\n * 对齐参考:CLI widgets/tools/read/widget.py format_title\n */\nimport { displayPath } from '../presentation/paths';\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\n\nconst LINES_RANGE_RE = /lines (\\d+)-(\\d+) of (\\d+)/;\nconst READ_LINES_RE = /Read (\\d+) lines from/;\n\nfunction titleSuffixFromDisplay(display: unknown): string {\n const d = asDisplayRecord(display);\n if (!d) return '';\n\n if (d.type === 'text') {\n const start = numField(d, 'line_start');\n const end = numField(d, 'line_end');\n if (start != null && end != null) {\n return ` · lines ${start}-${end}`;\n }\n }\n\n if (d.type === 'pdf') {\n const ps = numField(d, 'page_start');\n const pe = numField(d, 'page_end');\n if (ps != null && pe != null) {\n return ` · pages ${ps}-${pe}`;\n }\n }\n\n return '';\n}\n\nfunction titleSuffixFromSummary(summary: string, input: unknown): string {\n const matchRange = summary.match(LINES_RANGE_RE);\n if (matchRange) {\n return ` · lines ${matchRange[1]}-${matchRange[2]}`;\n }\n\n const inp = asInputRecord(input);\n const offset = numField(inp, 'offset');\n const limit = numField(inp, 'limit');\n if (offset != null && limit != null) {\n return ` · lines ${offset}-${offset + limit - 1}`;\n }\n\n const matchLines = summary.match(READ_LINES_RE);\n if (matchLines) {\n return ` · ${matchLines[1]} lines`;\n }\n\n return '';\n}\n\nexport function formatReadTitle(input: unknown, display: unknown, summary?: string | null): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const path = displayPath(\n strField(d ?? {}, 'file_path') ||\n strField(inp, 'file_path') ||\n strField(inp, 'path'),\n );\n\n const suffix =\n titleSuffixFromDisplay(display) ||\n (summary ? titleSuffixFromSummary(summary, input) : '');\n\n if (!path) {\n return suffix ? `Read(${suffix.trim()})` : 'Read';\n }\n\n return `Read(${path}${suffix})`;\n}\n","/**\n * formatSkillTitle.ts — skill 工具标题\n *\n * 对齐参考:CLI widgets/tools/skill/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\n\nexport function formatSkillTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const name = strField(d ?? {}, 'skill_name') || strField(inp, 'skill_name');\n if (!name) return 'Skill';\n\n if (d?.source === 'commands_DEPRECATED') {\n return `/${name}`;\n }\n return name;\n}\n","/**\n * formatWebFetchTitle.ts — WebFetch 工具标题\n *\n * 对齐参考:CLI widgets/tools/webfetch/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nexport function formatWebFetchTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const url = strField(d ?? {}, 'url') || strField(inp, 'url');\n if (!url) return 'Fetch';\n\n const code = numField(d ?? {}, 'http_code');\n const title =\n code != null ? `${url} · HTTP ${code}` : truncatePreview(url, 100);\n return `Fetch(${title})`;\n}\n","/**\n * formatWebSearchTitle.ts — WebSearch 工具标题\n *\n * 对齐参考:CLI widgets/tools/websearch/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, numField, strField } from '../displayRecord';\nimport { truncatePreview } from '../presentation/textHelpers';\n\nexport function formatWebSearchTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const query = strField(d ?? {}, 'query') || strField(inp, 'query');\n if (!query) return 'Web Search';\n\n let queryPart = `\"${truncatePreview(query, 100)}\"`;\n const hits = numField(d ?? {}, 'total_hits');\n if (hits != null) queryPart = `${queryPart} · ${hits} hits`;\n\n return `Web Search(${queryPart})`;\n}\n","/**\n * formatWriteTitle.ts — write 工具标题\n *\n * 对齐参考:CLI widgets/tools/write/widget.py format_title\n */\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\nimport { displayPath } from '../presentation/paths';\n\nexport function formatWriteTitle(\n input: unknown,\n display: unknown,\n _summary?: string | null,\n): string {\n const inp = asInputRecord(input);\n const d = asDisplayRecord(display);\n const path = displayPath(\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\n );\n if (!path) return 'Write';\n return `Write(${path})`;\n}\n","/**\n * formatToolTitle.ts — 工具卡片标题格式化\n */\nimport { formatAgentTitle } from './presentation/agentHelpers';\nimport { formatAskUserQuestionTitle } from './ask_user_question/formatAskUserQuestionTitle';\nimport { formatBashTitle } from './presentation/bashHelpers';\nimport { formatEditTitle } from './edit/formatEditTitle';\nimport { formatGlobTitle } from './glob/formatGlobTitle';\nimport { formatGrepTitle } from './grep/formatGrepTitle';\nimport { formatReadTitle } from './read/formatReadTitle';\nimport { formatSkillTitle } from './skill/formatSkillTitle';\nimport { formatWebFetchTitle } from './webfetch/formatWebFetchTitle';\nimport { formatWebSearchTitle } from './websearch/formatWebSearchTitle';\nimport { formatWriteTitle } from './write/formatWriteTitle';\nimport {\n Agent,\n AskUserQuestion,\n Bash,\n Edit,\n Glob,\n Grep,\n Read,\n Skill,\n WebFetch,\n WebSearch,\n Write,\n} from './toolNames';\n\ntype TitleFormatter = (\n input: unknown,\n display: unknown,\n summary?: string | null,\n meta?: unknown,\n) => string;\n\nconst TITLE_FORMATTERS: Record<string, TitleFormatter> = {\n [Read]: formatReadTitle,\n [Grep]: formatGrepTitle,\n [Glob]: formatGlobTitle,\n [Edit]: formatEditTitle,\n [Write]: formatWriteTitle,\n [Bash]: formatBashTitle,\n [Agent]: formatAgentTitle,\n [Skill]: formatSkillTitle,\n [WebSearch]: formatWebSearchTitle,\n [WebFetch]: formatWebFetchTitle,\n [AskUserQuestion]: formatAskUserQuestionTitle,\n};\n\nexport function formatToolTitle(\n toolName: string,\n input: unknown,\n display: unknown,\n summary?: string | null,\n meta?: unknown,\n): string {\n const formatter = TITLE_FORMATTERS[toolName];\n if (formatter) {\n return formatter(input, display, summary, meta);\n }\n return toolName;\n}\n","/**\n * DefaultToolBody.tsx — 未注册工具回退 Body\n *\n * 职责:\n * summary + display JSON 预览(≥ V2);markdown/text 走 TruncatedContent。\n *\n * 链路位置:\n * resolveToolBody 最终回退。\n *\n * 当前裁剪范围:\n * 不渲染 blocks 主视图(折叠区保留在 ToolCallCard details)。\n *\n * 对齐参考:\n * CLI widgets/tools/base.py BaseToolWidget · V2 ToolCallCard JSON pre\n */\nimport { TruncatedContent } from './presentation/TruncatedContent';\nimport type { ToolDisplayProps } from './types';\n\nfunction formatDisplayJson(display: unknown): string {\n if (display == null) return '';\n if (typeof display === 'string') return display;\n try {\n return JSON.stringify(display, null, 2);\n } catch {\n return String(display);\n }\n}\n\nfunction extractTextContent(display: unknown): string | null {\n if (display == null) return null;\n if (typeof display === 'string') return display;\n if (typeof display === 'object') {\n const record = display as { content?: unknown; text?: unknown };\n if (typeof record.content === 'string') return record.content;\n if (typeof record.text === 'string') return record.text;\n }\n return null;\n}\n\nexport function DefaultToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n const summary = result?.summary;\n const displayBody = result?.display ?? null;\n const textContent = extractTextContent(displayBody);\n const jsonBody = textContent ?? formatDisplayJson(displayBody);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--default\">\n {summary ? (\n <div className=\"lax-tool-card__summary\">{summary}</div>\n ) : null}\n\n {displayBody != null && displayBody !== '' && jsonBody ? (\n <div className=\"lax-tool-card__display\">\n {textContent != null ? (\n <TruncatedContent\n text={textContent}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : (\n <pre className=\"lax-tool-card__display-body\">{jsonBody}</pre>\n )}\n </div>\n ) : null}\n\n {result?.truncated ? (\n <div className=\"lax-tool-card__truncated\">结果已截断</div>\n ) : null}\n\n {result?.overflow_file ? (\n <div className=\"lax-tool-card__overflow\">\n 完整输出:\n <code>{result.overflow_file}</code>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * resolveToolBody.ts — 工具 Body 路由纯函数\n *\n * 职责:\n * registry → display.type → DefaultToolBody(精确 tool_name 匹配,无 alias)。\n *\n * 链路位置:\n * ToolCallCard render。\n *\n * 当前裁剪范围:\n * T0 display.type 二级路由表为空;T1+ 注册专用 Widget 与 kind router。\n *\n * 对齐参考:\n * CLI widgets/tools/__init__.py resolve_tool_widget\n */\nimport { DefaultToolBody } from './DefaultToolBody';\nimport type { ToolDisplayRegistry } from './registry';\nimport type { ToolBodyComponent } from './types';\n\n/** display.type → Body;T0 空表,T1+ 填充。 */\nconst DISPLAY_KIND_ROUTER = new Map<string, ToolBodyComponent>();\n\nfunction getDisplayType(display: unknown): string | undefined {\n if (display == null || typeof display !== 'object') return undefined;\n const type = (display as { type?: unknown }).type;\n return typeof type === 'string' ? type : undefined;\n}\n\nexport function resolveToolBody(\n toolName: string,\n display: unknown,\n registry: ToolDisplayRegistry,\n): ToolBodyComponent {\n const byName = registry.resolve(toolName);\n if (byName) return byName;\n\n const displayType = getDisplayType(display);\n if (displayType) {\n const byKind = DISPLAY_KIND_ROUTER.get(displayType);\n if (byKind) return byKind;\n }\n\n return DefaultToolBody;\n}\n\n/** 测试 / 扩展用:注册 display.type 路由。 */\nexport function registerDisplayKind(\n displayType: string,\n body: ToolBodyComponent,\n): void {\n DISPLAY_KIND_ROUTER.set(displayType, body);\n}\n\n/** 测试用:清空 display kind 路由。 */\nexport function clearDisplayKindRouter(): void {\n DISPLAY_KIND_ROUTER.clear();\n}\n","/**\n * 职责:人类回写薄层 API;PermissionNode 触发,业务实现 HTTP 回写。\n * 链路位置:AgentSession interactionBus prop → PermissionNode 按钮。\n * 当前裁剪范围:permission resolve;不含 HITL 表单协议。\n */\n\nexport interface PermissionResolvePayload {\n requestId: string;\n allow: boolean;\n message?: string;\n}\n\nexport interface InteractionBus {\n resolvePermission: (payload: PermissionResolvePayload) => void | Promise<void>;\n}\n\nexport interface InteractionBusHandlers {\n onPermissionResolve?: (payload: PermissionResolvePayload) => void | Promise<void>;\n}\n\nconst noopBus: InteractionBus = {\n resolvePermission() {\n if (import.meta.env?.DEV) {\n console.warn('[langchain_agentx_stream_ui] resolvePermission without InteractionBus');\n }\n },\n};\n\nexport function createInteractionBus(handlers: InteractionBusHandlers = {}): InteractionBus {\n return {\n resolvePermission(payload) {\n return handlers.onPermissionResolve?.(payload);\n },\n };\n}\n\nexport function getNoopInteractionBus(): InteractionBus {\n return noopBus;\n}\n","/**\n * 职责:向 PermissionNode 注入 InteractionBus。\n * 链路位置:AgentSession / MultiAgentSession Provider。\n * 当前裁剪范围:单 bus;多会话共用同一 bus(业务按 requestId 路由)。\n */\nimport { createContext, useContext } from 'react';\n\nimport type { InteractionBus } from '../interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../interaction/InteractionBus';\n\nexport const InteractionBusContext = createContext<InteractionBus>(getNoopInteractionBus());\n\nexport function useInteractionBus(): InteractionBus {\n return useContext(InteractionBusContext);\n}\n","/**\n * ToolPermissionWait.tsx — ToolCallShell 内嵌 permission 等待态(T4.6)\n *\n * 对齐参考:CC AssistantToolUseMessage「Waiting for permission…」分支\n */\nimport { useState } from 'react';\n\nimport { useInteractionBus } from '../../core/context/InteractionContext';\nimport type { PermissionNode } from '../../types/nodes';\nimport type { PermissionUiMode } from '../sessionViewOptions';\n\nexport interface ToolPermissionWaitProps {\n permission: PermissionNode;\n mode: PermissionUiMode;\n}\n\nexport function ToolPermissionWait({ permission, mode }: ToolPermissionWaitProps) {\n const bus = useInteractionBus();\n const [resolvedLocally, setResolvedLocally] = useState(false);\n\n if (permission.status !== 'pending' || resolvedLocally) return null;\n\n const showActions = mode === 'inline' || mode === 'both';\n\n const onAllow = () => {\n void bus.resolvePermission({ requestId: permission.requestId, allow: true });\n setResolvedLocally(true);\n };\n\n const onDeny = () => {\n void bus.resolvePermission({ requestId: permission.requestId, allow: false });\n setResolvedLocally(true);\n };\n\n return (\n <div className=\"lax-tool-shell__permission-wait\" role=\"status\">\n <div className=\"lax-tool-shell__permission-wait-text\">\n Waiting for permission…\n </div>\n {permission.message ? (\n <div className=\"lax-tool-shell__permission-wait-detail\">{permission.message}</div>\n ) : null}\n {showActions ? (\n <div className=\"lax-tool-shell__permission-actions\">\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\n Allow\n </button>\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\n Deny\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * ToolCallShell.tsx — 工具卡片外壳\n *\n * 职责:\n * 状态圆点、标题、progress、error 边框;不含工具语义。\n *\n * 链路位置:\n * ToolCallCard 外层布局。\n *\n * 当前裁剪范围:\n * T4.6 内嵌 permission 等待态;Grouped 紧凑布局 variant。\n *\n * 对齐参考:\n * CLI base.py 状态圆点 · CC AssistantToolUseMessage.tsx 外层 Box\n */\nimport type { ReactNode } from 'react';\n\nimport type { ToolCallNode } from '../../types/nodes';\nimport type { PermissionNode } from '../../types/nodes';\nimport type { PermissionUiMode } from '../sessionViewOptions';\nimport { ToolPermissionWait } from './ToolPermissionWait';\n\nexport interface ToolCallShellProps {\n status: ToolCallNode['status'];\n title: string;\n progress?: ToolCallNode['progress'];\n errorMessage?: string | null;\n layout?: 'default' | 'grouped';\n permissionWait?: PermissionNode;\n permissionUiMode?: PermissionUiMode;\n children?: ReactNode;\n}\n\nexport function ToolCallShell({\n status,\n title,\n progress,\n errorMessage,\n layout = 'default',\n permissionWait,\n permissionUiMode = 'standalone',\n children,\n}: ToolCallShellProps) {\n const bare = !title.trim();\n const waitingForPermission =\n permissionWait &&\n permissionUiMode !== 'standalone' &&\n (status === 'running' || status === 'failed');\n\n return (\n <div\n className={[\n 'lax-tool-card',\n 'lax-tool-shell',\n bare ? 'lax-tool-shell--bare' : '',\n layout === 'grouped' ? 'lax-tool-shell--grouped' : '',\n waitingForPermission ? 'lax-tool-shell--permission-wait' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n data-status={status}\n data-error-kind={\n errorMessage ? 'error' : waitingForPermission ? 'permission' : undefined\n }\n >\n {!bare ? (\n <div className=\"lax-tool-shell__header lax-tool-card__header\">\n <span\n className=\"lax-tool-shell__status-dot lax-tool-card__status-dot\"\n data-status={status}\n aria-hidden\n >\n ●{' '}\n </span>\n <span className=\"lax-tool-shell__title lax-tool-card__name\">{title}</span>\n </div>\n ) : null}\n\n {progress ? (\n <div className=\"lax-tool-shell__progress lax-tool-card__progress\">\n {progress.message ?? `${progress.current}/${progress.total}`}\n </div>\n ) : null}\n\n {waitingForPermission && permissionWait ? (\n <ToolPermissionWait permission={permissionWait} mode={permissionUiMode} />\n ) : null}\n\n {children}\n\n {errorMessage && status === 'failed' ? (\n <div className=\"lax-tool-card__error\" role=\"alert\">\n {errorMessage}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs"]}
|