@yumiai/chat-widget 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -1
  3. package/dist/ExcelCore-EAXQMKZT.js +10 -0
  4. package/dist/{ExcelViewer-3YLLYYIQ.js → ExcelViewer-OGWM52ZT.js} +2 -3
  5. package/dist/{ExcelViewer-3YLLYYIQ.js.map → ExcelViewer-OGWM52ZT.js.map} +1 -1
  6. package/dist/{GerberViewerA2UI-X5FWAD5M.js → GerberViewerA2UI-AORHOCF6.js} +2 -3
  7. package/dist/{GerberViewerA2UI-X5FWAD5M.js.map → GerberViewerA2UI-AORHOCF6.js.map} +1 -1
  8. package/dist/{GraphStatsLegend-D5bPeXB_.d.cts → GraphStatsLegend-CV0Y3-cP.d.cts} +39 -0
  9. package/dist/{GraphStatsLegend-D5bPeXB_.d.ts → GraphStatsLegend-CV0Y3-cP.d.ts} +39 -0
  10. package/dist/JsonRenderStandalone-L5ROJ6XP.js +17 -0
  11. package/dist/{KicadViewer-GV6ZC4AQ.js → KicadViewer-H6YY6WVC.js} +3 -4
  12. package/dist/{KicadViewer-GV6ZC4AQ.js.map → KicadViewer-H6YY6WVC.js.map} +1 -1
  13. package/dist/KicadViewerCore-XVJE2FTQ.js +10 -0
  14. package/dist/{PdfViewer-CHPDRK46.js → PdfViewer-GKVDDNCZ.js} +9 -10
  15. package/dist/{PdfViewer-CHPDRK46.js.map → PdfViewer-GKVDDNCZ.js.map} +1 -1
  16. package/dist/{PdfViewerCore-HJPEHSRA.js → PdfViewerCore-SUVXHXYO.js} +24 -11
  17. package/dist/PdfViewerCore-SUVXHXYO.js.map +1 -0
  18. package/dist/PowerPointCore-IZ4G6HEQ.js +10 -0
  19. package/dist/{PowerPointViewer-LQTO6UCU.js → PowerPointViewer-5R2KSWWJ.js} +2 -3
  20. package/dist/{PowerPointViewer-LQTO6UCU.js.map → PowerPointViewer-5R2KSWWJ.js.map} +1 -1
  21. package/dist/{StepViewerCore-7W3L3R4E.js → StepViewerCore-RORWXIRU.js} +2 -3
  22. package/dist/{StepViewerCore-7W3L3R4E.js.map → StepViewerCore-RORWXIRU.js.map} +1 -1
  23. package/dist/{ThreeViewerCore-N3QJD5QI.js → ThreeViewerCore-GTUZKD5V.js} +2 -3
  24. package/dist/{ThreeViewerCore-N3QJD5QI.js.map → ThreeViewerCore-GTUZKD5V.js.map} +1 -1
  25. package/dist/WordCore-QFG5HTYD.js +10 -0
  26. package/dist/{WordViewer-ZHCQMHOH.js → WordViewer-7XUQFS4A.js} +2 -3
  27. package/dist/{WordViewer-ZHCQMHOH.js.map → WordViewer-7XUQFS4A.js.map} +1 -1
  28. package/dist/{chunk-QLVPIM6R.js → chunk-3CNQONCV.js} +79 -1
  29. package/dist/chunk-3CNQONCV.js.map +1 -0
  30. package/dist/{chunk-2UC7YLVX.js → chunk-3LOSHCSH.js} +3 -3
  31. package/dist/chunk-5VUKEGFC.js +108 -0
  32. package/dist/chunk-5VUKEGFC.js.map +1 -0
  33. package/dist/chunk-AO4YUJQT.js +479 -0
  34. package/dist/chunk-AO4YUJQT.js.map +1 -0
  35. package/dist/{chunk-KQV7IKET.js → chunk-ASV4TISB.js} +2 -2
  36. package/dist/{chunk-CFKGNAJM.js → chunk-AT6VLLOO.js} +15 -15
  37. package/dist/{chunk-56WRZM3R.js → chunk-EYWNUJVZ.js} +3 -3
  38. package/dist/{chunk-K4KGNVL5.js → chunk-EZ46FGQ6.js} +3 -3
  39. package/dist/{chunk-GYXTSY22.js → chunk-KXPR6SRW.js} +4 -4
  40. package/dist/{chunk-7S67DOHQ.js → chunk-MTN6SUUQ.js} +2 -2
  41. package/dist/chunk-Q5PLT3AI.js +29 -0
  42. package/dist/chunk-Q5PLT3AI.js.map +1 -0
  43. package/dist/{chunk-PZXSASDY.js → chunk-R5LHMOAC.js} +3 -3
  44. package/dist/chunk-X67V7257.js +238 -0
  45. package/dist/chunk-X67V7257.js.map +1 -0
  46. package/dist/citationContext-CILHTO2Z.js +25 -0
  47. package/dist/components/JsonRender/standalone.cjs +56 -9753
  48. package/dist/components/JsonRender/standalone.cjs.map +1 -1
  49. package/dist/components/JsonRender/standalone.js +10 -11
  50. package/dist/components/JsonRender/standalone.js.map +1 -1
  51. package/dist/{gerber-2d-entry-OQ4SQRBY.js → gerber-2d-entry-HEFXQGBK.js} +5 -9
  52. package/dist/{gerber-2d-entry-OQ4SQRBY.js.map → gerber-2d-entry-HEFXQGBK.js.map} +1 -1
  53. package/dist/{gerber-3d-entry-DEHDBOO2.js → gerber-3d-entry-KVTONA37.js} +5 -9
  54. package/dist/{gerber-3d-entry-DEHDBOO2.js.map → gerber-3d-entry-KVTONA37.js.map} +1 -1
  55. package/dist/{gerber-simulation-entry-EBDX72XE.js → gerber-simulation-entry-GZ62QX5H.js} +5 -9
  56. package/dist/{gerber-simulation-entry-EBDX72XE.js.map → gerber-simulation-entry-GZ62QX5H.js.map} +1 -1
  57. package/dist/index.cjs +6690 -13472
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.css +776 -4
  60. package/dist/index.css.map +1 -1
  61. package/dist/index.d.cts +979 -26
  62. package/dist/index.d.ts +979 -26
  63. package/dist/index.js +4350 -1859
  64. package/dist/index.js.map +1 -1
  65. package/dist/provenance/index.cjs +78 -0
  66. package/dist/provenance/index.cjs.map +1 -1
  67. package/dist/provenance/index.d.cts +2 -2
  68. package/dist/provenance/index.d.ts +2 -2
  69. package/dist/provenance/index.js +2 -3
  70. package/dist/{resolveToArrayBuffer-AQIDZHSQ.js → resolveToArrayBuffer-PVSVIAII.js} +1 -3
  71. package/dist/{resolveToArrayBuffer-AQIDZHSQ.js.map → resolveToArrayBuffer-PVSVIAII.js.map} +1 -1
  72. package/dist/sseAdapter-LFXYGYC4.js +8 -0
  73. package/dist/sseAdapter-LFXYGYC4.js.map +1 -0
  74. package/package.json +2 -1
  75. package/dist/ExcelCore-DJOIVQMI.js +0 -11
  76. package/dist/JsonRenderStandalone-EIZM62JU.js +0 -18
  77. package/dist/KicadViewerCore-U7BWZHKJ.js +0 -11
  78. package/dist/PdfViewerCore-HJPEHSRA.js.map +0 -1
  79. package/dist/PowerPointCore-FPDR2BL4.js +0 -11
  80. package/dist/WordCore-JKSXK2XD.js +0 -11
  81. package/dist/chunk-7A4FY6FK.js +0 -10226
  82. package/dist/chunk-7A4FY6FK.js.map +0 -1
  83. package/dist/chunk-7D4SUZUM.js +0 -38
  84. package/dist/chunk-QLVPIM6R.js.map +0 -1
  85. package/dist/chunk-VXJWGLZ7.js +0 -21
  86. package/dist/chunk-VXJWGLZ7.js.map +0 -1
  87. /package/dist/{ExcelCore-DJOIVQMI.js.map → ExcelCore-EAXQMKZT.js.map} +0 -0
  88. /package/dist/{JsonRenderStandalone-EIZM62JU.js.map → JsonRenderStandalone-L5ROJ6XP.js.map} +0 -0
  89. /package/dist/{KicadViewerCore-U7BWZHKJ.js.map → KicadViewerCore-XVJE2FTQ.js.map} +0 -0
  90. /package/dist/{PowerPointCore-FPDR2BL4.js.map → PowerPointCore-IZ4G6HEQ.js.map} +0 -0
  91. /package/dist/{WordCore-JKSXK2XD.js.map → WordCore-QFG5HTYD.js.map} +0 -0
  92. /package/dist/{chunk-2UC7YLVX.js.map → chunk-3LOSHCSH.js.map} +0 -0
  93. /package/dist/{chunk-KQV7IKET.js.map → chunk-ASV4TISB.js.map} +0 -0
  94. /package/dist/{chunk-CFKGNAJM.js.map → chunk-AT6VLLOO.js.map} +0 -0
  95. /package/dist/{chunk-56WRZM3R.js.map → chunk-EYWNUJVZ.js.map} +0 -0
  96. /package/dist/{chunk-K4KGNVL5.js.map → chunk-EZ46FGQ6.js.map} +0 -0
  97. /package/dist/{chunk-GYXTSY22.js.map → chunk-KXPR6SRW.js.map} +0 -0
  98. /package/dist/{chunk-7S67DOHQ.js.map → chunk-MTN6SUUQ.js.map} +0 -0
  99. /package/dist/{chunk-PZXSASDY.js.map → chunk-R5LHMOAC.js.map} +0 -0
  100. /package/dist/{chunk-7D4SUZUM.js.map → citationContext-CILHTO2Z.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/provenance/index.ts","../../src/provenance/ProvenanceGraphDrawerContent.tsx","../../src/provenance/hooks/useProvenanceGraph.ts","../../src/provenance/GraphBuilder.ts","../../src/provenance/api.ts","../../src/provenance/components/ProvenanceGraph3D.tsx","../../src/provenance/components/NodeMeshFactory.ts","../../src/provenance/constants.ts","../../src/provenance/components/GraphStatsLegend.tsx","../../src/i18n/context.ts","../../src/i18n/messages.ts","../../src/provenance/components/NodeDetailPanel.tsx","../../src/provenance/ProvenanceI18nProvider.tsx","../../src/provenance/components/FilterBar.tsx","../../src/provenance/components/GraphToolbar.tsx"],"sourcesContent":["export { default as ProvenanceGraphDrawerContent } from './ProvenanceGraphDrawerContent'\nexport { ProvenanceI18nProvider } from './ProvenanceI18nProvider'\nexport { useProvenanceGraph } from './hooks/useProvenanceGraph'\nexport { GraphBuilder } from './GraphBuilder'\nexport { fetchProvenanceGraph } from './api'\nexport { ProvenanceGraph3D } from './components/ProvenanceGraph3D'\nexport { NodeDetailPanel } from './components/NodeDetailPanel'\nexport { FilterBar } from './components/FilterBar'\nexport { GraphToolbar } from './components/GraphToolbar'\nexport { GraphStatsLegend } from './components/GraphStatsLegend'\nexport type { ProvenanceGraphFetcher, FetchGraphOptions } from './api'\nexport type { ProvenanceGraphSnapshot, ProvenanceNode, GraphEdge, NodeType, EdgeType, GraphSSEPayload, GraphFilter } from './types'\n","/**\n * JETP-025: ProvenanceGraphDrawerContent\n *\n * Lightweight wrapper for embedding the provenance graph inside an antd Drawer.\n * Reuses ProvenanceGraph3D + GraphStatsLegend + NodeDetailPanel.\n *\n * Supports real-time SSE updates via onProcessEventRef callback.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { Spin, Empty } from 'antd'\nimport { useProvenanceGraph } from './hooks/useProvenanceGraph'\nimport { ProvenanceGraph3D } from './components/ProvenanceGraph3D'\nimport { GraphStatsLegend } from './components/GraphStatsLegend'\nimport { NodeDetailPanel } from './components/NodeDetailPanel'\nimport type { NodeType, GraphSSEPayload } from './types'\nimport { useChatWidgetI18n } from '../i18n'\nimport './ProvenanceGraph.css'\n\ninterface ProvenanceGraphDrawerContentProps {\n sessionId: number\n onProcessEventRef?: React.MutableRefObject<((p: GraphSSEPayload) => void) | null>\n}\n\nfunction useContainerSize(ref: React.RefObject<HTMLDivElement | null>) {\n const [size, setSize] = React.useState({ width: 600, height: 500 })\n\n React.useEffect(() => {\n if (!ref.current) return\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n setSize({ width: Math.floor(width), height: Math.floor(height) })\n }\n })\n observer.observe(ref.current)\n return () => observer.disconnect()\n }, [ref])\n\n return size\n}\n\nconst ProvenanceGraphDrawerContent: React.FC<ProvenanceGraphDrawerContentProps> = ({\n sessionId,\n onProcessEventRef,\n}) => {\n const { t } = useChatWidgetI18n()\n const containerRef = useRef<HTMLDivElement>(null)\n const { width, height } = useContainerSize(containerRef)\n\n const { graph, loading, error, processEvent } = useProvenanceGraph({\n sessionId,\n enabled: true,\n })\n\n // Expose processEvent to parent via ref\n useEffect(() => {\n if (onProcessEventRef) {\n onProcessEventRef.current = processEvent\n }\n return () => {\n if (onProcessEventRef) {\n onProcessEventRef.current = null\n }\n }\n }, [onProcessEventRef, processEvent])\n\n const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null)\n const [detailOpen, setDetailOpen] = useState(false)\n\n const handleNodeClick = useCallback((nodeId: string, _nodeType: NodeType) => {\n setSelectedNodeId(nodeId)\n setDetailOpen(true)\n }, [])\n\n const handleBackgroundClick = useCallback(() => {\n setSelectedNodeId(null)\n setDetailOpen(false)\n }, [])\n\n return (\n <div\n ref={containerRef}\n style={{ width: '100%', height: '100%', minHeight: 400, position: 'relative' }}\n >\n {loading && !graph && (\n <div className=\"ycw-provenance-loading\">\n <Spin size=\"large\" />\n </div>\n )}\n\n {error && !graph && (\n <div className=\"ycw-provenance-empty\">\n <span style={{ color: '#ff4d4f' }}>{error.message}</span>\n </div>\n )}\n\n {graph && graph.node_count === 0 && !loading && (\n <Empty description={t('provenance.drawer.emptyGraph')} style={{ paddingTop: 80 }} />\n )}\n\n {graph && graph.node_count > 0 && (\n <>\n <ProvenanceGraph3D\n graph={graph}\n width={width}\n height={height}\n selectedNodeId={selectedNodeId}\n onNodeClick={handleNodeClick}\n onBackgroundClick={handleBackgroundClick}\n />\n <GraphStatsLegend stats={graph.stats} edgeCount={graph.edges.length} />\n </>\n )}\n\n {graph && (\n <NodeDetailPanel\n open={detailOpen}\n nodeId={selectedNodeId}\n graph={graph}\n onClose={() => {\n setDetailOpen(false)\n setSelectedNodeId(null)\n }}\n />\n )}\n </div>\n )\n}\n\nexport default ProvenanceGraphDrawerContent\n","/**\n * JETP-025: useProvenanceGraph Hook\n *\n * Manages the provenance graph lifecycle:\n * 1. Fetches initial snapshot via REST\n * 2. Accepts SSE events from parent to incrementally update\n * 3. Handles reconnection by fetching delta via since_turn_id\n * 4. Debounces re-renders for burst SSE events\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { GraphBuilder } from '../GraphBuilder'\nimport { fetchProvenanceGraph } from '../api'\nimport type { ProvenanceGraphFetcher } from '../api'\nimport type { ProvenanceGraphSnapshot, GraphSSEPayload } from '../types'\n\ninterface UseProvenanceGraphOptions {\n sessionId: number | null\n /** Adapter-supplied fetcher; when absent, fetch is disabled */\n fetcher?: ProvenanceGraphFetcher\n enabled?: boolean\n /** Auto-poll interval in ms. 0 disables. Default 3000. */\n pollInterval?: number\n}\n\ninterface UseProvenanceGraphReturn {\n graph: ProvenanceGraphSnapshot | null\n loading: boolean\n error: Error | null\n processEvent: (payload: GraphSSEPayload) => void\n refetch: () => void\n}\n\nconst EMPTY_SNAPSHOT: ProvenanceGraphSnapshot = {\n session_id: 0,\n generated_at: 0,\n node_count: 0,\n edge_count: 0,\n max_turn_id: null,\n nodes: { agents: [], actions: [], files: [], tasks: [], reasonings: [] },\n edges: [],\n stats: { agent_count: 0, action_count: 0, file_count: 0, task_count: 0, reasoning_count: 0, max_depth: 0 },\n}\n\nconst DEBOUNCE_MS = 80\n\nexport function useProvenanceGraph(\n opts: UseProvenanceGraphOptions,\n): UseProvenanceGraphReturn {\n const { sessionId, fetcher, enabled = true, pollInterval = 3000 } = opts\n const builderRef = useRef(new GraphBuilder())\n const maxTurnIdRef = useRef<number | null>(null)\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const mountedRef = useRef(true)\n\n const [graph, setGraph] = useState<ProvenanceGraphSnapshot | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const flushSnapshot = useCallback(() => {\n if (!mountedRef.current) return\n const snap = builderRef.current.getSnapshot()\n setGraph(snap)\n }, [])\n\n const scheduleFlush = useCallback(() => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n debounceTimerRef.current = setTimeout(flushSnapshot, DEBOUNCE_MS)\n }, [flushSnapshot])\n\n const fetchSnapshot = useCallback(\n async (sinceTurnId?: number | null) => {\n if (!sessionId || !fetcher) return\n setLoading(true)\n setError(null)\n try {\n const snap = await fetchProvenanceGraph(fetcher, {\n sessionId,\n sinceTurnId,\n })\n if (!mountedRef.current) return\n\n if (sinceTurnId != null && sinceTurnId > 0) {\n builderRef.current.mergeSnapshot(snap)\n } else {\n builderRef.current.replaceWithSnapshot(snap)\n }\n maxTurnIdRef.current = snap.max_turn_id\n flushSnapshot()\n } catch (e) {\n if (!mountedRef.current) return\n const err = e instanceof Error ? e : new Error(String(e))\n setError(err)\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n },\n [sessionId, fetcher, flushSnapshot],\n )\n\n const processEvent = useCallback(\n (payload: GraphSSEPayload) => {\n const handled = builderRef.current.applyEvent(payload)\n if (handled) scheduleFlush()\n },\n [scheduleFlush],\n )\n\n const refetch = useCallback(() => {\n fetchSnapshot(maxTurnIdRef.current)\n }, [fetchSnapshot])\n\n // Initial fetch when session changes\n useEffect(() => {\n mountedRef.current = true\n if (sessionId && enabled) {\n builderRef.current = new GraphBuilder()\n maxTurnIdRef.current = null\n fetchSnapshot(null)\n } else {\n setGraph(sessionId ? null : EMPTY_SNAPSHOT)\n }\n return () => {\n mountedRef.current = false\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n }\n }, [sessionId, enabled, fetchSnapshot])\n\n // Auto-poll for incremental updates (uses since_turn_id for efficiency)\n useEffect(() => {\n if (!sessionId || !enabled || pollInterval <= 0) return\n const id = setInterval(() => {\n if (!mountedRef.current) return\n fetchSnapshot(maxTurnIdRef.current)\n }, pollInterval)\n return () => clearInterval(id)\n }, [sessionId, enabled, pollInterval, fetchSnapshot])\n\n return { graph, loading, error, processEvent, refetch }\n}\n","/**\n * JETP-025: Client-side GraphBuilder\n *\n * Incrementally builds a provenance graph from SSE events.\n * Maintains Maps for O(1) node lookup and deduplication.\n *\n * Handlers: agent_start, agent_end, mcp_start, mcp_end,\n * artifact_result, plan_result, model_start, model_result, model_end\n */\n\nimport type {\n AgentNode,\n ActionNode,\n FileNode,\n TaskNode,\n ReasoningNode,\n GraphEdge,\n ProvenanceGraphSnapshot,\n GraphSSEPayload,\n EdgeType,\n} from './types'\n\ntype Handler = (p: GraphSSEPayload) => void\n\nexport class GraphBuilder {\n private sessionId = 0\n private agents = new Map<number, AgentNode>()\n private actions = new Map<string, ActionNode>()\n private files = new Map<string, FileNode>()\n private tasks = new Map<string, TaskNode>()\n private reasonings = new Map<string, ReasoningNode>()\n private edges: GraphEdge[] = []\n private edgeKeys = new Set<string>()\n private lastCompletedActions = new Map<number, string[]>()\n\n private readonly handlers: Record<string, Handler> = {\n agent_start: (p) => this.handleAgentStart(p),\n agent_end: (p) => this.handleAgentEnd(p),\n mcp_start: (p) => this.handleMcpStart(p),\n mcp_end: (p) => this.handleMcpEnd(p),\n artifact_result: (p) => this.handleArtifactResult(p),\n plan_result: (p) => this.handlePlanResult(p),\n model_start: (p) => this.handleModelStart(p),\n model_result: (p) => this.handleModelResult(p),\n model_end: (p) => this.handleModelEnd(p),\n }\n\n /** Apply an SSE event. Returns true if the event was handled. */\n applyEvent(payload: GraphSSEPayload): boolean {\n const type = payload.notification_type ?? ''\n const handler = this.handlers[type]\n if (!handler) return false\n handler(payload)\n return true\n }\n\n /** Replace all state from a backend snapshot (initial load). */\n replaceWithSnapshot(snapshot: ProvenanceGraphSnapshot): void {\n this.sessionId = snapshot.session_id\n this.agents.clear()\n this.actions.clear()\n this.files.clear()\n this.tasks.clear()\n this.reasonings.clear()\n this.edges = []\n this.edgeKeys.clear()\n\n for (const n of snapshot.nodes.agents) this.agents.set(n.agent_instance_id, { ...n })\n for (const n of snapshot.nodes.actions) this.actions.set(n.tool_call_id, { ...n })\n for (const n of snapshot.nodes.files) this.files.set(n.id, { ...n })\n for (const n of snapshot.nodes.tasks) this.tasks.set(n.id, { ...n })\n for (const n of snapshot.nodes.reasonings) this.reasonings.set(n.id, { ...n })\n for (const e of snapshot.edges) {\n const key = this.edgeKey(e.source, e.target, e.type, e.label)\n if (!this.edgeKeys.has(key)) {\n this.edgeKeys.add(key)\n this.edges.push({ ...e })\n }\n }\n }\n\n /** Merge an incremental snapshot (reconnection). */\n mergeSnapshot(snapshot: ProvenanceGraphSnapshot): void {\n for (const n of snapshot.nodes.agents) this.agents.set(n.agent_instance_id, { ...n })\n for (const n of snapshot.nodes.actions) this.actions.set(n.tool_call_id, { ...n })\n for (const n of snapshot.nodes.files) this.files.set(n.id, { ...n })\n for (const n of snapshot.nodes.tasks) this.tasks.set(n.id, { ...n })\n for (const n of snapshot.nodes.reasonings) this.reasonings.set(n.id, { ...n })\n for (const e of snapshot.edges) {\n const key = this.edgeKey(e.source, e.target, e.type, e.label)\n if (!this.edgeKeys.has(key)) {\n this.edgeKeys.add(key)\n this.edges.push({ ...e })\n }\n }\n }\n\n /** Produce an immutable snapshot for React state. */\n getSnapshot(): ProvenanceGraphSnapshot {\n const agents = Array.from(this.agents.values())\n const actions = Array.from(this.actions.values())\n const files = Array.from(this.files.values())\n const tasks = Array.from(this.tasks.values())\n const reasonings = Array.from(this.reasonings.values())\n const nodeCount =\n agents.length + actions.length + files.length + tasks.length + reasonings.length\n const maxDepth = agents.length > 0 ? Math.max(...agents.map((a) => a.level)) : 0\n\n return {\n session_id: this.sessionId,\n generated_at: Date.now(),\n node_count: nodeCount,\n edge_count: this.edges.length,\n max_turn_id: null,\n nodes: { agents, actions, files, tasks, reasonings },\n edges: [...this.edges],\n stats: {\n agent_count: agents.length,\n action_count: actions.length,\n file_count: files.length,\n task_count: tasks.length,\n reasoning_count: reasonings.length,\n max_depth: maxDepth,\n },\n }\n }\n\n // -----------------------------------------------------------------------\n // Handlers\n // -----------------------------------------------------------------------\n\n private handleAgentStart(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const caller = p.caller_instance_id ?? null\n const ts = this.parseTimestamp(p.timestamp)\n\n const node: AgentNode = {\n id: `agent-inst-${callee}`,\n type: 'agent',\n label: p.agent_name ?? p.agent_id ?? `agent-${callee}`,\n timestamp: ts,\n metadata: {},\n agent_id: p.agent_id ?? `agent-${callee}`,\n agent_instance_id: callee,\n agent_name: p.agent_name ?? `agent-${callee}`,\n level: p.level ?? 0,\n parent_agent_instance_id: caller != null && caller >= 0 ? caller : null,\n status: 'running',\n }\n this.agents.set(callee, node)\n\n if (caller != null && caller >= 0 && this.agents.has(caller)) {\n this.addEdge(`agent-inst-${caller}`, `agent-inst-${callee}`, 'spawns', ts)\n }\n }\n\n private handleAgentEnd(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id\n if (callee == null) return\n const existing = this.agents.get(callee)\n if (existing) {\n this.agents.set(callee, { ...existing, status: 'completed' })\n }\n }\n\n private handleMcpStart(p: GraphSSEPayload): void {\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id\n if (!tcid) return\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n\n const node: ActionNode = {\n id: `action-${tcid}`,\n type: 'action',\n label: this.extractString(p.ext, 'tool_name') ?? p.tool_name ?? tcid,\n timestamp: ts,\n metadata: {},\n tool_name: this.extractString(p.ext, 'tool_name') ?? p.tool_name ?? '',\n tool_call_id: tcid,\n task_purpose: this.extractString(p.ext, 'task_purpose') ?? p.task_purpose ?? '',\n agent_instance_id: callee,\n status: 'running',\n duration_ms: null,\n }\n this.actions.set(tcid, node)\n\n if (this.agents.has(callee)) {\n this.addEdge(`agent-inst-${callee}`, `action-${tcid}`, 'executes', ts)\n }\n\n // Derive triggers edge: most recent reasoning for this agent → this action\n const latestReasoning = this.findLatestReasoning(callee)\n if (latestReasoning) {\n this.addEdge(latestReasoning.id, `action-${tcid}`, 'triggers', ts)\n }\n\n // Retroactive: connect any files that arrived before this action was registered\n for (const [fid, fileNode] of this.files) {\n if (fileNode.tool_call_id === tcid) {\n const op = fileNode.operation\n const et: EdgeType =\n op === 'create' ? 'produces' : op === 'delete' ? 'deletes' : 'modifies'\n this.addEdge(`action-${tcid}`, fid, et, ts)\n }\n }\n }\n\n private handleMcpEnd(p: GraphSSEPayload): void {\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id\n if (!tcid) return\n const existing = this.actions.get(tcid)\n if (!existing) return\n\n const statusStr = this.extractString(p.ext, 'status') ?? p.tool_status ?? 'success'\n const status: 'success' | 'error' = statusStr === 'error' ? 'error' : 'success'\n const endTs = this.parseTimestamp(p.timestamp)\n const duration = endTs - existing.timestamp\n\n this.actions.set(tcid, { ...existing, status, duration_ms: duration > 0 ? duration : null })\n\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const prev = this.lastCompletedActions.get(callee) ?? []\n prev.push(tcid)\n this.lastCompletedActions.set(callee, prev)\n }\n\n private handleArtifactResult(p: GraphSSEPayload): void {\n // JETP-026: route xref_scan_result to dedicated handler\n if (p.ext?.xref_scan_result) {\n this.handleXrefScanResult(p)\n return\n }\n\n const data = this.extractArtifactData(p.content)\n if (!data) return\n\n const fileId = data.file_id ?? data.identifier ?? ''\n if (!fileId) return\n\n const fid = `file-${fileId}`\n const op = this.normalizeOperation(data.operation_type)\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id ?? null\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n\n const existing = this.files.get(fid)\n const node: FileNode = {\n id: fid,\n type: 'file',\n label: data.file_name ?? data.git_path ?? fileId,\n timestamp: existing?.timestamp ?? ts,\n metadata: {},\n file_id: fileId,\n file_name: data.file_name ?? '',\n git_path: data.git_path ?? '',\n operation: op,\n agent_instance_id: callee,\n tool_call_id: tcid,\n task_purpose: this.extractString(p.ext, 'task_purpose') ?? p.task_purpose ?? null,\n }\n this.files.set(fid, node)\n\n // Absorb any placeholder nodes that match by file_name or git_path\n this.absorbPlaceholders(node)\n\n const edgeType: EdgeType =\n op === 'create' ? 'produces' : op === 'delete' ? 'deletes' : 'modifies'\n\n if (tcid && this.actions.has(tcid)) {\n this.addEdge(`action-${tcid}`, fid, edgeType, ts)\n } else if (this.reasonings.size > 0) {\n // Action not yet registered (out-of-order SSE). When mcp_start arrives\n // later, handleMcpStart will retroactively add the correct action→file\n // edge. For now, attach to the latest reasoning so the node isn't orphaned.\n let latest: ReasoningNode | null = null\n for (const r of this.reasonings.values()) {\n if (!latest || r.timestamp > latest.timestamp) latest = r\n }\n if (latest) {\n this.addEdge(latest.id, fid, edgeType, ts)\n }\n }\n }\n\n /** JETP-026: create references edges from xref scan result. */\n private handleXrefScanResult(p: GraphSSEPayload): void {\n const ext = p.ext\n if (!ext) return\n const sourceFileId = ext.source_file_id as string | undefined\n const xrefs = ext.xrefs as Array<Record<string, unknown>> | undefined\n if (!sourceFileId || !xrefs) return\n\n const ts = this.parseTimestamp(p.timestamp)\n const sourceNodeId = `file-${sourceFileId}`\n\n for (const xref of xrefs) {\n const targetFileId = xref.target_file_id as string | undefined\n const targetResource = (xref.target_resource as string) ?? ''\n\n let targetNodeId: string\n\n if (targetFileId) {\n targetNodeId = `file-${targetFileId}`\n if (!this.files.has(targetNodeId)) {\n const resolved = this.resolveFileByName(targetFileId)\n if (resolved) {\n targetNodeId = resolved\n } else {\n this.files.set(targetNodeId, {\n id: targetNodeId,\n type: 'file',\n label: targetFileId,\n timestamp: ts,\n metadata: { placeholder: true },\n file_id: targetFileId,\n file_name: '',\n git_path: '',\n operation: 'referenced',\n agent_instance_id: 0,\n tool_call_id: null,\n task_purpose: null,\n })\n }\n }\n } else {\n const hash = this.simpleHash(targetResource)\n targetNodeId = `file-ext-url-${hash}`\n if (!this.files.has(targetNodeId)) {\n const displayUrl = targetResource.replace('url://', '')\n this.files.set(targetNodeId, {\n id: targetNodeId,\n type: 'file',\n label: displayUrl.length > 50 ? displayUrl.slice(0, 47) + '...' : displayUrl,\n timestamp: ts,\n metadata: { external: true },\n file_id: `ext-url-${hash}`,\n file_name: displayUrl,\n git_path: targetResource,\n operation: 'external',\n agent_instance_id: 0,\n tool_call_id: null,\n task_purpose: null,\n })\n }\n }\n\n const description = (xref.description as string) ?? ''\n this.addEdge(sourceNodeId, targetNodeId, 'references', ts, description)\n }\n }\n\n private handlePlanResult(p: GraphSSEPayload): void {\n const checklist = this.extractChecklist(p.content)\n if (!checklist) return\n\n for (const task of checklist) {\n const tid = task.id ? `task-${task.id}` : `task-${task.description.slice(0, 20)}`\n const node: TaskNode = {\n id: tid,\n type: 'task',\n label: task.description,\n timestamp: Date.now(),\n metadata: {},\n task_id: task.id ?? tid,\n description: task.description,\n status: task.status ?? 'pending',\n }\n this.tasks.set(tid, node)\n }\n }\n\n private handleModelStart(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n const rid = `reasoning-${callee}-${ts}`\n\n const node: ReasoningNode = {\n id: rid,\n type: 'reasoning',\n label: this.extractString(p.ext, 'model') ?? 'reasoning',\n timestamp: ts,\n metadata: {},\n agent_instance_id: callee,\n model: this.extractString(p.ext, 'model') ?? '',\n content_preview: '',\n token_count: null,\n duration_ms: null,\n status: 'thinking',\n }\n this.reasonings.set(rid, node)\n\n if (this.agents.has(callee)) {\n this.addEdge(`agent-inst-${callee}`, rid, 'thinks', ts)\n }\n\n const prevActions = this.lastCompletedActions.get(callee) ?? []\n for (const tcid of prevActions) {\n this.addEdge(`action-${tcid}`, rid, 'informs', ts)\n }\n this.lastCompletedActions.delete(callee)\n }\n\n private handleModelResult(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const latest = this.findLatestReasoning(callee)\n if (!latest) return\n\n const preview = String(this.extractString(p.ext, 'content_preview') ?? '').slice(0, 200)\n this.reasonings.set(latest.id, {\n ...latest,\n status: 'completed',\n ...(preview ? { content_preview: preview } : {}),\n })\n }\n\n private handleModelEnd(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const latest = this.findLatestReasoning(callee)\n if (!latest) return\n\n const endTs = this.parseTimestamp(p.timestamp)\n const duration = endTs - latest.timestamp\n const tokens = this.extractNumber(p.ext, 'total_tokens')\n\n this.reasonings.set(latest.id, {\n ...latest,\n status: 'completed',\n duration_ms: duration > 0 ? duration : null,\n token_count: tokens,\n })\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private addEdge(source: string, target: string, type: EdgeType, ts: number, label?: string): void {\n const key = this.edgeKey(source, target, type, label)\n if (this.edgeKeys.has(key)) return\n this.edgeKeys.add(key)\n this.edges.push({ source, target, type, label, timestamp: ts })\n }\n\n private edgeKey(source: string, target: string, type: string, label?: string): string {\n return label ? `${source}:${target}:${type}:${label}` : `${source}:${target}:${type}`\n }\n\n findLatestReasoning(agentInstanceId: number): ReasoningNode | null {\n let latest: ReasoningNode | null = null\n for (const r of this.reasonings.values()) {\n if (r.agent_instance_id === agentInstanceId) {\n if (!latest || r.timestamp > latest.timestamp) latest = r\n }\n }\n return latest\n }\n\n private parseTimestamp(ts: string | number | undefined): number {\n if (ts == null) return Date.now()\n if (typeof ts === 'number') return ts\n const n = Date.parse(ts)\n return Number.isNaN(n) ? Date.now() : n\n }\n\n private extractString(ext: Record<string, unknown> | undefined, key: string): string | null {\n if (!ext) return null\n const v = ext[key]\n return typeof v === 'string' ? v : null\n }\n\n private extractNumber(ext: Record<string, unknown> | undefined, key: string): number | null {\n if (!ext) return null\n const v = ext[key]\n return typeof v === 'number' ? v : null\n }\n\n private extractArtifactData(\n content: unknown[] | undefined,\n ): Record<string, string> | null {\n if (!content || !Array.isArray(content)) return null\n for (const part of content) {\n const c = (part as { content?: { data?: Record<string, string> } })?.content\n if (c?.data) return c.data\n }\n return null\n }\n\n private normalizeOperation(op: string | undefined): FileNode['operation'] {\n const o = (op ?? 'create').toLowerCase()\n if (o === 'create' || o === 'update' || o === 'delete' || o === 'external' || o === 'referenced') return o\n if (o.includes('create') || o.includes('add')) return 'create'\n if (o.includes('delete') || o.includes('remove')) return 'delete'\n return 'update'\n }\n\n /** Merge placeholder file nodes into a real node, remapping all edges.\n * Uses exact + stem matching (same ambiguity-safe logic as resolveFileByName). */\n private absorbPlaceholders(realNode: FileNode): void {\n const names = new Set<string>()\n if (realNode.file_name) {\n names.add(realNode.file_name)\n const fnStem = GraphBuilder.fileStem(realNode.file_name)\n if (fnStem !== realNode.file_name) names.add(fnStem)\n }\n if (realNode.git_path) {\n names.add(realNode.git_path)\n const gpStem = GraphBuilder.fileStem(realNode.git_path)\n if (gpStem !== realNode.git_path) names.add(gpStem)\n if (realNode.git_path.includes('/')) {\n const basename = realNode.git_path.split('/').pop()!\n names.add(basename)\n const bnStem = GraphBuilder.fileStem(basename)\n if (bnStem !== basename) names.add(bnStem)\n }\n }\n\n // Collect candidates; check for ambiguity per stem\n const stemHits = new Map<string, string[]>()\n for (const [id, node] of this.files) {\n if (id === realNode.id) continue\n if (!node.metadata?.placeholder) continue\n const matchKey = node.file_id || node.label\n if (names.has(matchKey)) {\n stemHits.set(id, [...(stemHits.get(id) ?? []), matchKey])\n }\n }\n\n const toRemove: string[] = []\n for (const [id] of stemHits) {\n for (const edge of this.edges) {\n if (edge.source === id) edge.source = realNode.id\n if (edge.target === id) edge.target = realNode.id\n }\n toRemove.push(id)\n }\n for (const id of toRemove) this.files.delete(id)\n }\n\n /** Match a file name/path against existing FileNodes by git_path or file_name.\n * Pass 1 — exact match. Pass 2 — stem match (extension stripped) when\n * *name* has no extension and exactly one non-placeholder candidate exists. */\n private resolveFileByName(name: string): string | null {\n for (const node of this.files.values()) {\n if (node.git_path === name || node.file_name === name) return node.id\n if (node.git_path && node.git_path.endsWith('/' + name)) return node.id\n }\n\n if (GraphBuilder.nameHasExtension(name)) return null\n\n const candidates: string[] = []\n for (const node of this.files.values()) {\n if (node.operation === 'referenced' || node.operation === 'external') continue\n if (node.file_name && GraphBuilder.fileStem(node.file_name) === name) {\n candidates.push(node.id)\n continue\n }\n if (node.git_path) {\n const gpStem = GraphBuilder.fileStem(node.git_path)\n if (gpStem === name || gpStem.endsWith('/' + name)) {\n candidates.push(node.id)\n continue\n }\n }\n }\n\n const unique = [...new Set(candidates)]\n return unique.length === 1 ? unique[0] : null\n }\n\n /** Strip trailing extension: 'arch.md' → 'arch', 'a/b.txt' → 'a/b'. */\n private static fileStem(name: string): string {\n const slash = name.lastIndexOf('/')\n const basename = name.slice(slash + 1)\n const dot = basename.lastIndexOf('.')\n if (dot > 0) return name.slice(0, slash + 1 + dot)\n return name\n }\n\n /** True when the trailing path component carries a dot-extension (ignores dotfiles). */\n private static nameHasExtension(name: string): boolean {\n const slash = name.lastIndexOf('/')\n const basename = name.slice(slash + 1)\n return basename.lastIndexOf('.') > 0\n }\n\n private simpleHash(s: string): string {\n let h = 0\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0\n }\n return Math.abs(h).toString(16).padStart(8, '0').slice(0, 8)\n }\n\n private extractChecklist(\n content: unknown[] | undefined,\n ): Array<{ id: string; description: string; status?: TaskNode['status'] }> | null {\n if (!content || !Array.isArray(content)) return null\n for (const part of content) {\n const typed = part as { type?: string; content?: { tasks?: unknown[] } }\n if (typed.type === 'checklist' && typed.content?.tasks) {\n return typed.content.tasks as Array<{\n id: string\n description: string\n status?: TaskNode['status']\n }>\n }\n }\n return null\n }\n}\n","/**\n * Provenance Graph API Client (SDK version)\n *\n * Delegates HTTP to the caller-supplied fetch function, decoupling from\n * any specific Axios instance or auth mechanism.\n */\n\nimport type { ProvenanceGraphSnapshot } from './types'\n\nexport interface FetchGraphOptions {\n sessionId: number\n sinceTurnId?: number | null\n limit?: number\n}\n\nexport type ProvenanceGraphFetcher = (\n sessionId: number,\n params?: { since_turn_id?: number; limit?: number },\n) => Promise<ProvenanceGraphSnapshot>\n\nexport async function fetchProvenanceGraph(\n fetcher: ProvenanceGraphFetcher,\n opts: FetchGraphOptions,\n): Promise<ProvenanceGraphSnapshot> {\n const params: { since_turn_id?: number; limit?: number } = {}\n if (opts.sinceTurnId != null && opts.sinceTurnId > 0) {\n params.since_turn_id = opts.sinceTurnId\n }\n if (opts.limit != null && opts.limit > 0) {\n params.limit = opts.limit\n }\n\n return fetcher(opts.sessionId, Object.keys(params).length > 0 ? params : undefined)\n}\n","/**\n * JETP-025: ProvenanceGraph3D\n *\n * Core 3D graph visualization using react-force-graph-3d (Three.js).\n * Renders agent/action/file/task/reasoning nodes as distinct 3D shapes\n * with animated edges, selection dimming, and camera focus.\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport ForceGraph3D from 'react-force-graph-3d'\nimport type { ForceGraphMethods } from 'react-force-graph-3d'\nimport * as THREE from 'three'\nimport SpriteText from 'three-spritetext'\nimport type { ProvenanceGraphSnapshot, ProvenanceNode, GraphEdge, NodeType } from '../types'\nimport { createNodeMesh, disposeGeometryCache } from './NodeMeshFactory'\nimport {\n NODE_COLORS,\n NODE_SIZES,\n EDGE_COLORS,\n EDGE_WIDTHS,\n SCENE_BG,\n LINK_PARTICLE_COUNT,\n LINK_PARTICLE_WIDTH,\n LINK_PARTICLE_SPEED,\n DIM_OPACITY,\n CAMERA_DISTANCE,\n CAMERA_FOCUS_DURATION_MS,\n LABEL_FONT_SIZE,\n LABEL_COLOR,\n} from '../constants'\n\n// ---------------------------------------------------------------------------\n// Internal node/link shapes for the force graph engine\n// ---------------------------------------------------------------------------\n\ninterface GraphNode3D {\n id: string\n type: NodeType\n label: string\n /** Second line: task_purpose (for action/file nodes) */\n subtitle?: string\n /** Content preview for reasoning cards */\n contentPreview?: string\n /** Agent name attribution for reasoning cards */\n agentLabel?: string\n status?: string\n level?: number\n agentInstanceId?: number\n x?: number\n y?: number\n z?: number\n}\n\ninterface GraphLink3D {\n source: string\n target: string\n type: string\n timestamp: number\n label?: string\n}\n\ninterface ProvenanceGraph3DProps {\n graph: ProvenanceGraphSnapshot\n width?: number\n height?: number\n selectedNodeId?: string | null\n onNodeClick?: (nodeId: string, nodeType: NodeType) => void\n onNodeHover?: (nodeId: string | null) => void\n onBackgroundClick?: () => void\n depthFilter?: number\n}\n\nconst HIDDEN_EDGE_TYPES = new Set(['spawns', 'executes', 'thinks'])\n\nfunction flattenNodes(snap: ProvenanceGraphSnapshot): ProvenanceNode[] {\n const { actions, files, tasks, reasonings } = snap.nodes\n return [...actions, ...files, ...tasks, ...reasonings]\n}\n\nfunction getConnectedIds(\n nodeId: string,\n edges: GraphEdge[],\n hops: number,\n): Set<string> {\n const visited = new Set<string>([nodeId])\n let frontier = new Set<string>([nodeId])\n\n for (let h = 0; h < hops; h++) {\n const next = new Set<string>()\n for (const e of edges) {\n if (frontier.has(e.source) && !visited.has(e.target)) {\n visited.add(e.target)\n next.add(e.target)\n }\n if (frontier.has(e.target) && !visited.has(e.source)) {\n visited.add(e.source)\n next.add(e.source)\n }\n }\n if (next.size === 0) break\n frontier = next\n }\n return visited\n}\n\nfunction truncate(s: string, maxLen: number): string {\n return s.length > maxLen ? s.slice(0, maxLen - 1) + '…' : s\n}\n\nfunction wrapText(s: string, lineWidth: number, maxLines: number): string {\n const clean = s.replace(/\\n/g, ' ').trim()\n const lines: string[] = []\n let pos = 0\n for (let i = 0; i < maxLines && pos < clean.length; i++) {\n const remaining = clean.slice(pos)\n if (remaining.length <= lineWidth) {\n lines.push(remaining)\n break\n }\n lines.push(remaining.slice(0, lineWidth))\n pos += lineWidth\n }\n const result = lines.join('\\n')\n return pos < clean.length ? result + '…' : result\n}\n\nconst ProvenanceGraph3DInner: React.FC<ProvenanceGraph3DProps> = ({\n graph,\n width,\n height,\n selectedNodeId = null,\n onNodeClick,\n onNodeHover,\n onBackgroundClick,\n depthFilter,\n}) => {\n const fgRef = useRef<ForceGraphMethods | undefined>(undefined)\n const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null)\n\n // Flatten snapshot into force-graph format (agents excluded)\n const graphData = useMemo(() => {\n const allNodes = flattenNodes(graph)\n const nodeMap = new Set(allNodes.map((n) => n.id))\n\n const purposeByNodeId = new Map<string, string>()\n for (const a of graph.nodes.actions) {\n if (a.task_purpose) purposeByNodeId.set(a.id, a.task_purpose)\n }\n for (const f of graph.nodes.files) {\n if (f.task_purpose) purposeByNodeId.set(f.id, f.task_purpose)\n }\n\n const previewById = new Map<string, string>()\n for (const r of graph.nodes.reasonings) {\n if (r.content_preview) previewById.set(r.id, r.content_preview)\n }\n\n const agentNameByInstId = new Map<number, string>()\n for (const a of graph.nodes.agents) {\n agentNameByInstId.set(a.agent_instance_id, a.agent_name || a.agent_id || `agent-${a.agent_instance_id}`)\n }\n\n const nodes: GraphNode3D[] = allNodes.map((n) => {\n const instId = 'agent_instance_id' in n\n ? (n as { agent_instance_id?: number }).agent_instance_id\n : undefined\n return {\n id: n.id,\n type: n.type,\n label: n.label,\n subtitle: purposeByNodeId.get(n.id),\n contentPreview: previewById.get(n.id),\n agentLabel: instId != null ? agentNameByInstId.get(instId) : undefined,\n status: 'status' in n ? (n as { status?: string }).status : undefined,\n level: 'level' in n ? (n as { level?: number }).level : undefined,\n agentInstanceId: instId,\n }\n })\n\n const links: GraphLink3D[] = graph.edges\n .filter((e) => !HIDDEN_EDGE_TYPES.has(e.type) && nodeMap.has(e.source) && nodeMap.has(e.target))\n .map((e) => {\n const purpose =\n purposeByNodeId.get(e.target) ?? purposeByNodeId.get(e.source) ?? undefined\n return {\n source: e.source,\n target: e.target,\n type: e.type,\n timestamp: e.timestamp,\n label: e.label || purpose,\n }\n })\n\n return { nodes, links }\n }, [graph])\n\n // Selection & dimming: compute visible set\n const connectedSet = useMemo(() => {\n if (!selectedNodeId) return null\n return getConnectedIds(selectedNodeId, graph.edges, depthFilter ?? 2)\n }, [selectedNodeId, graph.edges, depthFilter])\n\n // Node object factory\n const nodeThreeObject = useCallback(\n (node: GraphNode3D) => {\n const isDimmed = connectedSet != null && !connectedSet.has(node.id)\n const isSelected = node.id === selectedNodeId\n const isRunning = node.status === 'running' || node.status === 'thinking'\n\n const group = new THREE.Group()\n\n // Reasoning nodes → refined card with agent header + content body\n if (node.type === 'reasoning') {\n const agentName = node.agentLabel ?? 'Agent'\n const bodyText = node.contentPreview\n ? wrapText(node.contentPreview, 28, 2)\n : (isRunning ? 'Thinking…' : '')\n const dimAlpha = isDimmed ? 0.15 : 1\n\n // Agent name header\n const header = new SpriteText(\n (isRunning ? '● ' : '') + agentName,\n 2,\n isDimmed ? '#bbb' : (isRunning ? '#9b59b6' : '#667eea'),\n )\n header.fontFace = 'Inter, system-ui, sans-serif'\n header.fontWeight = '600'\n header.backgroundColor = 'transparent'\n header.padding = [0, 0]\n header.position.y = bodyText ? 4.5 : 0\n header.material.opacity = dimAlpha\n group.add(header)\n\n // Content body\n if (bodyText) {\n const body = new SpriteText(\n bodyText,\n 2.2,\n isDimmed ? '#ccc' : '#444',\n )\n body.fontFace = 'Inter, system-ui, sans-serif'\n body.backgroundColor = isDimmed\n ? 'rgba(245,245,245,0.2)'\n : isSelected\n ? 'rgba(102,126,234,0.08)'\n : 'rgba(255,255,255,0.92)'\n body.borderWidth = isSelected ? 1 : 0.4\n body.borderColor = isDimmed\n ? 'transparent'\n : isSelected ? 'rgba(102,126,234,0.5)' : 'rgba(0,0,0,0.08)'\n body.borderRadius = 3\n body.padding = [2.5, 4]\n body.material.opacity = dimAlpha\n group.add(body)\n }\n\n return group\n }\n\n const mesh = createNodeMesh(node.type, {\n selected: isSelected,\n dimmed: isDimmed,\n running: isRunning,\n })\n group.add(mesh)\n\n const nodeRadius = NODE_SIZES[node.type] ?? 5\n\n if (isRunning && !isDimmed) {\n const ringGeo = new THREE.RingGeometry(nodeRadius * 1.6, nodeRadius * 1.8, 32)\n const ringMat = new THREE.MeshBasicMaterial({\n color: NODE_COLORS[node.type as NodeType] ?? '#667eea',\n transparent: true,\n opacity: 0.4,\n side: THREE.DoubleSide,\n })\n const ring = new THREE.Mesh(ringGeo, ringMat)\n ring.rotation.x = Math.PI / 2\n ring.userData.__orbitRing = true\n group.add(ring)\n }\n\n if (!isDimmed) {\n const nameLabel = new SpriteText(\n truncate(node.label, 20),\n LABEL_FONT_SIZE,\n LABEL_COLOR,\n )\n nameLabel.backgroundColor = 'rgba(255,255,255,0.85)'\n nameLabel.borderRadius = 2\n nameLabel.padding = [1, 3]\n nameLabel.position.y = -(nodeRadius + 4)\n group.add(nameLabel)\n\n if (node.subtitle) {\n const purposeLabel = new SpriteText(\n truncate(node.subtitle, 16),\n 2.2,\n '#888',\n )\n purposeLabel.backgroundColor = 'rgba(245,247,250,0.9)'\n purposeLabel.borderRadius = 1.5\n purposeLabel.padding = [0.5, 2]\n purposeLabel.position.y = -(nodeRadius + 8)\n group.add(purposeLabel)\n }\n }\n\n return group\n },\n [connectedSet, selectedNodeId],\n )\n\n const CAUSAL_EDGES = new Set(['triggers', 'informs'])\n\n // Link color — invisible edge types get fully transparent color\n const linkColor = useCallback(\n (link: GraphLink3D) => {\n const edgeColor = EDGE_COLORS[link.type as keyof typeof EDGE_COLORS] ?? '#c0c0c0'\n if (connectedSet) {\n const srcId =\n typeof link.source === 'object' ? (link.source as GraphNode3D).id : link.source\n const tgtId =\n typeof link.target === 'object' ? (link.target as GraphNode3D).id : link.target\n if (!connectedSet.has(srcId) || !connectedSet.has(tgtId)) {\n return `rgba(200,200,200,${DIM_OPACITY})`\n }\n }\n return edgeColor\n },\n [connectedSet],\n )\n\n // Link width — invisible edges get zero width\n const linkWidth = useCallback(\n (link: GraphLink3D) => {\n const base = EDGE_WIDTHS[link.type as keyof typeof EDGE_WIDTHS] ?? 1.5\n return base * 1.2\n },\n [],\n )\n\n // Per-edge curvature: causal edges curve more to visually separate from structural edges\n const linkCurvature = useCallback(\n (link: GraphLink3D) => {\n if (link.type === 'references') return 0.35\n if (link.type === 'informs') return 0.3\n if (link.type === 'triggers') return 0.2\n return 0.06\n },\n [],\n )\n\n // Per-edge particle speed: causal edges have faster-moving particles\n const linkParticleSpeed = useCallback(\n (link: GraphLink3D) => {\n if (CAUSAL_EDGES.has(link.type)) return 0.008\n return LINK_PARTICLE_SPEED\n },\n [],\n )\n\n // Per-edge arrow length — invisible edges get no arrow\n const linkArrowLength = useCallback(\n (link: GraphLink3D) => {\n if (CAUSAL_EDGES.has(link.type)) return 7\n return 4\n },\n [],\n )\n\n // Particles on edges — none for invisible or reference edges\n const linkParticles = useCallback(\n (link: GraphLink3D) => {\n if (link.type === 'references') return 0\n if (connectedSet) {\n const srcId =\n typeof link.source === 'object' ? (link.source as GraphNode3D).id : link.source\n const tgtId =\n typeof link.target === 'object' ? (link.target as GraphNode3D).id : link.target\n if (!connectedSet.has(srcId) || !connectedSet.has(tgtId)) return 0\n }\n return LINK_PARTICLE_COUNT\n },\n [connectedSet],\n )\n\n // Configure forces — strong repulsion + typed link distances for readable spread\n useEffect(() => {\n if (!fgRef.current) return\n const fg = fgRef.current\n try {\n fg.d3Force('charge')?.strength(-420)\n fg.d3Force('link')?.distance((link: GraphLink3D) => {\n switch (link.type) {\n case 'references': return 160\n case 'informs': return 120\n case 'triggers': return 100\n case 'spawns': return 140\n default: return 80\n }\n })\n fg.d3Force('center')?.strength(0.04)\n } catch {\n // d3Force may not be ready yet\n }\n }, [graphData])\n\n // Camera focus on selection\n useEffect(() => {\n if (!selectedNodeId || !fgRef.current) return\n const node = graphData.nodes.find((n) => n.id === selectedNodeId)\n if (!node || node.x == null || node.y == null || node.z == null) return\n\n fgRef.current.cameraPosition(\n { x: node.x + CAMERA_DISTANCE * 0.3, y: node.y + CAMERA_DISTANCE * 0.2, z: node.z + CAMERA_DISTANCE * 0.5 },\n { x: node.x, y: node.y, z: node.z },\n CAMERA_FOCUS_DURATION_MS,\n )\n }, [selectedNodeId, graphData.nodes])\n\n // Setup scene lighting\n useEffect(() => {\n if (!fgRef.current) return\n try {\n const scene = fgRef.current.scene()\n if (!scene) return\n\n if (scene.userData.__lightsConfigured) return\n scene.userData.__lightsConfigured = true\n\n const ambient = new THREE.AmbientLight(0xffffff, 0.7)\n const directional = new THREE.DirectionalLight(0xffffff, 0.8)\n directional.position.set(100, 200, 150)\n scene.add(ambient, directional)\n\n scene.fog = new THREE.Fog(SCENE_BG, 600, 1600)\n } catch {\n // scene may not be ready\n }\n })\n\n // Animate orbit rings\n useEffect(() => {\n let frameId: number\n const animate = () => {\n if (!fgRef.current) return\n try {\n const scene = fgRef.current.scene()\n if (!scene) return\n scene.traverse((obj: THREE.Object3D) => {\n if (obj.userData.__orbitRing) {\n obj.rotation.z += 0.02\n }\n })\n } catch {\n // ignore\n }\n frameId = requestAnimationFrame(animate)\n }\n frameId = requestAnimationFrame(animate)\n return () => cancelAnimationFrame(frameId)\n }, [])\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n disposeGeometryCache()\n }\n }, [])\n\n const handleNodeClick = useCallback(\n (node: GraphNode3D) => {\n onNodeClick?.(node.id, node.type)\n },\n [onNodeClick],\n )\n\n const handleNodeHover = useCallback(\n (node: GraphNode3D | null) => {\n const id = node?.id ?? null\n setHoveredNodeId(id)\n onNodeHover?.(id)\n },\n [onNodeHover],\n )\n\n const handleBgClick = useCallback(() => {\n onBackgroundClick?.()\n }, [onBackgroundClick])\n\n // Edge hover tooltip — shows edge type + task_purpose\n const EDGE_TYPE_LABELS: Record<string, string> = {\n spawns: 'Spawns',\n executes: 'Executes',\n produces: 'Produces',\n modifies: 'Modifies',\n deletes: 'Deletes',\n thinks: 'Thinks',\n triggers: 'Triggers',\n informs: 'Informs',\n references: '引用', // JETP-026\n }\n\n const linkLabel = useCallback(\n (link: GraphLink3D) => {\n const typeLabel = EDGE_TYPE_LABELS[link.type] ?? link.type\n const color = EDGE_COLORS[link.type as keyof typeof EDGE_COLORS] ?? '#888'\n const lines = [\n `<span style=\"color:${color};font-weight:600\">${typeLabel}</span>`,\n ]\n if (link.label) lines.push(link.label)\n return `<div style=\"background:rgba(255,255,255,0.96);color:#444;padding:8px 12px;border-radius:6px;font-size:13px;line-height:1.6;box-shadow:0 2px 8px rgba(0,0,0,0.12);max-width:320px;word-break:break-all;border:1px solid #e8e8e8\">${lines.join('<br/>')}</div>`\n },\n [],\n )\n\n // Node hover tooltip\n const nodeLabel = useCallback(\n (node: GraphNode3D) => {\n if (hoveredNodeId !== node.id) return ''\n const lines: string[] = []\n if (node.type === 'reasoning') {\n lines.push(`<b>${node.agentLabel ?? 'Reasoning'}</b>`)\n if (node.status) lines.push(`Status: ${node.status}`)\n if (node.contentPreview) {\n const preview = node.contentPreview.length > 120\n ? node.contentPreview.slice(0, 120) + '…'\n : node.contentPreview\n lines.push(`<span style=\"color:#666\">${preview}</span>`)\n }\n } else {\n lines.push(`<b>${node.label}</b>`)\n if (node.subtitle) lines.push(`Purpose: ${node.subtitle}`)\n if (node.status) lines.push(`Status: ${node.status}`)\n }\n return `<div style=\"background:rgba(255,255,255,0.96);color:#333;padding:8px 12px;border-radius:6px;font-size:13px;line-height:1.6;box-shadow:0 2px 8px rgba(0,0,0,0.15);border:1px solid #e8e8e8;max-width:360px;word-break:break-all\">${lines.join('<br/>')}</div>`\n },\n [hoveredNodeId],\n )\n\n return (\n <ForceGraph3D\n ref={fgRef as React.MutableRefObject<ForceGraphMethods | undefined>}\n graphData={graphData}\n width={width}\n height={height}\n backgroundColor={`#${SCENE_BG.toString(16).padStart(6, '0')}`}\n showNavInfo={false}\n nodeThreeObject={nodeThreeObject as (node: object) => THREE.Object3D}\n nodeLabel={nodeLabel as (node: object) => string}\n linkLabel={linkLabel as (link: object) => string}\n linkColor={linkColor as (link: object) => string}\n linkWidth={linkWidth as (link: object) => number}\n linkOpacity={0.75}\n linkCurvature={linkCurvature as unknown as (link: object) => number}\n /* linkLineDash not in TS typings; inject at runtime if the version supports it */\n linkDirectionalParticles={linkParticles as (link: object) => number}\n linkDirectionalParticleWidth={LINK_PARTICLE_WIDTH}\n linkDirectionalParticleSpeed={linkParticleSpeed as unknown as (link: object) => number}\n linkDirectionalParticleColor={linkColor as (link: object) => string}\n linkDirectionalArrowLength={linkArrowLength as unknown as (link: object) => number}\n linkDirectionalArrowRelPos={0.92}\n linkDirectionalArrowColor={linkColor as (link: object) => string}\n d3AlphaDecay={0.04}\n d3VelocityDecay={0.4}\n warmupTicks={200}\n cooldownTicks={0}\n cooldownTime={3000}\n onNodeClick={handleNodeClick as (node: object, event: MouseEvent) => void}\n onNodeHover={handleNodeHover as (node: object | null, prev: object | null) => void}\n onBackgroundClick={handleBgClick}\n enableNodeDrag\n enableNavigationControls\n />\n )\n}\n\nexport const ProvenanceGraph3D = React.memo(ProvenanceGraph3DInner)\n","/**\n * JETP-025: NodeMeshFactory\n *\n * Creates distinctive Three.js meshes for each node type:\n * agent → Sphere (smooth, primary)\n * action → Icosahedron (faceted, dynamic)\n * file → Box (stable, structural)\n * task → Octahedron (angular, directional)\n * reasoning → Torus (continuous, cyclical thinking)\n *\n * Each mesh uses MeshStandardMaterial with emissive glow.\n * Reuses geometries via a cache for GPU efficiency.\n */\n\nimport * as THREE from 'three'\nimport type { NodeType } from '../types'\nimport {\n NODE_COLORS_HEX,\n NODE_EMISSIVE,\n NODE_SIZES,\n DIM_OPACITY,\n NORMAL_OPACITY,\n SELECTED_SCALE,\n} from '../constants'\n\nconst geoCache = new Map<string, THREE.BufferGeometry>()\n\nfunction getOrCreateGeometry(type: NodeType): THREE.BufferGeometry {\n const cached = geoCache.get(type)\n if (cached) return cached\n\n let geo: THREE.BufferGeometry\n const s = NODE_SIZES[type]\n\n switch (type) {\n case 'agent':\n geo = new THREE.SphereGeometry(s, 24, 16)\n break\n case 'action':\n geo = new THREE.IcosahedronGeometry(s, 0)\n break\n case 'file':\n geo = new THREE.BoxGeometry(s * 1.2, s * 1.2, s * 1.2)\n break\n case 'task':\n geo = new THREE.OctahedronGeometry(s, 0)\n break\n case 'reasoning':\n geo = new THREE.TorusGeometry(s * 0.7, s * 0.3, 12, 24)\n break\n default:\n geo = new THREE.SphereGeometry(s, 16, 12)\n }\n\n geoCache.set(type, geo)\n return geo\n}\n\nexport interface NodeMeshOptions {\n selected?: boolean\n dimmed?: boolean\n running?: boolean\n}\n\nexport function createNodeMesh(type: NodeType, opts: NodeMeshOptions = {}): THREE.Mesh {\n const geo = getOrCreateGeometry(type)\n const mat = new THREE.MeshStandardMaterial({\n color: NODE_COLORS_HEX[type],\n emissive: NODE_EMISSIVE[type],\n emissiveIntensity: opts.selected ? 0.6 : 0.25,\n metalness: 0.15,\n roughness: 0.55,\n transparent: true,\n opacity: opts.dimmed ? DIM_OPACITY : NORMAL_OPACITY,\n })\n\n const mesh = new THREE.Mesh(geo, mat)\n\n if (opts.selected) {\n mesh.scale.setScalar(SELECTED_SCALE)\n }\n\n mesh.castShadow = false\n mesh.receiveShadow = false\n\n return mesh\n}\n\n/** Apply selection/dimming state to an existing mesh */\nexport function updateMeshState(\n mesh: THREE.Mesh,\n _type: NodeType,\n opts: NodeMeshOptions,\n): void {\n const mat = mesh.material as THREE.MeshStandardMaterial\n mat.opacity = opts.dimmed ? DIM_OPACITY : NORMAL_OPACITY\n mat.emissiveIntensity = opts.selected ? 0.6 : 0.25\n mesh.scale.setScalar(opts.selected ? SELECTED_SCALE : 1)\n}\n\n/** Cleanup cached geometries (call on unmount) */\nexport function disposeGeometryCache(): void {\n for (const geo of geoCache.values()) {\n geo.dispose()\n }\n geoCache.clear()\n}\n","/**\n * JETP-025: Provenance Graph Visual Constants\n *\n * JetForge light-theme palette adapted for 3D graph rendering.\n * Primary: #667eea Background: #f5f7fa\n */\n\nimport type { NodeType, EdgeType } from './types'\n\n// ---------------------------------------------------------------------------\n// Node colors — vibrant against light scene background\n// ---------------------------------------------------------------------------\n\nexport const NODE_COLORS: Record<NodeType, string> = {\n agent: '#667eea',\n action: '#f5a623',\n file: '#50c878',\n task: '#e74c8b',\n reasoning: '#9b59b6',\n}\n\nexport const NODE_COLORS_HEX: Record<NodeType, number> = {\n agent: 0x667eea,\n action: 0xf5a623,\n file: 0x50c878,\n task: 0xe74c8b,\n reasoning: 0x9b59b6,\n}\n\nexport const NODE_EMISSIVE: Record<NodeType, number> = {\n agent: 0x3350c0,\n action: 0xc07a10,\n file: 0x2a8a48,\n task: 0xb83070,\n reasoning: 0x6e3a8a,\n}\n\n// ---------------------------------------------------------------------------\n// Node sizes (Three.js units)\n// ---------------------------------------------------------------------------\n\nexport const NODE_SIZES: Record<NodeType, number> = {\n agent: 6,\n action: 4.5,\n file: 3.5,\n task: 4,\n reasoning: 5,\n}\n\n// ---------------------------------------------------------------------------\n// Edge colors\n// ---------------------------------------------------------------------------\n\nexport const EDGE_COLORS: Record<EdgeType, string> = {\n spawns: '#667eea',\n executes: '#f5a623',\n produces: '#50c878',\n modifies: '#36a3d9',\n deletes: '#e74c3c',\n thinks: '#9b59b6',\n triggers: '#e67e22',\n informs: '#3498db',\n references: '#8e44ad', // JETP-026: purple for cross-references\n}\n\nexport const EDGE_WIDTHS: Record<EdgeType, number> = {\n spawns: 3,\n executes: 2,\n produces: 1.8,\n modifies: 1.8,\n deletes: 1.5,\n thinks: 2.5,\n triggers: 2,\n informs: 1.8,\n references: 1.0, // JETP-026: thin for cross-references\n}\n\n// ---------------------------------------------------------------------------\n// Scene / camera\n// ---------------------------------------------------------------------------\n\nexport const SCENE_BG = 0xf5f7fa\nexport const SCENE_FOG_COLOR = 0xf5f7fa\nexport const SCENE_FOG_NEAR = 800\nexport const SCENE_FOG_FAR = 2400\n\nexport const CAMERA_DISTANCE = 400\nexport const CAMERA_FOCUS_DURATION_MS = 600\n\n// ---------------------------------------------------------------------------\n// Link particle\n// ---------------------------------------------------------------------------\n\nexport const LINK_PARTICLE_COUNT = 2\nexport const LINK_PARTICLE_WIDTH = 3\nexport const LINK_PARTICLE_SPEED = 0.004\n\n// ---------------------------------------------------------------------------\n// Layout\n// ---------------------------------------------------------------------------\n\nexport const FORCE_LINK_DISTANCE = 80\nexport const FORCE_CHARGE = -420\nexport const FORCE_CENTER_STRENGTH = 0.04\n\n// ---------------------------------------------------------------------------\n// Selection & Dimming\n// ---------------------------------------------------------------------------\n\nexport const DIM_OPACITY = 0.08\nexport const SELECTED_SCALE = 1.4\nexport const NORMAL_OPACITY = 0.9\n\n// ---------------------------------------------------------------------------\n// Labels\n// ---------------------------------------------------------------------------\n\nexport const LABEL_FONT_SIZE = 3\nexport const LABEL_COLOR = '#333'\nexport const LABEL_BG_COLOR = 'rgba(255,255,255,0.85)'\n","/**\n * JETP-025: GraphStatsLegend\n *\n * Floating legend showing node counts by type and edge total.\n */\n\nimport React, { useMemo } from 'react'\nimport { Badge, Space } from 'antd'\nimport type { GraphStats, NodeType } from '../types'\nimport { NODE_COLORS, EDGE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\n\ninterface GraphStatsLegendProps {\n stats: GraphStats\n edgeCount: number\n}\n\nconst LEGEND_LABEL_KEYS: Record<string, 'provenance.legend.reasoning' | 'provenance.legend.action' | 'provenance.legend.file' | 'provenance.legend.task'> = {\n reasoning: 'provenance.legend.reasoning',\n action: 'provenance.legend.action',\n file: 'provenance.legend.file',\n task: 'provenance.legend.task',\n}\n\nconst LEGEND_TYPES: NodeType[] = ['reasoning', 'action', 'file', 'task']\n\nconst statKey = (type: NodeType): keyof GraphStats => {\n const map: Record<NodeType, keyof GraphStats> = {\n agent: 'agent_count',\n action: 'action_count',\n file: 'file_count',\n task: 'task_count',\n reasoning: 'reasoning_count',\n }\n return map[type]\n}\n\nconst GraphStatsLegendInner: React.FC<GraphStatsLegendProps> = ({\n stats,\n edgeCount,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const legendItems = useMemo(() =>\n LEGEND_TYPES.map((type) => ({ type, label: t(LEGEND_LABEL_KEYS[type]) })),\n [t],\n )\n\n return (\n <div\n style={{\n position: 'absolute',\n left: 16,\n bottom: 16,\n zIndex: 10,\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n padding: '10px 14px',\n borderRadius: 10,\n boxShadow: '0 1px 6px rgba(0,0,0,0.08)',\n fontSize: 12,\n lineHeight: 1.8,\n }}\n >\n <Space orientation=\"vertical\" size={2}>\n {legendItems.map(({ type, label }) => {\n const count = stats[statKey(type)] as number\n if (count === 0) return null\n return (\n <div key={type} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Badge color={NODE_COLORS[type]} />\n <span style={{ color: '#555' }}>{label}</span>\n <span style={{ fontWeight: 600, color: '#333' }}>{count}</span>\n </div>\n )\n })}\n {/* JETP-026: references edge legend */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <div\n style={{\n width: 14,\n height: 0,\n borderTop: `2px dashed ${EDGE_COLORS.references}`,\n }}\n />\n <span style={{ color: '#555' }}>{t('provenance.legend.references')}</span>\n </div>\n <div style={{ borderTop: '1px solid #eee', paddingTop: 4, marginTop: 2 }}>\n <span style={{ color: '#999' }}>{t('provenance.legend.edges')}</span>\n <span style={{ fontWeight: 600, color: '#333' }}>{edgeCount}</span>\n <span style={{ color: '#999', marginLeft: 8 }}>\n {t('provenance.legend.depth')}{stats.max_depth}\n </span>\n </div>\n </Space>\n </div>\n )\n}\n\nexport const GraphStatsLegend = React.memo(GraphStatsLegendInner)\n","import { createContext, useContext, useCallback } from 'react'\nimport type { ChatWidgetMessages, ChatWidgetLocale } from './messages.js'\nimport { zhCN, interpolate } from './messages.js'\n\nexport const I18nContext = createContext<ChatWidgetMessages>(zhCN)\n\nexport function useChatWidgetI18n() {\n const messages = useContext(I18nContext)\n\n const locale: ChatWidgetLocale = (messages['locale'] as ChatWidgetLocale) || 'zh-CN'\n\n const t = useCallback(\n (key: keyof ChatWidgetMessages, params?: Record<string, string | number>): string => {\n const template = messages[key] ?? key\n return interpolate(template, params)\n },\n [messages],\n )\n\n return { messages, t, locale }\n}\n","export interface ChatWidgetMessages {\n 'header.title': string\n 'header.icon': string\n 'status.connecting': string\n 'status.running': string\n 'status.compressing': string\n 'status.error': string\n 'status.idle': string\n 'empty.waiting': string\n 'empty.icon': string\n 'round.separator': string\n 'round.status.running': string\n 'round.status.completed': string\n 'round.status.error': string\n 'round.noMessage': string\n 'footer.attribution': string\n 'selection.ask': string\n 'viewer.loading': string\n 'viewer.error': string\n 'viewer.back': string\n 'viewer.defaultTitle': string\n 'viewer.copyFull': string\n 'viewer.copyFullTitle': string\n 'viewer.referenceFile': string\n 'viewer.referenceFileTitle': string\n 'viewer.referencePage': string\n 'viewer.referencePageTitle': string\n 'viewer.download': string\n 'viewer.fullscreen': string\n 'viewer.fullscreenExit': string\n 'viewer.close': string\n 'viewer.unknownType': string\n 'viewer.iframeHint': string\n 'viewer.copySnippet': string\n 'viewer.loadingPdf': string\n 'viewer.pdfPages': string\n 'viewer.loadingKicad': string\n 'viewer.loading3d': string\n 'viewer.loadingStep': string\n 'viewer.3d.wireframe': string\n 'viewer.3d.resetView': string\n 'viewer.gerberTitle': string\n 'viewer.gerberBlobWarning': string\n 'viewer.gerberNoHttpUrl': string\n 'viewer.pdfPreview': string\n 'viewer.htmlPreview': string\n 'viewer.htmlProjectLoading': string\n 'viewer.htmlProjectNoEntry': string\n 'viewer.htmlProjectSizeLimit': string\n 'viewer.htmlStrategyForcedInlineWarning': string\n 'viewer.htmlStrategyFallbackCspWarning': string\n 'viewer.copyFullKicadTitle': string\n 'viewer.zoomIn': string\n 'viewer.zoomOut': string\n 'viewer.zoomReset': string\n 'viewer.loadingWord': string\n 'viewer.loadingExcel': string\n 'viewer.loadingPowerPoint': string\n 'viewer.pptPrev': string\n 'viewer.pptNext': string\n 'viewer.pptSlide': string\n 'viewer.pptThumbnails': string\n 'viewer.excelRows': string\n 'viewer.excelColumns': string\n 'childAgent.status.running': string\n 'childAgent.status.completed': string\n 'hitl.form.defaultTitle': string\n 'hitl.wait.default': string\n 'todo.completed.count': string\n 'todo.blocked.count': string\n 'todo.more': string\n 'todo.header.done': string\n 'tool.phase.generating': string\n 'tool.phase.executing': string\n 'tool.phase.complete': string\n 'tool.phase.error': string\n 'tool.executing': string\n 'tool.mcp.running': string\n 'tool.mcp.success': string\n 'tool.mcp.error': string\n 'form.placeholder.select': string\n 'form.required.default': string\n 'form.submit.submit': string\n 'form.submit.submitting': string\n 'form.requestId': string\n 'pinned.label': string\n 'plan.title': string\n 'plan.step': string\n 'thinking.inProgress': string\n 'thinking.completed': string\n 'split.unreadCount': string\n 'split.askQuestion': string\n 'split.exitFullscreen': string\n 'context.inputPlaceholder': string\n 'context.inputPlaceholderWithFile': string\n 'context.send': string\n 'context.removeReference': string\n 'split.home': string\n 'split.workspace': string\n 'split.annotation': string\n 'split.tabClose': string\n 'split.tabNew': string\n 'workspace.title': string\n 'workspace.searchPlaceholder': string\n 'workspace.empty': string\n 'workspace.downloadAll': string\n 'workspace.recent': string\n 'workspace.open': string\n 'workspace.openInNewTab': string\n 'workspace.download': string\n 'workspace.copyPath': string\n 'workspace.expandAll': string\n 'workspace.collapseAll': string\n 'annotation.title': string\n 'annotation.empty': string\n 'annotation.fileLevelTitle': string\n 'annotation.fileLevelPlaceholder': string\n 'annotation.anchoredPlaceholder': string\n 'annotation.inlineInputPlaceholder': string\n 'annotation.replyPlaceholder': string\n 'annotation.anchorLabel': string\n 'annotation.close': string\n 'annotation.fabLabel': string\n 'annotation.fabHeader': string\n 'annotation.messageCount': string\n 'annotation.anchorInvalid': string\n 'annotation.errorRetry': string\n 'annotation.queuedHint': string\n 'annotation.selectionLabel': string\n 'agentControl.pause': string\n 'agentControl.resume': string\n 'agentControl.stop': string\n 'agentControl.paused': string\n 'agentControl.groupTitle': string\n 'aria.fileNavigation': string\n 'kicad.loadFailed': string\n 'kicad.urlNotReady': string\n 'kicad.loadingEngine': string\n 'kicad.sidebarTitle': string\n 'kicad.sidebarPcb': string\n 'kicad.sidebarSch': string\n 'kicad.sidebarGeneric': string\n 'kicad.viewVisual': string\n 'kicad.viewSource': string\n 'provenance.filter.type.agent': string\n 'provenance.filter.type.action': string\n 'provenance.filter.type.file': string\n 'provenance.filter.type.task': string\n 'provenance.filter.type.reasoning': string\n 'provenance.filter.depth': string\n 'provenance.toolbar.zoomToFit': string\n 'provenance.toolbar.resetCamera': string\n 'provenance.toolbar.refresh': string\n 'provenance.legend.reasoning': string\n 'provenance.legend.action': string\n 'provenance.legend.file': string\n 'provenance.legend.task': string\n 'provenance.legend.references': string\n 'provenance.legend.edges': string\n 'provenance.legend.depth': string\n 'provenance.detail.title': string\n 'provenance.detail.noSelection': string\n 'provenance.detail.label.name': string\n 'provenance.detail.label.id': string\n 'provenance.detail.label.timestamp': string\n 'provenance.detail.label.agentId': string\n 'provenance.detail.label.instanceId': string\n 'provenance.detail.label.level': string\n 'provenance.detail.label.status': string\n 'provenance.detail.label.tool': string\n 'provenance.detail.label.purpose': string\n 'provenance.detail.label.duration': string\n 'provenance.detail.label.path': string\n 'provenance.detail.label.operation': string\n 'provenance.detail.label.taskId': string\n 'provenance.detail.label.description': string\n 'provenance.detail.label.model': string\n 'provenance.detail.label.tokenCount': string\n 'provenance.detail.label.reasoningPreview': string\n 'provenance.detail.relatedEdges': string\n 'provenance.page.noSessionHint': string\n 'provenance.page.loading': string\n 'provenance.page.emptyGraph': string\n 'provenance.drawer.emptyGraph': string\n 'provenance.graph.edgeType.references': string\n 'toolResult.label': string\n 'toolResult.expandAll': string\n 'toolResult.searchSummary': string\n 'toolResult.scrapeSummary': string\n 'toolResult.more': string\n 'plan.status.active': string\n 'pinned.noMessage': string\n 'viewer.fallback.unknownType': string\n 'viewer.fallback.download': string\n 'fileSize.B': string\n 'fileSize.KB': string\n 'fileSize.MB': string\n 'thinking.title': string\n 'thinking.step': string\n 'viewer.stepHint': string\n 'viewer.threeHint': string\n 'reference.header': string\n 'history.noMessage': string\n 'agent.defaultName': string\n 'error.unknown': string\n 'locale': string\n 'skill.inlineLabel': string\n 'skill.empty': string\n 'skill.searchPlaceholder': string\n 'skill.removeLabel': string\n 'skill.loading': string\n 'skill.loadError': string\n 'skill.loadMore': string\n 'skill.selectorLabel': string\n 'pool.idle': string\n 'pool.collaborating': string\n /** JETP-083 WS3.7.7 follow-up: badge text when at least one agent is\n * paused on a HIL response (no RUNNING agents). ``{{count}}`` = number\n * of paused agents. */\n 'pool.awaiting': string\n 'pool.title': string\n 'pool.empty': string\n 'pool.state.running': string\n /** JETP-083 WS3.7.7 follow-up: agent-row state label for an agent that\n * is blocked inside ``_await_genui_blocking`` waiting on a human HIL\n * reply. Distinguishes from ``running`` / ``completed`` / ``lost``;\n * mapped from backend ``state=\"PAUSED\"``. */\n 'pool.state.paused': string\n 'pool.state.completed': string\n 'pool.state.lost': string\n 'pool.state.unknown': string\n 'input.placeholder': string\n 'input.placeholderLoading': string\n 'discussion.title': string\n 'discussion.empty': string\n 'discussion.active': string\n 'discussion.resolved': string\n 'discussion.archived': string\n 'round.foreign.label': string\n 'round.foreign.unread': string\n 'round.foreign.expand': string\n 'sidebar.mainChat': string\n 'sidebar.chat': string\n 'sidebar.fileQA': string\n 'sidebar.selectionQA': string\n 'sessionList.title': string\n 'sessionList.newSession': string\n 'sessionList.logout': string\n 'sessionList.loading': string\n 'sessionList.empty': string\n 'sessionList.unsupported': string\n 'sessionList.untitled': string\n 'sessionList.deleteTitle': string\n 'sessionList.deleteConfirm': string\n 'sessionList.prevPage': string\n 'sessionList.nextPage': string\n 'sessionList.pageInfo': string\n // ModelPicker (composer 内的\"本次发送使用的模型\"切换器)\n 'modelPicker.menu.head': string\n 'modelPicker.menu.aria': string\n 'modelPicker.auto.title': string\n 'modelPicker.auto.hint.knownChannel': string\n 'modelPicker.auto.hint.knownBasename': string\n 'modelPicker.auto.hint.fallback': string\n 'modelPicker.row.hint.channelMulti': string\n 'modelPicker.row.hint.channelSingle': string\n 'modelPicker.row.hint.versionMulti': string\n 'modelPicker.fallback.placeholder': string\n 'modelPicker.inert.title': string\n 'modelPicker.guestLocked.label': string\n 'modelPicker.guestLocked.title': string\n 'modelPicker.loadingList': string\n 'modelPicker.trigger.title.stale': string\n 'modelPicker.trigger.title.agentDefault.withChannel': string\n 'modelPicker.trigger.title.agentDefault': string\n 'modelPicker.trigger.title.current': string\n 'modelPicker.row.title.pickDefault': string\n 'modelPicker.row.title.pick': string\n 'modelPicker.chip.aria': string\n 'modelPicker.chip.title.available': string\n 'modelPicker.chip.title.unavailable': string\n // CWRF-013 Phase 4 P2-T00 — `jr-primitives` i18n namespace\n // (spec drift D-I18N-01: rather than pull in `react-i18next` + `i18next`\n // as the spec D9 originally proposed, we extend the existing chat-widget\n // in-house i18n. Same key semantics, zero new dependency.)\n 'jr.confirmDialog.cancel': string\n 'jr.confirmDialog.confirm': string\n 'jr.confirmDialog.loading': string\n}\n\nexport const zhCN: ChatWidgetMessages = {\n 'header.title': 'YumiAI',\n 'header.icon': '',\n 'status.connecting': '连接中...',\n 'status.running': '执行中...',\n 'status.compressing': '上下文压缩中...',\n 'status.error': '连接错误',\n 'status.idle': '待命',\n 'empty.waiting': '等待对话开始...',\n 'empty.icon': '',\n 'round.separator': '上一轮对话',\n 'round.status.running': '执行中',\n 'round.status.completed': '已完成',\n 'round.status.error': '执行失败',\n 'round.noMessage': '(无消息)',\n 'footer.attribution': '',\n 'selection.ask': '问一下',\n 'viewer.loading': '加载中...',\n 'viewer.error': '无法获取文件内容',\n 'viewer.back': '← 返回',\n 'viewer.defaultTitle': '文件预览',\n 'viewer.copyFull': '复制全文',\n 'viewer.copyFullTitle': '复制全文到剪贴板并引用',\n 'viewer.referenceFile': '引用此文件',\n 'viewer.referenceFileTitle': '引用此文件',\n 'viewer.referencePage': '引用当前页面',\n 'viewer.referencePageTitle': '引用当前页面到对话',\n 'viewer.download': '下载',\n 'viewer.fullscreen': '全屏 (⌘L)',\n 'viewer.fullscreenExit': '退出全屏',\n 'viewer.close': '关闭',\n 'viewer.unknownType': '未知类型',\n 'viewer.iframeHint': 'iframe 内容无法直接选中文本,请使用上方「引用此文件」按钮',\n 'viewer.copySnippet': '复制片段',\n 'viewer.loadingPdf': '加载 PDF 查看器...',\n 'viewer.pdfPages': '共 {{count}} 页',\n 'viewer.loadingKicad': '加载 KiCad 查看器...',\n 'viewer.loading3d': '加载 3D 查看器...',\n 'viewer.loadingStep': '加载 STEP 查看器...',\n 'viewer.gerberTitle': 'DFX Copilot — Gerber 预览',\n 'viewer.gerberBlobWarning':\n 'DFX Copilot 需要从公网可访问的地址拉取文件。当前为本地 blob/data URL,iframe 内无法使用。请在 Adapter 中返回 content_url,或实现 getResourceUrl 提供 HTTPS 预签名链接。',\n 'viewer.gerberNoHttpUrl':\n '当前资源地址不是 http(s),无法嵌入 DFX Copilot。请使用直链或预签名 URL。',\n 'viewer.pdfPreview': 'PDF 预览',\n 'viewer.htmlPreview': 'HTML 预览',\n 'viewer.htmlProjectLoading': '正在加载 HTML 项目文件…',\n 'viewer.htmlProjectNoEntry': 'HTML 项目缺少入口文件(如 index.html),无法预览',\n 'viewer.htmlProjectSizeLimit': 'HTML 项目超出大小限制,仅显示入口文件',\n 'viewer.htmlStrategyForcedInlineWarning': '检测到 ESM 模块,但已强制 inline 策略,可能加载失败',\n 'viewer.htmlStrategyFallbackCspWarning': '宿主 CSP 禁止 blob:,已自动降级到 inline 策略',\n 'viewer.copyFullKicadTitle': '复制全文 KiCad 原文到剪贴板并引用,粘贴到输入框即可带入',\n 'viewer.zoomIn': '放大',\n 'viewer.zoomOut': '缩小',\n 'viewer.zoomReset': '重置',\n 'viewer.loadingWord': '加载 Word 查看器...',\n 'viewer.loadingExcel': '加载 Excel 查看器...',\n 'viewer.loadingPowerPoint': '加载 PowerPoint 查看器...',\n 'viewer.pptPrev': '‹ 上一页',\n 'viewer.pptNext': '下一页 ›',\n 'viewer.pptSlide': '幻灯片',\n 'viewer.pptThumbnails': '缩略图',\n 'viewer.excelRows': '行',\n 'viewer.excelColumns': '列',\n 'childAgent.status.running': '执行中',\n 'childAgent.status.completed': '已完成',\n 'hitl.form.defaultTitle': '请填写表单',\n 'hitl.wait.default': '等待用户输入...',\n 'todo.completed.count': '已完成 {{completed}}/{{total}}',\n 'todo.blocked.count': '{{count}} 项阻塞',\n 'todo.more': '+ {{count}} 更多',\n 'todo.header.done': '已完成',\n 'tool.phase.generating': '生成中',\n 'tool.phase.executing': '执行中',\n 'tool.phase.complete': '完成',\n 'tool.phase.error': '失败',\n 'tool.executing': '执行工具: {{name}}',\n 'tool.mcp.running': '执行中',\n 'tool.mcp.success': '完成',\n 'tool.mcp.error': '失败',\n 'form.placeholder.select': '请选择',\n 'form.required.default': '此项为必填项',\n 'form.submit.submit': '提交',\n 'form.submit.submitting': '提交中...',\n 'form.requestId': '请求 ID: ',\n 'pinned.label': '置顶',\n 'plan.title': '执行计划',\n 'plan.step': '步骤 {{index}}',\n 'thinking.inProgress': '思考中...',\n 'thinking.completed': '思考完成',\n 'split.unreadCount': '{{count}} 条新消息',\n 'split.askQuestion': '提问 (⌘/)',\n 'split.exitFullscreen': '退出全屏 (Esc)',\n 'context.inputPlaceholder': '在这里提问…',\n 'context.inputPlaceholderWithFile': '关于 {{fileName}} 提问…',\n 'context.send': '发送',\n 'context.removeReference': '移除引用',\n 'split.home': '主对话',\n 'split.workspace': '工作空间',\n 'split.annotation': '批注',\n 'split.tabClose': '关闭标签页',\n 'split.tabNew': '新标签页',\n 'workspace.title': '工作空间',\n 'workspace.searchPlaceholder': '搜索文件…',\n 'workspace.empty': '暂无文件',\n 'workspace.downloadAll': '打包下载全部文件',\n 'workspace.recent': '最近修改',\n 'workspace.open': '打开',\n 'workspace.openInNewTab': '在新标签页打开',\n 'workspace.download': '下载',\n 'workspace.copyPath': '复制路径',\n 'workspace.expandAll': '展开全部',\n 'workspace.collapseAll': '折叠全部',\n 'annotation.title': '批注',\n 'annotation.empty': '暂无批注',\n 'annotation.fileLevelTitle': '文件对话',\n 'annotation.fileLevelPlaceholder': '关于此文件提问…',\n 'annotation.anchoredPlaceholder': '关于所选内容提问…',\n 'annotation.inlineInputPlaceholder': '就此处提问…',\n 'annotation.replyPlaceholder': '继续追问…',\n 'annotation.anchorLabel': '锚点: {{text}}',\n 'annotation.close': '关闭',\n 'annotation.fabLabel': '文件批注',\n 'annotation.fabHeader': '{{fileName}} · 文件对话',\n 'annotation.messageCount': '{{count}} 条消息',\n 'annotation.anchorInvalid': '锚点已失效',\n 'annotation.errorRetry': '发送失败,点击重试',\n 'annotation.queuedHint': '排队中,请稍候…',\n 'annotation.selectionLabel': '选中内容',\n 'agentControl.pause': '暂停',\n 'agentControl.resume': '继续',\n 'agentControl.stop': '停止',\n 'agentControl.paused': '已暂停',\n 'agentControl.groupTitle': '工作组',\n 'aria.fileNavigation': '文件导航',\n 'kicad.loadFailed': 'KiCanvas 加载失败,已切换至源码视图',\n 'kicad.urlNotReady': '资源 URL 未就绪,当前显示源码',\n 'kicad.loadingEngine': '加载 KiCanvas 可视化引擎...',\n 'kicad.sidebarTitle': 'KiCanvas 侧栏提供:属性、符号/封装列表、文档信息等',\n 'kicad.sidebarPcb': 'PCB:侧栏可查属性、封装列表',\n 'kicad.sidebarSch': 'SCH:侧栏可查符号/子图属性',\n 'kicad.sidebarGeneric': '侧栏查看属性',\n 'kicad.viewVisual': '可视化',\n 'kicad.viewSource': '源码',\n 'provenance.filter.type.agent': '智能体',\n 'provenance.filter.type.action': '工具',\n 'provenance.filter.type.file': '文件',\n 'provenance.filter.type.task': '任务',\n 'provenance.filter.type.reasoning': '推理',\n 'provenance.filter.depth': '深度:',\n 'provenance.toolbar.zoomToFit': '自适应',\n 'provenance.toolbar.resetCamera': '重置视角',\n 'provenance.toolbar.refresh': '刷新',\n 'provenance.legend.reasoning': '推理',\n 'provenance.legend.action': '工具',\n 'provenance.legend.file': '文件',\n 'provenance.legend.task': '任务',\n 'provenance.legend.references': '引用',\n 'provenance.legend.edges': '边: ',\n 'provenance.legend.depth': '深度: ',\n 'provenance.detail.title': '节点详情',\n 'provenance.detail.noSelection': '未选中节点',\n 'provenance.detail.label.name': '名称',\n 'provenance.detail.label.id': 'ID',\n 'provenance.detail.label.timestamp': '时间',\n 'provenance.detail.label.agentId': 'Agent ID',\n 'provenance.detail.label.instanceId': '实例 ID',\n 'provenance.detail.label.level': '层级',\n 'provenance.detail.label.status': '状态',\n 'provenance.detail.label.tool': '工具',\n 'provenance.detail.label.purpose': '目的',\n 'provenance.detail.label.duration': '耗时',\n 'provenance.detail.label.path': '路径',\n 'provenance.detail.label.operation': '操作',\n 'provenance.detail.label.taskId': '任务 ID',\n 'provenance.detail.label.description': '描述',\n 'provenance.detail.label.model': '模型',\n 'provenance.detail.label.tokenCount': 'Token 数',\n 'provenance.detail.label.reasoningPreview': '推理预览',\n 'provenance.detail.relatedEdges': '关联边 ({{count}})',\n 'provenance.page.noSessionHint': '请通过 URL 参数指定会话: ?session_id=NNN',\n 'provenance.page.loading': '加载推理图谱...',\n 'provenance.page.emptyGraph': '当前会话暂无图谱数据',\n 'provenance.drawer.emptyGraph': '暂无图谱数据',\n 'provenance.graph.edgeType.references': '引用',\n 'toolResult.label': '执行结果',\n 'toolResult.expandAll': '展开全部 ({{count}} 行)',\n 'toolResult.searchSummary': '搜索结果 · {{count}} 条',\n 'toolResult.scrapeSummary': '抓取结果 · {{title}}',\n 'toolResult.more': '+{{count}} more',\n 'plan.status.active': '执行中',\n 'pinned.noMessage': '(无消息内容)',\n 'viewer.fallback.unknownType': '未知类型',\n 'viewer.fallback.download': '下载文件',\n 'fileSize.B': '{{size}} B',\n 'fileSize.KB': '{{size}} KB',\n 'fileSize.MB': '{{size}} MB',\n 'thinking.title': '思考推理',\n 'thinking.step': '步骤 {{step}}',\n 'viewer.stepHint': '鼠标拖拽旋转,滚轮缩放,右键平移',\n 'viewer.threeHint': '鼠标拖拽旋转,滚轮缩放,右键平移',\n 'viewer.3d.wireframe': '线框模式',\n 'viewer.3d.resetView': '重置视角',\n 'reference.header': '[引用文件: {{fileName}}]',\n 'history.noMessage': '(历史消息)',\n 'agent.defaultName': '助手',\n 'error.unknown': '未知错误',\n 'locale': 'zh-CN',\n 'skill.inlineLabel': '先查看并使用{{name}}技能,去解决:',\n 'skill.empty': '暂无可用技能',\n 'skill.searchPlaceholder': '搜索技能...',\n 'skill.removeLabel': '移除技能',\n 'skill.loading': '加载中...',\n 'skill.loadError': '加载技能失败',\n 'skill.loadMore': '加载更多',\n 'skill.selectorLabel': '技能选择',\n 'pool.idle': '待命',\n 'pool.collaborating': '{{count}} 协作中',\n 'pool.awaiting': '{{count}} 等待人工',\n 'pool.title': '智能体池',\n 'pool.empty': '暂无活跃智能体',\n 'pool.state.running': '执行中',\n 'pool.state.paused': '等待人工',\n 'pool.state.completed': '已完成',\n 'pool.state.lost': '已失联',\n 'pool.state.unknown': '未知',\n 'input.placeholder': '输入消息,/ 选择技能',\n 'input.placeholderLoading': '等待回复中…',\n 'discussion.title': '讨论',\n 'discussion.empty': '暂无讨论',\n 'discussion.active': '进行中',\n 'discussion.resolved': '已结论',\n 'discussion.archived': '已归档',\n 'round.foreign.label': '来自其他窗口的对话',\n 'round.foreign.unread': '{{count}} 条新消息',\n 'round.foreign.expand': '点击展开',\n 'sidebar.mainChat': '主对话',\n 'sidebar.chat': '对话',\n 'sidebar.fileQA': '文件问答',\n 'sidebar.selectionQA': '选区问答',\n 'sessionList.title': '历史会话',\n 'sessionList.newSession': '+ 新会话',\n 'sessionList.logout': '退出',\n 'sessionList.loading': '加载中...',\n 'sessionList.empty': '暂无会话',\n 'sessionList.unsupported': '当前 adapter 未实现 listSessions',\n 'sessionList.untitled': '无标题',\n 'sessionList.deleteTitle': '删除会话',\n 'sessionList.deleteConfirm': '确定删除该会话?',\n 'sessionList.prevPage': '←',\n 'sessionList.nextPage': '→',\n 'sessionList.pageInfo': '第 {page} / {totalPages} 页',\n 'modelPicker.menu.head': '本次使用的模型',\n 'modelPicker.menu.aria': '选择本次使用的模型',\n 'modelPicker.auto.title': '默认(跟随 Agent)',\n 'modelPicker.auto.hint.knownChannel': '当前 Agent 默认:{{name}} · {{channel}}',\n 'modelPicker.auto.hint.knownBasename': '当前 Agent 默认:{{name}}',\n 'modelPicker.auto.hint.fallback': '使用 Agent 注册的默认模型,跨子 Agent 自动切换',\n 'modelPicker.row.hint.channelMulti': '{{available}}/{{total}} 个渠道可用',\n 'modelPicker.row.hint.channelSingle': '渠道:{{channel}}',\n 'modelPicker.row.hint.versionMulti': '{{count}} 个版本可用',\n 'modelPicker.fallback.placeholder': '默认模型',\n 'modelPicker.inert.title': '模型选择当前不可用',\n 'modelPicker.guestLocked.label': '默认模型 · 登录后可选',\n 'modelPicker.guestLocked.title': '登录后可在多个模型间切换;游客先用默认模型即可开干。',\n 'modelPicker.loadingList': '加载模型清单…',\n 'modelPicker.trigger.title.stale': '{{name}}(已不在清单中,发送时仍会尝试使用)',\n 'modelPicker.trigger.title.agentDefault.withChannel':\n '当前 Agent 默认:{{name}} · {{channel}}(发送时跟随 Agent)',\n 'modelPicker.trigger.title.agentDefault': '当前 Agent 默认:{{name}}(发送时跟随 Agent)',\n 'modelPicker.trigger.title.current': '当前模型:{{name}}',\n 'modelPicker.row.title.pickDefault': '选默认渠道({{hint}})',\n 'modelPicker.row.title.pick': '选用 {{name}}',\n 'modelPicker.chip.aria': '{{title}} 渠道',\n 'modelPicker.chip.title.available': '渠道 {{channel}} · 模型 {{name}}',\n 'modelPicker.chip.title.unavailable': '渠道 {{channel}} · 当前不可用',\n 'jr.confirmDialog.cancel': '取消',\n 'jr.confirmDialog.confirm': '确认',\n 'jr.confirmDialog.loading': '处理中',\n}\n\nexport const enUS: ChatWidgetMessages = {\n 'header.title': 'AI Assistant',\n 'header.icon': '',\n 'status.connecting': 'Connecting...',\n 'status.running': 'Running...',\n 'status.compressing': 'Compressing context...',\n 'status.error': 'Connection error',\n 'status.idle': 'Idle',\n 'empty.waiting': 'Waiting for conversation...',\n 'empty.icon': '',\n 'round.separator': 'Previous round',\n 'round.status.running': 'Running',\n 'round.status.completed': 'Completed',\n 'round.status.error': 'Failed',\n 'round.noMessage': '(no message)',\n 'footer.attribution': '',\n 'selection.ask': 'Ask',\n 'viewer.loading': 'Loading...',\n 'viewer.error': 'Failed to load file content',\n 'viewer.back': '← Back',\n 'viewer.defaultTitle': 'File Preview',\n 'viewer.copyFull': 'Copy full',\n 'viewer.copyFullTitle': 'Copy full content to clipboard',\n 'viewer.referenceFile': 'Reference file',\n 'viewer.referenceFileTitle': 'Reference this file',\n 'viewer.referencePage': 'Reference page',\n 'viewer.referencePageTitle': 'Reference this page in chat',\n 'viewer.download': 'Download',\n 'viewer.fullscreen': 'Fullscreen (⌘L)',\n 'viewer.fullscreenExit': 'Exit fullscreen',\n 'viewer.close': 'Close',\n 'viewer.unknownType': 'Unknown type',\n 'viewer.iframeHint': 'iframe content cannot be selected directly. Use the \"Reference file\" button above.',\n 'viewer.copySnippet': 'Copy snippet',\n 'viewer.loadingPdf': 'Loading PDF viewer...',\n 'viewer.pdfPages': '{{count}} pages',\n 'viewer.loadingKicad': 'Loading KiCad viewer...',\n 'viewer.loading3d': 'Loading 3D viewer...',\n 'viewer.loadingStep': 'Loading STEP viewer...',\n 'viewer.gerberTitle': 'DFX Copilot — Gerber preview',\n 'viewer.gerberBlobWarning':\n 'DFX Copilot must fetch the file from a public URL. Local blob/data URLs cannot be used inside a cross-origin iframe. Return content_url from getResourceContent or implement getResourceUrl with an HTTPS presigned link.',\n 'viewer.gerberNoHttpUrl':\n 'The resource URL is not http(s); it cannot be passed to DFX Copilot. Use a direct or presigned URL.',\n 'viewer.pdfPreview': 'PDF Preview',\n 'viewer.htmlPreview': 'HTML Preview',\n 'viewer.htmlProjectLoading': 'Loading HTML project files…',\n 'viewer.htmlProjectNoEntry': 'HTML project is missing an entry file (e.g. index.html); cannot render',\n 'viewer.htmlProjectSizeLimit': 'HTML project exceeds size limit; only the entry file is rendered',\n 'viewer.htmlStrategyForcedInlineWarning': 'ESM modules detected, but inline strategy is forced; imports may fail',\n 'viewer.htmlStrategyFallbackCspWarning': 'Host CSP blocks blob: URLs; automatically falling back to inline strategy',\n 'viewer.copyFullKicadTitle': 'Copy full KiCad source to clipboard and reference',\n 'viewer.zoomIn': 'Zoom in',\n 'viewer.zoomOut': 'Zoom out',\n 'viewer.zoomReset': 'Reset',\n 'viewer.loadingWord': 'Loading Word viewer...',\n 'viewer.loadingExcel': 'Loading Excel viewer...',\n 'viewer.loadingPowerPoint': 'Loading PowerPoint viewer...',\n 'viewer.pptPrev': '‹ Prev',\n 'viewer.pptNext': 'Next ›',\n 'viewer.pptSlide': 'Slide',\n 'viewer.pptThumbnails': 'Thumbnails',\n 'viewer.excelRows': 'rows',\n 'viewer.excelColumns': 'columns',\n 'childAgent.status.running': 'Running',\n 'childAgent.status.completed': 'Completed',\n 'hitl.form.defaultTitle': 'Please fill the form',\n 'hitl.wait.default': 'Waiting for user input...',\n 'todo.completed.count': '{{completed}}/{{total}} completed',\n 'todo.blocked.count': '{{count}} blocked',\n 'todo.more': '+ {{count}} more',\n 'todo.header.done': 'Done',\n 'tool.phase.generating': 'Generating',\n 'tool.phase.executing': 'Executing',\n 'tool.phase.complete': 'Complete',\n 'tool.phase.error': 'Failed',\n 'tool.executing': 'Execute tool: {{name}}',\n 'tool.mcp.running': 'Running',\n 'tool.mcp.success': 'Complete',\n 'tool.mcp.error': 'Failed',\n 'form.placeholder.select': 'Please select',\n 'form.required.default': 'This field is required',\n 'form.submit.submit': 'Submit',\n 'form.submit.submitting': 'Submitting...',\n 'form.requestId': 'Request ID: ',\n 'pinned.label': 'Pinned',\n 'plan.title': 'Execution Plan',\n 'plan.step': 'Step {{index}}',\n 'thinking.inProgress': 'Thinking...',\n 'thinking.completed': 'Thinking completed',\n 'split.unreadCount': '{{count}} new messages',\n 'split.askQuestion': 'Ask (⌘/)',\n 'split.exitFullscreen': 'Exit fullscreen (Esc)',\n 'context.inputPlaceholder': 'Ask here...',\n 'context.inputPlaceholderWithFile': 'Ask about {{fileName}}...',\n 'context.send': 'Send',\n 'context.removeReference': 'Remove reference',\n 'split.home': 'Main Chat',\n 'split.workspace': 'Workspace',\n 'split.annotation': 'Annotations',\n 'split.tabClose': 'Close tab',\n 'split.tabNew': 'New tab',\n 'workspace.title': 'Workspace',\n 'workspace.searchPlaceholder': 'Search files...',\n 'workspace.empty': 'No files yet',\n 'workspace.downloadAll': 'Download all files as zip',\n 'workspace.recent': 'Recent changes',\n 'workspace.open': 'Open',\n 'workspace.openInNewTab': 'Open in new tab',\n 'workspace.download': 'Download',\n 'workspace.copyPath': 'Copy path',\n 'workspace.expandAll': 'Expand all',\n 'workspace.collapseAll': 'Collapse all',\n 'annotation.title': 'Annotations',\n 'annotation.empty': 'No annotations',\n 'annotation.fileLevelTitle': 'File Conversation',\n 'annotation.fileLevelPlaceholder': 'Ask about this file...',\n 'annotation.anchoredPlaceholder': 'Ask about selection...',\n 'annotation.inlineInputPlaceholder': 'Ask about this...',\n 'annotation.replyPlaceholder': 'Follow up...',\n 'annotation.anchorLabel': 'Anchor: {{text}}',\n 'annotation.close': 'Close',\n 'annotation.fabLabel': 'File annotation',\n 'annotation.fabHeader': '{{fileName}} · File Conversation',\n 'annotation.messageCount': '{{count}} messages',\n 'annotation.anchorInvalid': 'Anchor invalidated',\n 'annotation.errorRetry': 'Send failed, click to retry',\n 'annotation.queuedHint': 'Queued, please wait...',\n 'annotation.selectionLabel': 'Selected text',\n 'agentControl.pause': 'Pause',\n 'agentControl.resume': 'Resume',\n 'agentControl.stop': 'Stop',\n 'agentControl.paused': 'Paused',\n 'agentControl.groupTitle': 'Agent Group',\n 'aria.fileNavigation': 'File navigation',\n 'kicad.loadFailed': 'KiCanvas load failed, switched to source view',\n 'kicad.urlNotReady': 'Resource URL not ready, showing source',\n 'kicad.loadingEngine': 'Loading KiCanvas engine...',\n 'kicad.sidebarTitle': 'KiCanvas sidebar: properties, symbol/footprint list, docs',\n 'kicad.sidebarPcb': 'PCB: view properties, footprint list',\n 'kicad.sidebarSch': 'SCH: view symbol/sub-sheet properties',\n 'kicad.sidebarGeneric': 'View properties',\n 'kicad.viewVisual': 'Visual',\n 'kicad.viewSource': 'Source',\n 'provenance.filter.type.agent': 'Agent',\n 'provenance.filter.type.action': 'Action',\n 'provenance.filter.type.file': 'File',\n 'provenance.filter.type.task': 'Task',\n 'provenance.filter.type.reasoning': 'Reasoning',\n 'provenance.filter.depth': 'Depth:',\n 'provenance.toolbar.zoomToFit': 'Zoom to fit',\n 'provenance.toolbar.resetCamera': 'Reset camera',\n 'provenance.toolbar.refresh': 'Refresh',\n 'provenance.legend.reasoning': 'Reasoning',\n 'provenance.legend.action': 'Action',\n 'provenance.legend.file': 'File',\n 'provenance.legend.task': 'Task',\n 'provenance.legend.references': 'References',\n 'provenance.legend.edges': 'Edges: ',\n 'provenance.legend.depth': 'Depth: ',\n 'provenance.detail.title': 'Node details',\n 'provenance.detail.noSelection': 'No node selected',\n 'provenance.detail.label.name': 'Name',\n 'provenance.detail.label.id': 'ID',\n 'provenance.detail.label.timestamp': 'Timestamp',\n 'provenance.detail.label.agentId': 'Agent ID',\n 'provenance.detail.label.instanceId': 'Instance ID',\n 'provenance.detail.label.level': 'Level',\n 'provenance.detail.label.status': 'Status',\n 'provenance.detail.label.tool': 'Tool',\n 'provenance.detail.label.purpose': 'Purpose',\n 'provenance.detail.label.duration': 'Duration',\n 'provenance.detail.label.path': 'Path',\n 'provenance.detail.label.operation': 'Operation',\n 'provenance.detail.label.taskId': 'Task ID',\n 'provenance.detail.label.description': 'Description',\n 'provenance.detail.label.model': 'Model',\n 'provenance.detail.label.tokenCount': 'Token count',\n 'provenance.detail.label.reasoningPreview': 'Reasoning preview',\n 'provenance.detail.relatedEdges': 'Related edges ({{count}})',\n 'provenance.page.noSessionHint': 'Please specify session via URL: ?session_id=NNN',\n 'provenance.page.loading': 'Loading provenance graph...',\n 'provenance.page.emptyGraph': 'No graph data for this session',\n 'provenance.drawer.emptyGraph': 'No graph data',\n 'provenance.graph.edgeType.references': 'References',\n 'toolResult.label': 'Result',\n 'toolResult.expandAll': 'Expand all ({{count}} lines)',\n 'toolResult.searchSummary': 'Search results · {{count}}',\n 'toolResult.scrapeSummary': 'Scrape result · {{title}}',\n 'toolResult.more': '+{{count}} more',\n 'plan.status.active': 'Running',\n 'pinned.noMessage': '(no message content)',\n 'viewer.fallback.unknownType': 'Unknown type',\n 'viewer.fallback.download': 'Download file',\n 'fileSize.B': '{{size}} B',\n 'fileSize.KB': '{{size}} KB',\n 'fileSize.MB': '{{size}} MB',\n 'thinking.title': 'Thinking',\n 'thinking.step': 'Step {{step}}',\n 'viewer.stepHint': 'Drag to rotate, scroll to zoom, right-click to pan',\n 'viewer.threeHint': 'Drag to rotate, scroll to zoom, right-click to pan',\n 'viewer.3d.wireframe': 'Wireframe',\n 'viewer.3d.resetView': 'Reset view',\n 'reference.header': '[Reference: {{fileName}}]',\n 'history.noMessage': '(history message)',\n 'agent.defaultName': 'Assistant',\n 'error.unknown': 'Unknown error',\n 'locale': 'en-US',\n 'skill.inlineLabel': 'First check and use the {{name}} skill to solve: ',\n 'skill.empty': 'No skills available',\n 'skill.searchPlaceholder': 'Search skills...',\n 'skill.removeLabel': 'Remove skill',\n 'skill.loading': 'Loading...',\n 'skill.loadError': 'Failed to load skills',\n 'skill.loadMore': 'Load more',\n 'skill.selectorLabel': 'Skill selector',\n 'pool.idle': 'Idle',\n 'pool.collaborating': '{{count}} working',\n 'pool.awaiting': '{{count}} awaiting human',\n 'pool.title': 'Agent Pool',\n 'pool.empty': 'No active agents',\n 'pool.state.running': 'Running',\n 'pool.state.paused': 'Awaiting human',\n 'pool.state.completed': 'Completed',\n 'pool.state.lost': 'Lost',\n 'pool.state.unknown': 'Unknown',\n 'input.placeholder': 'Type a message, / for skills',\n 'input.placeholderLoading': 'Waiting for response…',\n 'discussion.title': 'Discussions',\n 'discussion.empty': 'No discussions',\n 'discussion.active': 'Active',\n 'discussion.resolved': 'Resolved',\n 'discussion.archived': 'Archived',\n 'round.foreign.label': 'Conversation from another tab',\n 'round.foreign.unread': '{{count}} new messages',\n 'round.foreign.expand': 'Click to expand',\n 'sidebar.mainChat': 'Main chat',\n 'sidebar.chat': 'Chat',\n 'sidebar.fileQA': 'File Q&A',\n 'sidebar.selectionQA': 'Selection Q&A',\n 'sessionList.title': 'Sessions',\n 'sessionList.newSession': '+ New chat',\n 'sessionList.logout': 'Logout',\n 'sessionList.loading': 'Loading...',\n 'sessionList.empty': 'No sessions yet',\n 'sessionList.unsupported': 'Adapter does not implement listSessions',\n 'sessionList.untitled': 'Untitled',\n 'sessionList.deleteTitle': 'Delete session',\n 'sessionList.deleteConfirm': 'Delete this session?',\n 'sessionList.prevPage': '←',\n 'sessionList.nextPage': '→',\n 'sessionList.pageInfo': 'Page {page} / {totalPages}',\n 'modelPicker.menu.head': 'Model for this turn',\n 'modelPicker.menu.aria': 'Choose the model for this turn',\n 'modelPicker.auto.title': 'Default (follow agent)',\n 'modelPicker.auto.hint.knownChannel': 'Agent default: {{name}} · {{channel}}',\n 'modelPicker.auto.hint.knownBasename': 'Agent default: {{name}}',\n 'modelPicker.auto.hint.fallback':\n \"Use the agent's registered default model; sub-agents follow automatically\",\n 'modelPicker.row.hint.channelMulti': '{{available}} of {{total}} channels available',\n 'modelPicker.row.hint.channelSingle': 'Channel: {{channel}}',\n 'modelPicker.row.hint.versionMulti': '{{count}} versions available',\n 'modelPicker.fallback.placeholder': 'Default model',\n 'modelPicker.inert.title': 'Model picker is unavailable',\n 'modelPicker.guestLocked.label': 'Default model · sign in to choose',\n 'modelPicker.guestLocked.title':\n 'Signed-in users can switch among multiple models. As a guest you start with the default — sign in any time to swap.',\n 'modelPicker.loadingList': 'Loading model list…',\n 'modelPicker.trigger.title.stale':\n '{{name}} (no longer listed — will still be attempted on send)',\n 'modelPicker.trigger.title.agentDefault.withChannel':\n 'Agent default: {{name}} · {{channel}} (sent value follows the agent)',\n 'modelPicker.trigger.title.agentDefault':\n 'Agent default: {{name}} (sent value follows the agent)',\n 'modelPicker.trigger.title.current': 'Current model: {{name}}',\n 'modelPicker.row.title.pickDefault': 'Use default channel ({{hint}})',\n 'modelPicker.row.title.pick': 'Use {{name}}',\n 'modelPicker.chip.aria': '{{title}} channels',\n 'modelPicker.chip.title.available': 'Channel {{channel}} · model {{name}}',\n 'modelPicker.chip.title.unavailable': 'Channel {{channel}} · currently unavailable',\n 'jr.confirmDialog.cancel': 'Cancel',\n 'jr.confirmDialog.confirm': 'Confirm',\n 'jr.confirmDialog.loading': 'Processing',\n}\n\nexport type ChatWidgetLocale = 'zh-CN' | 'en-US'\n\nconst builtinMessages: Record<ChatWidgetLocale, ChatWidgetMessages> = {\n 'zh-CN': zhCN,\n 'en-US': enUS,\n}\n\nexport function resolveMessages(\n locale: ChatWidgetLocale = 'zh-CN',\n overrides?: Partial<ChatWidgetMessages>,\n): ChatWidgetMessages {\n const base = builtinMessages[locale] ?? zhCN\n if (!overrides) return base\n return { ...base, ...overrides }\n}\n\nexport function interpolate(\n template: string,\n params?: Record<string, string | number>,\n): string {\n if (!params) return template\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) =>\n String(params[key] ?? ''),\n )\n}\n","/**\n * JETP-025: NodeDetailPanel\n *\n * Drawer panel showing detailed information about a selected graph node.\n * Uses antd Drawer + Descriptions for consistent JetForge styling.\n */\n\nimport React, { useMemo } from 'react'\nimport { Drawer, Descriptions, Tag, Typography, Space, Badge } from 'antd'\nimport type { ProvenanceGraphSnapshot, NodeType, ProvenanceNode } from '../types'\nimport { NODE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\nimport type { ChatWidgetMessages } from '../../i18n'\n\nconst { Text, Paragraph } = Typography\n\ninterface NodeDetailPanelProps {\n open: boolean\n nodeId: string | null\n graph: ProvenanceGraphSnapshot\n onClose: () => void\n}\n\nconst TYPE_LABEL_KEYS: Record<NodeType, keyof ChatWidgetMessages> = {\n agent: 'provenance.filter.type.agent',\n action: 'provenance.filter.type.action',\n file: 'provenance.filter.type.file',\n task: 'provenance.filter.type.task',\n reasoning: 'provenance.filter.type.reasoning',\n}\n\nfunction findNode(graph: ProvenanceGraphSnapshot, nodeId: string): ProvenanceNode | null {\n const all = [\n ...graph.nodes.agents,\n ...graph.nodes.actions,\n ...graph.nodes.files,\n ...graph.nodes.tasks,\n ...graph.nodes.reasonings,\n ]\n return all.find((n) => n.id === nodeId) ?? null\n}\n\nfunction formatTimestamp(ts: number): string {\n return new Date(ts).toLocaleString('zh-CN')\n}\n\nfunction formatDuration(ms: number | null | undefined): string {\n if (ms == null) return '-'\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\nconst NodeDetailPanelInner: React.FC<NodeDetailPanelProps> = ({\n open,\n nodeId,\n graph,\n onClose,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const node = useMemo(() => (nodeId ? findNode(graph, nodeId) : null), [graph, nodeId])\n\n const relatedEdges = useMemo(() => {\n if (!nodeId) return []\n return graph.edges.filter((e) => e.source === nodeId || e.target === nodeId)\n }, [graph.edges, nodeId])\n\n if (!node) {\n return (\n <Drawer title={t('provenance.detail.title')} open={open} onClose={onClose} width={360}>\n <Text type=\"secondary\">{t('provenance.detail.noSelection')}</Text>\n </Drawer>\n )\n }\n\n return (\n <Drawer\n title={\n <Space>\n <Badge color={NODE_COLORS[node.type]} />\n <span>{t(TYPE_LABEL_KEYS[node.type])}</span>\n <Tag>{node.type}</Tag>\n </Space>\n }\n open={open}\n onClose={onClose}\n width={380}\n destroyOnHidden\n >\n <Descriptions column={1} size=\"small\" bordered>\n <Descriptions.Item label={t('provenance.detail.label.name')}>\n <Text strong>{node.label}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.id')}>\n <Text code copyable>{node.id}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.timestamp')}>{formatTimestamp(node.timestamp)}</Descriptions.Item>\n\n {node.type === 'agent' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.agentId')}>\n <Text code>{node.agent_id}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.instanceId')}>{node.agent_instance_id}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.level')}>{node.level}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag color={node.status === 'running' ? 'processing' : node.status === 'completed' ? 'success' : 'error'}>\n {node.status ?? 'unknown'}\n </Tag>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'action' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.tool')}>{node.tool_name}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.purpose')}>{node.task_purpose || '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag color={node.status === 'success' ? 'success' : node.status === 'error' ? 'error' : 'processing'}>\n {node.status}\n </Tag>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.duration')}>{formatDuration(node.duration_ms)}</Descriptions.Item>\n </>\n )}\n\n {node.type === 'file' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.path')}>\n <Text code>{node.git_path}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.operation')}>\n <Tag color={node.operation === 'create' ? 'green' : node.operation === 'delete' ? 'red' : 'blue'}>\n {node.operation}\n </Tag>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'task' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.taskId')}>{node.task_id}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag>{node.status}</Tag>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.description')}>\n <Paragraph ellipsis={{ rows: 3 }}>{node.description}</Paragraph>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'reasoning' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.model')}>{node.model || '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.tokenCount')}>{node.token_count ?? '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.duration')}>{formatDuration(node.duration_ms)}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.reasoningPreview')}>\n <Paragraph ellipsis={{ rows: 5 }}>{node.content_preview || '(empty)'}</Paragraph>\n </Descriptions.Item>\n </>\n )}\n </Descriptions>\n\n {relatedEdges.length > 0 && (\n <>\n <Text strong style={{ display: 'block', marginTop: 16, marginBottom: 8 }}>\n {t('provenance.detail.relatedEdges', { count: relatedEdges.length })}\n </Text>\n <Space orientation=\"vertical\" size={4} style={{ width: '100%' }}>\n {relatedEdges.slice(0, 20).map((e, i) => (\n <div key={i} style={{ fontSize: 12, color: '#666' }}>\n <Tag color=\"default\" style={{ fontSize: 11 }}>{e.type}</Tag>\n {e.source === nodeId ? `→ ${e.target}` : `← ${e.source}`}\n </div>\n ))}\n </Space>\n </>\n )}\n </Drawer>\n )\n}\n\nexport const NodeDetailPanel = React.memo(NodeDetailPanelInner)\n","import React from 'react'\nimport { I18nContext } from '../i18n'\nimport type { ChatWidgetMessages, ChatWidgetLocale } from '../i18n'\nimport { resolveMessages } from '../i18n'\n\ninterface ProvenanceI18nProviderProps {\n locale?: ChatWidgetLocale\n messages?: Partial<ChatWidgetMessages>\n children: React.ReactNode\n}\n\nexport const ProvenanceI18nProvider: React.FC<ProvenanceI18nProviderProps> = ({\n locale = 'zh-CN',\n messages: overrides,\n children,\n}) => {\n const resolved = React.useMemo(\n () => resolveMessages(locale, overrides),\n [locale, overrides],\n )\n\n return (\n <I18nContext.Provider value={resolved}>\n {children}\n </I18nContext.Provider>\n )\n}\n","/**\n * JETP-025: FilterBar\n *\n * Provides controls for filtering the provenance graph:\n * - Node type toggle (multi-select)\n * - Depth filter (N-hop from selected node)\n */\n\nimport React, { useCallback, useMemo } from 'react'\nimport { Checkbox, Slider, Space, Typography, Badge } from 'antd'\nimport type { NodeType } from '../types'\nimport { NODE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\n\nconst { Text } = Typography\n\ninterface FilterBarProps {\n visibleTypes: Set<NodeType>\n onVisibleTypesChange: (types: Set<NodeType>) => void\n depth: number\n onDepthChange: (depth: number) => void\n hasSelection: boolean\n}\n\nconst ALL_TYPES: NodeType[] = ['agent', 'action', 'file', 'task', 'reasoning']\n\nconst TYPE_LABEL_KEYS: Record<NodeType, 'provenance.filter.type.agent' | 'provenance.filter.type.action' | 'provenance.filter.type.file' | 'provenance.filter.type.task' | 'provenance.filter.type.reasoning'> = {\n agent: 'provenance.filter.type.agent',\n action: 'provenance.filter.type.action',\n file: 'provenance.filter.type.file',\n task: 'provenance.filter.type.task',\n reasoning: 'provenance.filter.type.reasoning',\n}\n\nconst FilterBarInner: React.FC<FilterBarProps> = ({\n visibleTypes,\n onVisibleTypesChange,\n depth,\n onDepthChange,\n hasSelection,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const typeOptions = useMemo(() => ALL_TYPES.map((tp) => ({\n label: (\n <Space size={4}>\n <Badge color={NODE_COLORS[tp]} />\n <span>{t(TYPE_LABEL_KEYS[tp])}</span>\n </Space>\n ),\n value: tp as string,\n })), [t])\n\n const handleTypeChange = useCallback(\n (values: string[]) => {\n onVisibleTypesChange(new Set(values as NodeType[]))\n },\n [onVisibleTypesChange],\n )\n\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n padding: '8px 16px',\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n borderBottom: '1px solid #eee',\n }}\n >\n <Checkbox.Group\n options={typeOptions}\n value={Array.from(visibleTypes)}\n onChange={handleTypeChange}\n />\n\n {hasSelection && (\n <Space size={8} style={{ marginLeft: 'auto' }}>\n <Text type=\"secondary\" style={{ fontSize: 12 }}>\n {t('provenance.filter.depth')}\n </Text>\n <Slider\n min={1}\n max={5}\n value={depth}\n onChange={onDepthChange}\n style={{ width: 100 }}\n tooltip={{ open: false }}\n />\n <Text style={{ fontSize: 12, minWidth: 20 }}>{depth}</Text>\n </Space>\n )}\n </div>\n )\n}\n\nexport const FilterBar = React.memo(FilterBarInner)\n","/**\n * JETP-025: GraphToolbar\n *\n * Floating toolbar with zoom-to-fit, reset camera, and refresh controls.\n */\n\nimport React from 'react'\nimport { Button, Space, Tooltip } from 'antd'\nimport {\n ExpandOutlined,\n ReloadOutlined,\n AimOutlined,\n} from '@ant-design/icons'\nimport { useChatWidgetI18n } from '../../i18n'\n\ninterface GraphToolbarProps {\n onZoomToFit: () => void\n onResetCamera: () => void\n onRefresh: () => void\n loading?: boolean\n}\n\nconst GraphToolbarInner: React.FC<GraphToolbarProps> = ({\n onZoomToFit,\n onResetCamera,\n onRefresh,\n loading,\n}) => {\n const { t } = useChatWidgetI18n()\n\n return (\n <div\n style={{\n position: 'absolute',\n right: 16,\n top: 16,\n zIndex: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n }}\n >\n <Space orientation=\"vertical\" size={4}>\n <Tooltip title={t('provenance.toolbar.zoomToFit')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<ExpandOutlined />}\n onClick={onZoomToFit}\n style={toolBtnStyle}\n />\n </Tooltip>\n <Tooltip title={t('provenance.toolbar.resetCamera')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<AimOutlined />}\n onClick={onResetCamera}\n style={toolBtnStyle}\n />\n </Tooltip>\n <Tooltip title={t('provenance.toolbar.refresh')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<ReloadOutlined />}\n onClick={onRefresh}\n loading={loading}\n style={toolBtnStyle}\n />\n </Tooltip>\n </Space>\n </div>\n )\n}\n\nconst toolBtnStyle: React.CSSProperties = {\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n boxShadow: '0 1px 4px rgba(0,0,0,0.08)',\n borderRadius: 8,\n width: 36,\n height: 36,\n}\n\nexport const GraphToolbar = React.memo(GraphToolbarInner)\n"],"mappings":"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","names":["import_react","import_antd","import_react","THREE","SpriteText","ForceGraph3D","React","import_react","import_react","import_jsx_runtime","React","import_react","import_antd","import_jsx_runtime","React","import_jsx_runtime","React","import_react","import_jsx_runtime","React","import_react","import_antd","import_jsx_runtime","Text","TYPE_LABEL_KEYS","React","import_react","import_antd","import_jsx_runtime","React"]}
1
+ {"version":3,"sources":["../../src/provenance/index.ts","../../src/provenance/ProvenanceGraphDrawerContent.tsx","../../src/provenance/hooks/useProvenanceGraph.ts","../../src/provenance/GraphBuilder.ts","../../src/provenance/api.ts","../../src/provenance/components/ProvenanceGraph3D.tsx","../../src/provenance/components/NodeMeshFactory.ts","../../src/provenance/constants.ts","../../src/provenance/components/GraphStatsLegend.tsx","../../src/i18n/context.ts","../../src/i18n/messages.ts","../../src/provenance/components/NodeDetailPanel.tsx","../../src/provenance/ProvenanceI18nProvider.tsx","../../src/provenance/components/FilterBar.tsx","../../src/provenance/components/GraphToolbar.tsx"],"sourcesContent":["export { default as ProvenanceGraphDrawerContent } from './ProvenanceGraphDrawerContent'\nexport { ProvenanceI18nProvider } from './ProvenanceI18nProvider'\nexport { useProvenanceGraph } from './hooks/useProvenanceGraph'\nexport { GraphBuilder } from './GraphBuilder'\nexport { fetchProvenanceGraph } from './api'\nexport { ProvenanceGraph3D } from './components/ProvenanceGraph3D'\nexport { NodeDetailPanel } from './components/NodeDetailPanel'\nexport { FilterBar } from './components/FilterBar'\nexport { GraphToolbar } from './components/GraphToolbar'\nexport { GraphStatsLegend } from './components/GraphStatsLegend'\nexport type { ProvenanceGraphFetcher, FetchGraphOptions } from './api'\nexport type { ProvenanceGraphSnapshot, ProvenanceNode, GraphEdge, NodeType, EdgeType, GraphSSEPayload, GraphFilter } from './types'\n","/**\n * JETP-025: ProvenanceGraphDrawerContent\n *\n * Lightweight wrapper for embedding the provenance graph inside an antd Drawer.\n * Reuses ProvenanceGraph3D + GraphStatsLegend + NodeDetailPanel.\n *\n * Supports real-time SSE updates via onProcessEventRef callback.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { Spin, Empty } from 'antd'\nimport { useProvenanceGraph } from './hooks/useProvenanceGraph'\nimport { ProvenanceGraph3D } from './components/ProvenanceGraph3D'\nimport { GraphStatsLegend } from './components/GraphStatsLegend'\nimport { NodeDetailPanel } from './components/NodeDetailPanel'\nimport type { NodeType, GraphSSEPayload } from './types'\nimport { useChatWidgetI18n } from '../i18n'\nimport './ProvenanceGraph.css'\n\ninterface ProvenanceGraphDrawerContentProps {\n sessionId: number\n onProcessEventRef?: React.MutableRefObject<((p: GraphSSEPayload) => void) | null>\n}\n\nfunction useContainerSize(ref: React.RefObject<HTMLDivElement | null>) {\n const [size, setSize] = React.useState({ width: 600, height: 500 })\n\n React.useEffect(() => {\n if (!ref.current) return\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n setSize({ width: Math.floor(width), height: Math.floor(height) })\n }\n })\n observer.observe(ref.current)\n return () => observer.disconnect()\n }, [ref])\n\n return size\n}\n\nconst ProvenanceGraphDrawerContent: React.FC<ProvenanceGraphDrawerContentProps> = ({\n sessionId,\n onProcessEventRef,\n}) => {\n const { t } = useChatWidgetI18n()\n const containerRef = useRef<HTMLDivElement>(null)\n const { width, height } = useContainerSize(containerRef)\n\n const { graph, loading, error, processEvent } = useProvenanceGraph({\n sessionId,\n enabled: true,\n })\n\n // Expose processEvent to parent via ref\n useEffect(() => {\n if (onProcessEventRef) {\n onProcessEventRef.current = processEvent\n }\n return () => {\n if (onProcessEventRef) {\n onProcessEventRef.current = null\n }\n }\n }, [onProcessEventRef, processEvent])\n\n const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null)\n const [detailOpen, setDetailOpen] = useState(false)\n\n const handleNodeClick = useCallback((nodeId: string, _nodeType: NodeType) => {\n setSelectedNodeId(nodeId)\n setDetailOpen(true)\n }, [])\n\n const handleBackgroundClick = useCallback(() => {\n setSelectedNodeId(null)\n setDetailOpen(false)\n }, [])\n\n return (\n <div\n ref={containerRef}\n style={{ width: '100%', height: '100%', minHeight: 400, position: 'relative' }}\n >\n {loading && !graph && (\n <div className=\"ycw-provenance-loading\">\n <Spin size=\"large\" />\n </div>\n )}\n\n {error && !graph && (\n <div className=\"ycw-provenance-empty\">\n <span style={{ color: '#ff4d4f' }}>{error.message}</span>\n </div>\n )}\n\n {graph && graph.node_count === 0 && !loading && (\n <Empty description={t('provenance.drawer.emptyGraph')} style={{ paddingTop: 80 }} />\n )}\n\n {graph && graph.node_count > 0 && (\n <>\n <ProvenanceGraph3D\n graph={graph}\n width={width}\n height={height}\n selectedNodeId={selectedNodeId}\n onNodeClick={handleNodeClick}\n onBackgroundClick={handleBackgroundClick}\n />\n <GraphStatsLegend stats={graph.stats} edgeCount={graph.edges.length} />\n </>\n )}\n\n {graph && (\n <NodeDetailPanel\n open={detailOpen}\n nodeId={selectedNodeId}\n graph={graph}\n onClose={() => {\n setDetailOpen(false)\n setSelectedNodeId(null)\n }}\n />\n )}\n </div>\n )\n}\n\nexport default ProvenanceGraphDrawerContent\n","/**\n * JETP-025: useProvenanceGraph Hook\n *\n * Manages the provenance graph lifecycle:\n * 1. Fetches initial snapshot via REST\n * 2. Accepts SSE events from parent to incrementally update\n * 3. Handles reconnection by fetching delta via since_turn_id\n * 4. Debounces re-renders for burst SSE events\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { GraphBuilder } from '../GraphBuilder'\nimport { fetchProvenanceGraph } from '../api'\nimport type { ProvenanceGraphFetcher } from '../api'\nimport type { ProvenanceGraphSnapshot, GraphSSEPayload } from '../types'\n\ninterface UseProvenanceGraphOptions {\n sessionId: number | null\n /** Adapter-supplied fetcher; when absent, fetch is disabled */\n fetcher?: ProvenanceGraphFetcher\n enabled?: boolean\n /** Auto-poll interval in ms. 0 disables. Default 3000. */\n pollInterval?: number\n}\n\ninterface UseProvenanceGraphReturn {\n graph: ProvenanceGraphSnapshot | null\n loading: boolean\n error: Error | null\n processEvent: (payload: GraphSSEPayload) => void\n refetch: () => void\n}\n\nconst EMPTY_SNAPSHOT: ProvenanceGraphSnapshot = {\n session_id: 0,\n generated_at: 0,\n node_count: 0,\n edge_count: 0,\n max_turn_id: null,\n nodes: { agents: [], actions: [], files: [], tasks: [], reasonings: [] },\n edges: [],\n stats: { agent_count: 0, action_count: 0, file_count: 0, task_count: 0, reasoning_count: 0, max_depth: 0 },\n}\n\nconst DEBOUNCE_MS = 80\n\nexport function useProvenanceGraph(\n opts: UseProvenanceGraphOptions,\n): UseProvenanceGraphReturn {\n const { sessionId, fetcher, enabled = true, pollInterval = 3000 } = opts\n const builderRef = useRef(new GraphBuilder())\n const maxTurnIdRef = useRef<number | null>(null)\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const mountedRef = useRef(true)\n\n const [graph, setGraph] = useState<ProvenanceGraphSnapshot | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const flushSnapshot = useCallback(() => {\n if (!mountedRef.current) return\n const snap = builderRef.current.getSnapshot()\n setGraph(snap)\n }, [])\n\n const scheduleFlush = useCallback(() => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n debounceTimerRef.current = setTimeout(flushSnapshot, DEBOUNCE_MS)\n }, [flushSnapshot])\n\n const fetchSnapshot = useCallback(\n async (sinceTurnId?: number | null) => {\n if (!sessionId || !fetcher) return\n setLoading(true)\n setError(null)\n try {\n const snap = await fetchProvenanceGraph(fetcher, {\n sessionId,\n sinceTurnId,\n })\n if (!mountedRef.current) return\n\n if (sinceTurnId != null && sinceTurnId > 0) {\n builderRef.current.mergeSnapshot(snap)\n } else {\n builderRef.current.replaceWithSnapshot(snap)\n }\n maxTurnIdRef.current = snap.max_turn_id\n flushSnapshot()\n } catch (e) {\n if (!mountedRef.current) return\n const err = e instanceof Error ? e : new Error(String(e))\n setError(err)\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n },\n [sessionId, fetcher, flushSnapshot],\n )\n\n const processEvent = useCallback(\n (payload: GraphSSEPayload) => {\n const handled = builderRef.current.applyEvent(payload)\n if (handled) scheduleFlush()\n },\n [scheduleFlush],\n )\n\n const refetch = useCallback(() => {\n fetchSnapshot(maxTurnIdRef.current)\n }, [fetchSnapshot])\n\n // Initial fetch when session changes\n useEffect(() => {\n mountedRef.current = true\n if (sessionId && enabled) {\n builderRef.current = new GraphBuilder()\n maxTurnIdRef.current = null\n fetchSnapshot(null)\n } else {\n setGraph(sessionId ? null : EMPTY_SNAPSHOT)\n }\n return () => {\n mountedRef.current = false\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n }\n }, [sessionId, enabled, fetchSnapshot])\n\n // Auto-poll for incremental updates (uses since_turn_id for efficiency)\n useEffect(() => {\n if (!sessionId || !enabled || pollInterval <= 0) return\n const id = setInterval(() => {\n if (!mountedRef.current) return\n fetchSnapshot(maxTurnIdRef.current)\n }, pollInterval)\n return () => clearInterval(id)\n }, [sessionId, enabled, pollInterval, fetchSnapshot])\n\n return { graph, loading, error, processEvent, refetch }\n}\n","/**\n * JETP-025: Client-side GraphBuilder\n *\n * Incrementally builds a provenance graph from SSE events.\n * Maintains Maps for O(1) node lookup and deduplication.\n *\n * Handlers: agent_start, agent_end, mcp_start, mcp_end,\n * artifact_result, plan_result, model_start, model_result, model_end\n */\n\nimport type {\n AgentNode,\n ActionNode,\n FileNode,\n TaskNode,\n ReasoningNode,\n GraphEdge,\n ProvenanceGraphSnapshot,\n GraphSSEPayload,\n EdgeType,\n} from './types'\n\ntype Handler = (p: GraphSSEPayload) => void\n\nexport class GraphBuilder {\n private sessionId = 0\n private agents = new Map<number, AgentNode>()\n private actions = new Map<string, ActionNode>()\n private files = new Map<string, FileNode>()\n private tasks = new Map<string, TaskNode>()\n private reasonings = new Map<string, ReasoningNode>()\n private edges: GraphEdge[] = []\n private edgeKeys = new Set<string>()\n private lastCompletedActions = new Map<number, string[]>()\n\n private readonly handlers: Record<string, Handler> = {\n agent_start: (p) => this.handleAgentStart(p),\n agent_end: (p) => this.handleAgentEnd(p),\n mcp_start: (p) => this.handleMcpStart(p),\n mcp_end: (p) => this.handleMcpEnd(p),\n artifact_result: (p) => this.handleArtifactResult(p),\n plan_result: (p) => this.handlePlanResult(p),\n model_start: (p) => this.handleModelStart(p),\n model_result: (p) => this.handleModelResult(p),\n model_end: (p) => this.handleModelEnd(p),\n }\n\n /** Apply an SSE event. Returns true if the event was handled. */\n applyEvent(payload: GraphSSEPayload): boolean {\n const type = payload.notification_type ?? ''\n const handler = this.handlers[type]\n if (!handler) return false\n handler(payload)\n return true\n }\n\n /** Replace all state from a backend snapshot (initial load). */\n replaceWithSnapshot(snapshot: ProvenanceGraphSnapshot): void {\n this.sessionId = snapshot.session_id\n this.agents.clear()\n this.actions.clear()\n this.files.clear()\n this.tasks.clear()\n this.reasonings.clear()\n this.edges = []\n this.edgeKeys.clear()\n\n for (const n of snapshot.nodes.agents) this.agents.set(n.agent_instance_id, { ...n })\n for (const n of snapshot.nodes.actions) this.actions.set(n.tool_call_id, { ...n })\n for (const n of snapshot.nodes.files) this.files.set(n.id, { ...n })\n for (const n of snapshot.nodes.tasks) this.tasks.set(n.id, { ...n })\n for (const n of snapshot.nodes.reasonings) this.reasonings.set(n.id, { ...n })\n for (const e of snapshot.edges) {\n const key = this.edgeKey(e.source, e.target, e.type, e.label)\n if (!this.edgeKeys.has(key)) {\n this.edgeKeys.add(key)\n this.edges.push({ ...e })\n }\n }\n }\n\n /** Merge an incremental snapshot (reconnection). */\n mergeSnapshot(snapshot: ProvenanceGraphSnapshot): void {\n for (const n of snapshot.nodes.agents) this.agents.set(n.agent_instance_id, { ...n })\n for (const n of snapshot.nodes.actions) this.actions.set(n.tool_call_id, { ...n })\n for (const n of snapshot.nodes.files) this.files.set(n.id, { ...n })\n for (const n of snapshot.nodes.tasks) this.tasks.set(n.id, { ...n })\n for (const n of snapshot.nodes.reasonings) this.reasonings.set(n.id, { ...n })\n for (const e of snapshot.edges) {\n const key = this.edgeKey(e.source, e.target, e.type, e.label)\n if (!this.edgeKeys.has(key)) {\n this.edgeKeys.add(key)\n this.edges.push({ ...e })\n }\n }\n }\n\n /** Produce an immutable snapshot for React state. */\n getSnapshot(): ProvenanceGraphSnapshot {\n const agents = Array.from(this.agents.values())\n const actions = Array.from(this.actions.values())\n const files = Array.from(this.files.values())\n const tasks = Array.from(this.tasks.values())\n const reasonings = Array.from(this.reasonings.values())\n const nodeCount =\n agents.length + actions.length + files.length + tasks.length + reasonings.length\n const maxDepth = agents.length > 0 ? Math.max(...agents.map((a) => a.level)) : 0\n\n return {\n session_id: this.sessionId,\n generated_at: Date.now(),\n node_count: nodeCount,\n edge_count: this.edges.length,\n max_turn_id: null,\n nodes: { agents, actions, files, tasks, reasonings },\n edges: [...this.edges],\n stats: {\n agent_count: agents.length,\n action_count: actions.length,\n file_count: files.length,\n task_count: tasks.length,\n reasoning_count: reasonings.length,\n max_depth: maxDepth,\n },\n }\n }\n\n // -----------------------------------------------------------------------\n // Handlers\n // -----------------------------------------------------------------------\n\n private handleAgentStart(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const caller = p.caller_instance_id ?? null\n const ts = this.parseTimestamp(p.timestamp)\n\n const node: AgentNode = {\n id: `agent-inst-${callee}`,\n type: 'agent',\n label: p.agent_name ?? p.agent_id ?? `agent-${callee}`,\n timestamp: ts,\n metadata: {},\n agent_id: p.agent_id ?? `agent-${callee}`,\n agent_instance_id: callee,\n agent_name: p.agent_name ?? `agent-${callee}`,\n level: p.level ?? 0,\n parent_agent_instance_id: caller != null && caller >= 0 ? caller : null,\n status: 'running',\n }\n this.agents.set(callee, node)\n\n if (caller != null && caller >= 0 && this.agents.has(caller)) {\n this.addEdge(`agent-inst-${caller}`, `agent-inst-${callee}`, 'spawns', ts)\n }\n }\n\n private handleAgentEnd(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id\n if (callee == null) return\n const existing = this.agents.get(callee)\n if (existing) {\n this.agents.set(callee, { ...existing, status: 'completed' })\n }\n }\n\n private handleMcpStart(p: GraphSSEPayload): void {\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id\n if (!tcid) return\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n\n const node: ActionNode = {\n id: `action-${tcid}`,\n type: 'action',\n label: this.extractString(p.ext, 'tool_name') ?? p.tool_name ?? tcid,\n timestamp: ts,\n metadata: {},\n tool_name: this.extractString(p.ext, 'tool_name') ?? p.tool_name ?? '',\n tool_call_id: tcid,\n task_purpose: this.extractString(p.ext, 'task_purpose') ?? p.task_purpose ?? '',\n agent_instance_id: callee,\n status: 'running',\n duration_ms: null,\n }\n this.actions.set(tcid, node)\n\n if (this.agents.has(callee)) {\n this.addEdge(`agent-inst-${callee}`, `action-${tcid}`, 'executes', ts)\n }\n\n // Derive triggers edge: most recent reasoning for this agent → this action\n const latestReasoning = this.findLatestReasoning(callee)\n if (latestReasoning) {\n this.addEdge(latestReasoning.id, `action-${tcid}`, 'triggers', ts)\n }\n\n // Retroactive: connect any files that arrived before this action was registered\n for (const [fid, fileNode] of this.files) {\n if (fileNode.tool_call_id === tcid) {\n const op = fileNode.operation\n const et: EdgeType =\n op === 'create' ? 'produces' : op === 'delete' ? 'deletes' : 'modifies'\n this.addEdge(`action-${tcid}`, fid, et, ts)\n }\n }\n }\n\n private handleMcpEnd(p: GraphSSEPayload): void {\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id\n if (!tcid) return\n const existing = this.actions.get(tcid)\n if (!existing) return\n\n const statusStr = this.extractString(p.ext, 'status') ?? p.tool_status ?? 'success'\n const status: 'success' | 'error' = statusStr === 'error' ? 'error' : 'success'\n const endTs = this.parseTimestamp(p.timestamp)\n const duration = endTs - existing.timestamp\n\n this.actions.set(tcid, { ...existing, status, duration_ms: duration > 0 ? duration : null })\n\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const prev = this.lastCompletedActions.get(callee) ?? []\n prev.push(tcid)\n this.lastCompletedActions.set(callee, prev)\n }\n\n private handleArtifactResult(p: GraphSSEPayload): void {\n // JETP-026: route xref_scan_result to dedicated handler\n if (p.ext?.xref_scan_result) {\n this.handleXrefScanResult(p)\n return\n }\n\n const data = this.extractArtifactData(p.content)\n if (!data) return\n\n const fileId = data.file_id ?? data.identifier ?? ''\n if (!fileId) return\n\n const fid = `file-${fileId}`\n const op = this.normalizeOperation(data.operation_type)\n const tcid = this.extractString(p.ext, 'tool_call_id') ?? p.tool_call_id ?? null\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n\n const existing = this.files.get(fid)\n const node: FileNode = {\n id: fid,\n type: 'file',\n label: data.file_name ?? data.git_path ?? fileId,\n timestamp: existing?.timestamp ?? ts,\n metadata: {},\n file_id: fileId,\n file_name: data.file_name ?? '',\n git_path: data.git_path ?? '',\n operation: op,\n agent_instance_id: callee,\n tool_call_id: tcid,\n task_purpose: this.extractString(p.ext, 'task_purpose') ?? p.task_purpose ?? null,\n }\n this.files.set(fid, node)\n\n // Absorb any placeholder nodes that match by file_name or git_path\n this.absorbPlaceholders(node)\n\n const edgeType: EdgeType =\n op === 'create' ? 'produces' : op === 'delete' ? 'deletes' : 'modifies'\n\n if (tcid && this.actions.has(tcid)) {\n this.addEdge(`action-${tcid}`, fid, edgeType, ts)\n } else if (this.reasonings.size > 0) {\n // Action not yet registered (out-of-order SSE). When mcp_start arrives\n // later, handleMcpStart will retroactively add the correct action→file\n // edge. For now, attach to the latest reasoning so the node isn't orphaned.\n let latest: ReasoningNode | null = null\n for (const r of this.reasonings.values()) {\n if (!latest || r.timestamp > latest.timestamp) latest = r\n }\n if (latest) {\n this.addEdge(latest.id, fid, edgeType, ts)\n }\n }\n }\n\n /** JETP-026: create references edges from xref scan result. */\n private handleXrefScanResult(p: GraphSSEPayload): void {\n const ext = p.ext\n if (!ext) return\n const sourceFileId = ext.source_file_id as string | undefined\n const xrefs = ext.xrefs as Array<Record<string, unknown>> | undefined\n if (!sourceFileId || !xrefs) return\n\n const ts = this.parseTimestamp(p.timestamp)\n const sourceNodeId = `file-${sourceFileId}`\n\n for (const xref of xrefs) {\n const targetFileId = xref.target_file_id as string | undefined\n const targetResource = (xref.target_resource as string) ?? ''\n\n let targetNodeId: string\n\n if (targetFileId) {\n targetNodeId = `file-${targetFileId}`\n if (!this.files.has(targetNodeId)) {\n const resolved = this.resolveFileByName(targetFileId)\n if (resolved) {\n targetNodeId = resolved\n } else {\n this.files.set(targetNodeId, {\n id: targetNodeId,\n type: 'file',\n label: targetFileId,\n timestamp: ts,\n metadata: { placeholder: true },\n file_id: targetFileId,\n file_name: '',\n git_path: '',\n operation: 'referenced',\n agent_instance_id: 0,\n tool_call_id: null,\n task_purpose: null,\n })\n }\n }\n } else {\n const hash = this.simpleHash(targetResource)\n targetNodeId = `file-ext-url-${hash}`\n if (!this.files.has(targetNodeId)) {\n const displayUrl = targetResource.replace('url://', '')\n this.files.set(targetNodeId, {\n id: targetNodeId,\n type: 'file',\n label: displayUrl.length > 50 ? displayUrl.slice(0, 47) + '...' : displayUrl,\n timestamp: ts,\n metadata: { external: true },\n file_id: `ext-url-${hash}`,\n file_name: displayUrl,\n git_path: targetResource,\n operation: 'external',\n agent_instance_id: 0,\n tool_call_id: null,\n task_purpose: null,\n })\n }\n }\n\n const description = (xref.description as string) ?? ''\n this.addEdge(sourceNodeId, targetNodeId, 'references', ts, description)\n }\n }\n\n private handlePlanResult(p: GraphSSEPayload): void {\n const checklist = this.extractChecklist(p.content)\n if (!checklist) return\n\n for (const task of checklist) {\n const tid = task.id ? `task-${task.id}` : `task-${task.description.slice(0, 20)}`\n const node: TaskNode = {\n id: tid,\n type: 'task',\n label: task.description,\n timestamp: Date.now(),\n metadata: {},\n task_id: task.id ?? tid,\n description: task.description,\n status: task.status ?? 'pending',\n }\n this.tasks.set(tid, node)\n }\n }\n\n private handleModelStart(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const ts = this.parseTimestamp(p.timestamp)\n const rid = `reasoning-${callee}-${ts}`\n\n const node: ReasoningNode = {\n id: rid,\n type: 'reasoning',\n label: this.extractString(p.ext, 'model') ?? 'reasoning',\n timestamp: ts,\n metadata: {},\n agent_instance_id: callee,\n model: this.extractString(p.ext, 'model') ?? '',\n content_preview: '',\n token_count: null,\n duration_ms: null,\n status: 'thinking',\n }\n this.reasonings.set(rid, node)\n\n if (this.agents.has(callee)) {\n this.addEdge(`agent-inst-${callee}`, rid, 'thinks', ts)\n }\n\n const prevActions = this.lastCompletedActions.get(callee) ?? []\n for (const tcid of prevActions) {\n this.addEdge(`action-${tcid}`, rid, 'informs', ts)\n }\n this.lastCompletedActions.delete(callee)\n }\n\n private handleModelResult(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const latest = this.findLatestReasoning(callee)\n if (!latest) return\n\n const preview = String(this.extractString(p.ext, 'content_preview') ?? '').slice(0, 200)\n this.reasonings.set(latest.id, {\n ...latest,\n status: 'completed',\n ...(preview ? { content_preview: preview } : {}),\n })\n }\n\n private handleModelEnd(p: GraphSSEPayload): void {\n const callee = p.callee_instance_id ?? p.agent_instance_id ?? 0\n const latest = this.findLatestReasoning(callee)\n if (!latest) return\n\n const endTs = this.parseTimestamp(p.timestamp)\n const duration = endTs - latest.timestamp\n const tokens = this.extractNumber(p.ext, 'total_tokens')\n\n this.reasonings.set(latest.id, {\n ...latest,\n status: 'completed',\n duration_ms: duration > 0 ? duration : null,\n token_count: tokens,\n })\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private addEdge(source: string, target: string, type: EdgeType, ts: number, label?: string): void {\n const key = this.edgeKey(source, target, type, label)\n if (this.edgeKeys.has(key)) return\n this.edgeKeys.add(key)\n this.edges.push({ source, target, type, label, timestamp: ts })\n }\n\n private edgeKey(source: string, target: string, type: string, label?: string): string {\n return label ? `${source}:${target}:${type}:${label}` : `${source}:${target}:${type}`\n }\n\n findLatestReasoning(agentInstanceId: number): ReasoningNode | null {\n let latest: ReasoningNode | null = null\n for (const r of this.reasonings.values()) {\n if (r.agent_instance_id === agentInstanceId) {\n if (!latest || r.timestamp > latest.timestamp) latest = r\n }\n }\n return latest\n }\n\n private parseTimestamp(ts: string | number | undefined): number {\n if (ts == null) return Date.now()\n if (typeof ts === 'number') return ts\n const n = Date.parse(ts)\n return Number.isNaN(n) ? Date.now() : n\n }\n\n private extractString(ext: Record<string, unknown> | undefined, key: string): string | null {\n if (!ext) return null\n const v = ext[key]\n return typeof v === 'string' ? v : null\n }\n\n private extractNumber(ext: Record<string, unknown> | undefined, key: string): number | null {\n if (!ext) return null\n const v = ext[key]\n return typeof v === 'number' ? v : null\n }\n\n private extractArtifactData(\n content: unknown[] | undefined,\n ): Record<string, string> | null {\n if (!content || !Array.isArray(content)) return null\n for (const part of content) {\n const c = (part as { content?: { data?: Record<string, string> } })?.content\n if (c?.data) return c.data\n }\n return null\n }\n\n private normalizeOperation(op: string | undefined): FileNode['operation'] {\n const o = (op ?? 'create').toLowerCase()\n if (o === 'create' || o === 'update' || o === 'delete' || o === 'external' || o === 'referenced') return o\n if (o.includes('create') || o.includes('add')) return 'create'\n if (o.includes('delete') || o.includes('remove')) return 'delete'\n return 'update'\n }\n\n /** Merge placeholder file nodes into a real node, remapping all edges.\n * Uses exact + stem matching (same ambiguity-safe logic as resolveFileByName). */\n private absorbPlaceholders(realNode: FileNode): void {\n const names = new Set<string>()\n if (realNode.file_name) {\n names.add(realNode.file_name)\n const fnStem = GraphBuilder.fileStem(realNode.file_name)\n if (fnStem !== realNode.file_name) names.add(fnStem)\n }\n if (realNode.git_path) {\n names.add(realNode.git_path)\n const gpStem = GraphBuilder.fileStem(realNode.git_path)\n if (gpStem !== realNode.git_path) names.add(gpStem)\n if (realNode.git_path.includes('/')) {\n const basename = realNode.git_path.split('/').pop()!\n names.add(basename)\n const bnStem = GraphBuilder.fileStem(basename)\n if (bnStem !== basename) names.add(bnStem)\n }\n }\n\n // Collect candidates; check for ambiguity per stem\n const stemHits = new Map<string, string[]>()\n for (const [id, node] of this.files) {\n if (id === realNode.id) continue\n if (!node.metadata?.placeholder) continue\n const matchKey = node.file_id || node.label\n if (names.has(matchKey)) {\n stemHits.set(id, [...(stemHits.get(id) ?? []), matchKey])\n }\n }\n\n const toRemove: string[] = []\n for (const [id] of stemHits) {\n for (const edge of this.edges) {\n if (edge.source === id) edge.source = realNode.id\n if (edge.target === id) edge.target = realNode.id\n }\n toRemove.push(id)\n }\n for (const id of toRemove) this.files.delete(id)\n }\n\n /** Match a file name/path against existing FileNodes by git_path or file_name.\n * Pass 1 — exact match. Pass 2 — stem match (extension stripped) when\n * *name* has no extension and exactly one non-placeholder candidate exists. */\n private resolveFileByName(name: string): string | null {\n for (const node of this.files.values()) {\n if (node.git_path === name || node.file_name === name) return node.id\n if (node.git_path && node.git_path.endsWith('/' + name)) return node.id\n }\n\n if (GraphBuilder.nameHasExtension(name)) return null\n\n const candidates: string[] = []\n for (const node of this.files.values()) {\n if (node.operation === 'referenced' || node.operation === 'external') continue\n if (node.file_name && GraphBuilder.fileStem(node.file_name) === name) {\n candidates.push(node.id)\n continue\n }\n if (node.git_path) {\n const gpStem = GraphBuilder.fileStem(node.git_path)\n if (gpStem === name || gpStem.endsWith('/' + name)) {\n candidates.push(node.id)\n continue\n }\n }\n }\n\n const unique = [...new Set(candidates)]\n return unique.length === 1 ? unique[0] : null\n }\n\n /** Strip trailing extension: 'arch.md' → 'arch', 'a/b.txt' → 'a/b'. */\n private static fileStem(name: string): string {\n const slash = name.lastIndexOf('/')\n const basename = name.slice(slash + 1)\n const dot = basename.lastIndexOf('.')\n if (dot > 0) return name.slice(0, slash + 1 + dot)\n return name\n }\n\n /** True when the trailing path component carries a dot-extension (ignores dotfiles). */\n private static nameHasExtension(name: string): boolean {\n const slash = name.lastIndexOf('/')\n const basename = name.slice(slash + 1)\n return basename.lastIndexOf('.') > 0\n }\n\n private simpleHash(s: string): string {\n let h = 0\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) - h + s.charCodeAt(i)) | 0\n }\n return Math.abs(h).toString(16).padStart(8, '0').slice(0, 8)\n }\n\n private extractChecklist(\n content: unknown[] | undefined,\n ): Array<{ id: string; description: string; status?: TaskNode['status'] }> | null {\n if (!content || !Array.isArray(content)) return null\n for (const part of content) {\n const typed = part as { type?: string; content?: { tasks?: unknown[] } }\n if (typed.type === 'checklist' && typed.content?.tasks) {\n return typed.content.tasks as Array<{\n id: string\n description: string\n status?: TaskNode['status']\n }>\n }\n }\n return null\n }\n}\n","/**\n * Provenance Graph API Client (SDK version)\n *\n * Delegates HTTP to the caller-supplied fetch function, decoupling from\n * any specific Axios instance or auth mechanism.\n */\n\nimport type { ProvenanceGraphSnapshot } from './types'\n\nexport interface FetchGraphOptions {\n sessionId: number\n sinceTurnId?: number | null\n limit?: number\n}\n\nexport type ProvenanceGraphFetcher = (\n sessionId: number,\n params?: { since_turn_id?: number; limit?: number },\n) => Promise<ProvenanceGraphSnapshot>\n\nexport async function fetchProvenanceGraph(\n fetcher: ProvenanceGraphFetcher,\n opts: FetchGraphOptions,\n): Promise<ProvenanceGraphSnapshot> {\n const params: { since_turn_id?: number; limit?: number } = {}\n if (opts.sinceTurnId != null && opts.sinceTurnId > 0) {\n params.since_turn_id = opts.sinceTurnId\n }\n if (opts.limit != null && opts.limit > 0) {\n params.limit = opts.limit\n }\n\n return fetcher(opts.sessionId, Object.keys(params).length > 0 ? params : undefined)\n}\n","/**\n * JETP-025: ProvenanceGraph3D\n *\n * Core 3D graph visualization using react-force-graph-3d (Three.js).\n * Renders agent/action/file/task/reasoning nodes as distinct 3D shapes\n * with animated edges, selection dimming, and camera focus.\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport ForceGraph3D from 'react-force-graph-3d'\nimport type { ForceGraphMethods } from 'react-force-graph-3d'\nimport * as THREE from 'three'\nimport SpriteText from 'three-spritetext'\nimport type { ProvenanceGraphSnapshot, ProvenanceNode, GraphEdge, NodeType } from '../types'\nimport { createNodeMesh, disposeGeometryCache } from './NodeMeshFactory'\nimport {\n NODE_COLORS,\n NODE_SIZES,\n EDGE_COLORS,\n EDGE_WIDTHS,\n SCENE_BG,\n LINK_PARTICLE_COUNT,\n LINK_PARTICLE_WIDTH,\n LINK_PARTICLE_SPEED,\n DIM_OPACITY,\n CAMERA_DISTANCE,\n CAMERA_FOCUS_DURATION_MS,\n LABEL_FONT_SIZE,\n LABEL_COLOR,\n} from '../constants'\n\n// ---------------------------------------------------------------------------\n// Internal node/link shapes for the force graph engine\n// ---------------------------------------------------------------------------\n\ninterface GraphNode3D {\n id: string\n type: NodeType\n label: string\n /** Second line: task_purpose (for action/file nodes) */\n subtitle?: string\n /** Content preview for reasoning cards */\n contentPreview?: string\n /** Agent name attribution for reasoning cards */\n agentLabel?: string\n status?: string\n level?: number\n agentInstanceId?: number\n x?: number\n y?: number\n z?: number\n}\n\ninterface GraphLink3D {\n source: string\n target: string\n type: string\n timestamp: number\n label?: string\n}\n\ninterface ProvenanceGraph3DProps {\n graph: ProvenanceGraphSnapshot\n width?: number\n height?: number\n selectedNodeId?: string | null\n onNodeClick?: (nodeId: string, nodeType: NodeType) => void\n onNodeHover?: (nodeId: string | null) => void\n onBackgroundClick?: () => void\n depthFilter?: number\n}\n\nconst HIDDEN_EDGE_TYPES = new Set(['spawns', 'executes', 'thinks'])\n\nfunction flattenNodes(snap: ProvenanceGraphSnapshot): ProvenanceNode[] {\n const { actions, files, tasks, reasonings } = snap.nodes\n return [...actions, ...files, ...tasks, ...reasonings]\n}\n\nfunction getConnectedIds(\n nodeId: string,\n edges: GraphEdge[],\n hops: number,\n): Set<string> {\n const visited = new Set<string>([nodeId])\n let frontier = new Set<string>([nodeId])\n\n for (let h = 0; h < hops; h++) {\n const next = new Set<string>()\n for (const e of edges) {\n if (frontier.has(e.source) && !visited.has(e.target)) {\n visited.add(e.target)\n next.add(e.target)\n }\n if (frontier.has(e.target) && !visited.has(e.source)) {\n visited.add(e.source)\n next.add(e.source)\n }\n }\n if (next.size === 0) break\n frontier = next\n }\n return visited\n}\n\nfunction truncate(s: string, maxLen: number): string {\n return s.length > maxLen ? s.slice(0, maxLen - 1) + '…' : s\n}\n\nfunction wrapText(s: string, lineWidth: number, maxLines: number): string {\n const clean = s.replace(/\\n/g, ' ').trim()\n const lines: string[] = []\n let pos = 0\n for (let i = 0; i < maxLines && pos < clean.length; i++) {\n const remaining = clean.slice(pos)\n if (remaining.length <= lineWidth) {\n lines.push(remaining)\n break\n }\n lines.push(remaining.slice(0, lineWidth))\n pos += lineWidth\n }\n const result = lines.join('\\n')\n return pos < clean.length ? result + '…' : result\n}\n\nconst ProvenanceGraph3DInner: React.FC<ProvenanceGraph3DProps> = ({\n graph,\n width,\n height,\n selectedNodeId = null,\n onNodeClick,\n onNodeHover,\n onBackgroundClick,\n depthFilter,\n}) => {\n const fgRef = useRef<ForceGraphMethods | undefined>(undefined)\n const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null)\n\n // Flatten snapshot into force-graph format (agents excluded)\n const graphData = useMemo(() => {\n const allNodes = flattenNodes(graph)\n const nodeMap = new Set(allNodes.map((n) => n.id))\n\n const purposeByNodeId = new Map<string, string>()\n for (const a of graph.nodes.actions) {\n if (a.task_purpose) purposeByNodeId.set(a.id, a.task_purpose)\n }\n for (const f of graph.nodes.files) {\n if (f.task_purpose) purposeByNodeId.set(f.id, f.task_purpose)\n }\n\n const previewById = new Map<string, string>()\n for (const r of graph.nodes.reasonings) {\n if (r.content_preview) previewById.set(r.id, r.content_preview)\n }\n\n const agentNameByInstId = new Map<number, string>()\n for (const a of graph.nodes.agents) {\n agentNameByInstId.set(a.agent_instance_id, a.agent_name || a.agent_id || `agent-${a.agent_instance_id}`)\n }\n\n const nodes: GraphNode3D[] = allNodes.map((n) => {\n const instId = 'agent_instance_id' in n\n ? (n as { agent_instance_id?: number }).agent_instance_id\n : undefined\n return {\n id: n.id,\n type: n.type,\n label: n.label,\n subtitle: purposeByNodeId.get(n.id),\n contentPreview: previewById.get(n.id),\n agentLabel: instId != null ? agentNameByInstId.get(instId) : undefined,\n status: 'status' in n ? (n as { status?: string }).status : undefined,\n level: 'level' in n ? (n as { level?: number }).level : undefined,\n agentInstanceId: instId,\n }\n })\n\n const links: GraphLink3D[] = graph.edges\n .filter((e) => !HIDDEN_EDGE_TYPES.has(e.type) && nodeMap.has(e.source) && nodeMap.has(e.target))\n .map((e) => {\n const purpose =\n purposeByNodeId.get(e.target) ?? purposeByNodeId.get(e.source) ?? undefined\n return {\n source: e.source,\n target: e.target,\n type: e.type,\n timestamp: e.timestamp,\n label: e.label || purpose,\n }\n })\n\n return { nodes, links }\n }, [graph])\n\n // Selection & dimming: compute visible set\n const connectedSet = useMemo(() => {\n if (!selectedNodeId) return null\n return getConnectedIds(selectedNodeId, graph.edges, depthFilter ?? 2)\n }, [selectedNodeId, graph.edges, depthFilter])\n\n // Node object factory\n const nodeThreeObject = useCallback(\n (node: GraphNode3D) => {\n const isDimmed = connectedSet != null && !connectedSet.has(node.id)\n const isSelected = node.id === selectedNodeId\n const isRunning = node.status === 'running' || node.status === 'thinking'\n\n const group = new THREE.Group()\n\n // Reasoning nodes → refined card with agent header + content body\n if (node.type === 'reasoning') {\n const agentName = node.agentLabel ?? 'Agent'\n const bodyText = node.contentPreview\n ? wrapText(node.contentPreview, 28, 2)\n : (isRunning ? 'Thinking…' : '')\n const dimAlpha = isDimmed ? 0.15 : 1\n\n // Agent name header\n const header = new SpriteText(\n (isRunning ? '● ' : '') + agentName,\n 2,\n isDimmed ? '#bbb' : (isRunning ? '#9b59b6' : '#667eea'),\n )\n header.fontFace = 'Inter, system-ui, sans-serif'\n header.fontWeight = '600'\n header.backgroundColor = 'transparent'\n header.padding = [0, 0]\n header.position.y = bodyText ? 4.5 : 0\n header.material.opacity = dimAlpha\n group.add(header)\n\n // Content body\n if (bodyText) {\n const body = new SpriteText(\n bodyText,\n 2.2,\n isDimmed ? '#ccc' : '#444',\n )\n body.fontFace = 'Inter, system-ui, sans-serif'\n body.backgroundColor = isDimmed\n ? 'rgba(245,245,245,0.2)'\n : isSelected\n ? 'rgba(102,126,234,0.08)'\n : 'rgba(255,255,255,0.92)'\n body.borderWidth = isSelected ? 1 : 0.4\n body.borderColor = isDimmed\n ? 'transparent'\n : isSelected ? 'rgba(102,126,234,0.5)' : 'rgba(0,0,0,0.08)'\n body.borderRadius = 3\n body.padding = [2.5, 4]\n body.material.opacity = dimAlpha\n group.add(body)\n }\n\n return group\n }\n\n const mesh = createNodeMesh(node.type, {\n selected: isSelected,\n dimmed: isDimmed,\n running: isRunning,\n })\n group.add(mesh)\n\n const nodeRadius = NODE_SIZES[node.type] ?? 5\n\n if (isRunning && !isDimmed) {\n const ringGeo = new THREE.RingGeometry(nodeRadius * 1.6, nodeRadius * 1.8, 32)\n const ringMat = new THREE.MeshBasicMaterial({\n color: NODE_COLORS[node.type as NodeType] ?? '#667eea',\n transparent: true,\n opacity: 0.4,\n side: THREE.DoubleSide,\n })\n const ring = new THREE.Mesh(ringGeo, ringMat)\n ring.rotation.x = Math.PI / 2\n ring.userData.__orbitRing = true\n group.add(ring)\n }\n\n if (!isDimmed) {\n const nameLabel = new SpriteText(\n truncate(node.label, 20),\n LABEL_FONT_SIZE,\n LABEL_COLOR,\n )\n nameLabel.backgroundColor = 'rgba(255,255,255,0.85)'\n nameLabel.borderRadius = 2\n nameLabel.padding = [1, 3]\n nameLabel.position.y = -(nodeRadius + 4)\n group.add(nameLabel)\n\n if (node.subtitle) {\n const purposeLabel = new SpriteText(\n truncate(node.subtitle, 16),\n 2.2,\n '#888',\n )\n purposeLabel.backgroundColor = 'rgba(245,247,250,0.9)'\n purposeLabel.borderRadius = 1.5\n purposeLabel.padding = [0.5, 2]\n purposeLabel.position.y = -(nodeRadius + 8)\n group.add(purposeLabel)\n }\n }\n\n return group\n },\n [connectedSet, selectedNodeId],\n )\n\n const CAUSAL_EDGES = new Set(['triggers', 'informs'])\n\n // Link color — invisible edge types get fully transparent color\n const linkColor = useCallback(\n (link: GraphLink3D) => {\n const edgeColor = EDGE_COLORS[link.type as keyof typeof EDGE_COLORS] ?? '#c0c0c0'\n if (connectedSet) {\n const srcId =\n typeof link.source === 'object' ? (link.source as GraphNode3D).id : link.source\n const tgtId =\n typeof link.target === 'object' ? (link.target as GraphNode3D).id : link.target\n if (!connectedSet.has(srcId) || !connectedSet.has(tgtId)) {\n return `rgba(200,200,200,${DIM_OPACITY})`\n }\n }\n return edgeColor\n },\n [connectedSet],\n )\n\n // Link width — invisible edges get zero width\n const linkWidth = useCallback(\n (link: GraphLink3D) => {\n const base = EDGE_WIDTHS[link.type as keyof typeof EDGE_WIDTHS] ?? 1.5\n return base * 1.2\n },\n [],\n )\n\n // Per-edge curvature: causal edges curve more to visually separate from structural edges\n const linkCurvature = useCallback(\n (link: GraphLink3D) => {\n if (link.type === 'references') return 0.35\n if (link.type === 'informs') return 0.3\n if (link.type === 'triggers') return 0.2\n return 0.06\n },\n [],\n )\n\n // Per-edge particle speed: causal edges have faster-moving particles\n const linkParticleSpeed = useCallback(\n (link: GraphLink3D) => {\n if (CAUSAL_EDGES.has(link.type)) return 0.008\n return LINK_PARTICLE_SPEED\n },\n [],\n )\n\n // Per-edge arrow length — invisible edges get no arrow\n const linkArrowLength = useCallback(\n (link: GraphLink3D) => {\n if (CAUSAL_EDGES.has(link.type)) return 7\n return 4\n },\n [],\n )\n\n // Particles on edges — none for invisible or reference edges\n const linkParticles = useCallback(\n (link: GraphLink3D) => {\n if (link.type === 'references') return 0\n if (connectedSet) {\n const srcId =\n typeof link.source === 'object' ? (link.source as GraphNode3D).id : link.source\n const tgtId =\n typeof link.target === 'object' ? (link.target as GraphNode3D).id : link.target\n if (!connectedSet.has(srcId) || !connectedSet.has(tgtId)) return 0\n }\n return LINK_PARTICLE_COUNT\n },\n [connectedSet],\n )\n\n // Configure forces — strong repulsion + typed link distances for readable spread\n useEffect(() => {\n if (!fgRef.current) return\n const fg = fgRef.current\n try {\n fg.d3Force('charge')?.strength(-420)\n fg.d3Force('link')?.distance((link: GraphLink3D) => {\n switch (link.type) {\n case 'references': return 160\n case 'informs': return 120\n case 'triggers': return 100\n case 'spawns': return 140\n default: return 80\n }\n })\n fg.d3Force('center')?.strength(0.04)\n } catch {\n // d3Force may not be ready yet\n }\n }, [graphData])\n\n // Camera focus on selection\n useEffect(() => {\n if (!selectedNodeId || !fgRef.current) return\n const node = graphData.nodes.find((n) => n.id === selectedNodeId)\n if (!node || node.x == null || node.y == null || node.z == null) return\n\n fgRef.current.cameraPosition(\n { x: node.x + CAMERA_DISTANCE * 0.3, y: node.y + CAMERA_DISTANCE * 0.2, z: node.z + CAMERA_DISTANCE * 0.5 },\n { x: node.x, y: node.y, z: node.z },\n CAMERA_FOCUS_DURATION_MS,\n )\n }, [selectedNodeId, graphData.nodes])\n\n // Setup scene lighting\n useEffect(() => {\n if (!fgRef.current) return\n try {\n const scene = fgRef.current.scene()\n if (!scene) return\n\n if (scene.userData.__lightsConfigured) return\n scene.userData.__lightsConfigured = true\n\n const ambient = new THREE.AmbientLight(0xffffff, 0.7)\n const directional = new THREE.DirectionalLight(0xffffff, 0.8)\n directional.position.set(100, 200, 150)\n scene.add(ambient, directional)\n\n scene.fog = new THREE.Fog(SCENE_BG, 600, 1600)\n } catch {\n // scene may not be ready\n }\n })\n\n // Animate orbit rings\n useEffect(() => {\n let frameId: number\n const animate = () => {\n if (!fgRef.current) return\n try {\n const scene = fgRef.current.scene()\n if (!scene) return\n scene.traverse((obj: THREE.Object3D) => {\n if (obj.userData.__orbitRing) {\n obj.rotation.z += 0.02\n }\n })\n } catch {\n // ignore\n }\n frameId = requestAnimationFrame(animate)\n }\n frameId = requestAnimationFrame(animate)\n return () => cancelAnimationFrame(frameId)\n }, [])\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n disposeGeometryCache()\n }\n }, [])\n\n const handleNodeClick = useCallback(\n (node: GraphNode3D) => {\n onNodeClick?.(node.id, node.type)\n },\n [onNodeClick],\n )\n\n const handleNodeHover = useCallback(\n (node: GraphNode3D | null) => {\n const id = node?.id ?? null\n setHoveredNodeId(id)\n onNodeHover?.(id)\n },\n [onNodeHover],\n )\n\n const handleBgClick = useCallback(() => {\n onBackgroundClick?.()\n }, [onBackgroundClick])\n\n // Edge hover tooltip — shows edge type + task_purpose\n const EDGE_TYPE_LABELS: Record<string, string> = {\n spawns: 'Spawns',\n executes: 'Executes',\n produces: 'Produces',\n modifies: 'Modifies',\n deletes: 'Deletes',\n thinks: 'Thinks',\n triggers: 'Triggers',\n informs: 'Informs',\n references: '引用', // JETP-026\n }\n\n const linkLabel = useCallback(\n (link: GraphLink3D) => {\n const typeLabel = EDGE_TYPE_LABELS[link.type] ?? link.type\n const color = EDGE_COLORS[link.type as keyof typeof EDGE_COLORS] ?? '#888'\n const lines = [\n `<span style=\"color:${color};font-weight:600\">${typeLabel}</span>`,\n ]\n if (link.label) lines.push(link.label)\n return `<div style=\"background:rgba(255,255,255,0.96);color:#444;padding:8px 12px;border-radius:6px;font-size:13px;line-height:1.6;box-shadow:0 2px 8px rgba(0,0,0,0.12);max-width:320px;word-break:break-all;border:1px solid #e8e8e8\">${lines.join('<br/>')}</div>`\n },\n [],\n )\n\n // Node hover tooltip\n const nodeLabel = useCallback(\n (node: GraphNode3D) => {\n if (hoveredNodeId !== node.id) return ''\n const lines: string[] = []\n if (node.type === 'reasoning') {\n lines.push(`<b>${node.agentLabel ?? 'Reasoning'}</b>`)\n if (node.status) lines.push(`Status: ${node.status}`)\n if (node.contentPreview) {\n const preview = node.contentPreview.length > 120\n ? node.contentPreview.slice(0, 120) + '…'\n : node.contentPreview\n lines.push(`<span style=\"color:#666\">${preview}</span>`)\n }\n } else {\n lines.push(`<b>${node.label}</b>`)\n if (node.subtitle) lines.push(`Purpose: ${node.subtitle}`)\n if (node.status) lines.push(`Status: ${node.status}`)\n }\n return `<div style=\"background:rgba(255,255,255,0.96);color:#333;padding:8px 12px;border-radius:6px;font-size:13px;line-height:1.6;box-shadow:0 2px 8px rgba(0,0,0,0.15);border:1px solid #e8e8e8;max-width:360px;word-break:break-all\">${lines.join('<br/>')}</div>`\n },\n [hoveredNodeId],\n )\n\n return (\n <ForceGraph3D\n ref={fgRef as React.MutableRefObject<ForceGraphMethods | undefined>}\n graphData={graphData}\n width={width}\n height={height}\n backgroundColor={`#${SCENE_BG.toString(16).padStart(6, '0')}`}\n showNavInfo={false}\n nodeThreeObject={nodeThreeObject as (node: object) => THREE.Object3D}\n nodeLabel={nodeLabel as (node: object) => string}\n linkLabel={linkLabel as (link: object) => string}\n linkColor={linkColor as (link: object) => string}\n linkWidth={linkWidth as (link: object) => number}\n linkOpacity={0.75}\n linkCurvature={linkCurvature as unknown as (link: object) => number}\n /* linkLineDash not in TS typings; inject at runtime if the version supports it */\n linkDirectionalParticles={linkParticles as (link: object) => number}\n linkDirectionalParticleWidth={LINK_PARTICLE_WIDTH}\n linkDirectionalParticleSpeed={linkParticleSpeed as unknown as (link: object) => number}\n linkDirectionalParticleColor={linkColor as (link: object) => string}\n linkDirectionalArrowLength={linkArrowLength as unknown as (link: object) => number}\n linkDirectionalArrowRelPos={0.92}\n linkDirectionalArrowColor={linkColor as (link: object) => string}\n d3AlphaDecay={0.04}\n d3VelocityDecay={0.4}\n warmupTicks={200}\n cooldownTicks={0}\n cooldownTime={3000}\n onNodeClick={handleNodeClick as (node: object, event: MouseEvent) => void}\n onNodeHover={handleNodeHover as (node: object | null, prev: object | null) => void}\n onBackgroundClick={handleBgClick}\n enableNodeDrag\n enableNavigationControls\n />\n )\n}\n\nexport const ProvenanceGraph3D = React.memo(ProvenanceGraph3DInner)\n","/**\n * JETP-025: NodeMeshFactory\n *\n * Creates distinctive Three.js meshes for each node type:\n * agent → Sphere (smooth, primary)\n * action → Icosahedron (faceted, dynamic)\n * file → Box (stable, structural)\n * task → Octahedron (angular, directional)\n * reasoning → Torus (continuous, cyclical thinking)\n *\n * Each mesh uses MeshStandardMaterial with emissive glow.\n * Reuses geometries via a cache for GPU efficiency.\n */\n\nimport * as THREE from 'three'\nimport type { NodeType } from '../types'\nimport {\n NODE_COLORS_HEX,\n NODE_EMISSIVE,\n NODE_SIZES,\n DIM_OPACITY,\n NORMAL_OPACITY,\n SELECTED_SCALE,\n} from '../constants'\n\nconst geoCache = new Map<string, THREE.BufferGeometry>()\n\nfunction getOrCreateGeometry(type: NodeType): THREE.BufferGeometry {\n const cached = geoCache.get(type)\n if (cached) return cached\n\n let geo: THREE.BufferGeometry\n const s = NODE_SIZES[type]\n\n switch (type) {\n case 'agent':\n geo = new THREE.SphereGeometry(s, 24, 16)\n break\n case 'action':\n geo = new THREE.IcosahedronGeometry(s, 0)\n break\n case 'file':\n geo = new THREE.BoxGeometry(s * 1.2, s * 1.2, s * 1.2)\n break\n case 'task':\n geo = new THREE.OctahedronGeometry(s, 0)\n break\n case 'reasoning':\n geo = new THREE.TorusGeometry(s * 0.7, s * 0.3, 12, 24)\n break\n default:\n geo = new THREE.SphereGeometry(s, 16, 12)\n }\n\n geoCache.set(type, geo)\n return geo\n}\n\nexport interface NodeMeshOptions {\n selected?: boolean\n dimmed?: boolean\n running?: boolean\n}\n\nexport function createNodeMesh(type: NodeType, opts: NodeMeshOptions = {}): THREE.Mesh {\n const geo = getOrCreateGeometry(type)\n const mat = new THREE.MeshStandardMaterial({\n color: NODE_COLORS_HEX[type],\n emissive: NODE_EMISSIVE[type],\n emissiveIntensity: opts.selected ? 0.6 : 0.25,\n metalness: 0.15,\n roughness: 0.55,\n transparent: true,\n opacity: opts.dimmed ? DIM_OPACITY : NORMAL_OPACITY,\n })\n\n const mesh = new THREE.Mesh(geo, mat)\n\n if (opts.selected) {\n mesh.scale.setScalar(SELECTED_SCALE)\n }\n\n mesh.castShadow = false\n mesh.receiveShadow = false\n\n return mesh\n}\n\n/** Apply selection/dimming state to an existing mesh */\nexport function updateMeshState(\n mesh: THREE.Mesh,\n _type: NodeType,\n opts: NodeMeshOptions,\n): void {\n const mat = mesh.material as THREE.MeshStandardMaterial\n mat.opacity = opts.dimmed ? DIM_OPACITY : NORMAL_OPACITY\n mat.emissiveIntensity = opts.selected ? 0.6 : 0.25\n mesh.scale.setScalar(opts.selected ? SELECTED_SCALE : 1)\n}\n\n/** Cleanup cached geometries (call on unmount) */\nexport function disposeGeometryCache(): void {\n for (const geo of geoCache.values()) {\n geo.dispose()\n }\n geoCache.clear()\n}\n","/**\n * JETP-025: Provenance Graph Visual Constants\n *\n * JetForge light-theme palette adapted for 3D graph rendering.\n * Primary: #667eea Background: #f5f7fa\n */\n\nimport type { NodeType, EdgeType } from './types'\n\n// ---------------------------------------------------------------------------\n// Node colors — vibrant against light scene background\n// ---------------------------------------------------------------------------\n\nexport const NODE_COLORS: Record<NodeType, string> = {\n agent: '#667eea',\n action: '#f5a623',\n file: '#50c878',\n task: '#e74c8b',\n reasoning: '#9b59b6',\n}\n\nexport const NODE_COLORS_HEX: Record<NodeType, number> = {\n agent: 0x667eea,\n action: 0xf5a623,\n file: 0x50c878,\n task: 0xe74c8b,\n reasoning: 0x9b59b6,\n}\n\nexport const NODE_EMISSIVE: Record<NodeType, number> = {\n agent: 0x3350c0,\n action: 0xc07a10,\n file: 0x2a8a48,\n task: 0xb83070,\n reasoning: 0x6e3a8a,\n}\n\n// ---------------------------------------------------------------------------\n// Node sizes (Three.js units)\n// ---------------------------------------------------------------------------\n\nexport const NODE_SIZES: Record<NodeType, number> = {\n agent: 6,\n action: 4.5,\n file: 3.5,\n task: 4,\n reasoning: 5,\n}\n\n// ---------------------------------------------------------------------------\n// Edge colors\n// ---------------------------------------------------------------------------\n\nexport const EDGE_COLORS: Record<EdgeType, string> = {\n spawns: '#667eea',\n executes: '#f5a623',\n produces: '#50c878',\n modifies: '#36a3d9',\n deletes: '#e74c3c',\n thinks: '#9b59b6',\n triggers: '#e67e22',\n informs: '#3498db',\n references: '#8e44ad', // JETP-026: purple for cross-references\n}\n\nexport const EDGE_WIDTHS: Record<EdgeType, number> = {\n spawns: 3,\n executes: 2,\n produces: 1.8,\n modifies: 1.8,\n deletes: 1.5,\n thinks: 2.5,\n triggers: 2,\n informs: 1.8,\n references: 1.0, // JETP-026: thin for cross-references\n}\n\n// ---------------------------------------------------------------------------\n// Scene / camera\n// ---------------------------------------------------------------------------\n\nexport const SCENE_BG = 0xf5f7fa\nexport const SCENE_FOG_COLOR = 0xf5f7fa\nexport const SCENE_FOG_NEAR = 800\nexport const SCENE_FOG_FAR = 2400\n\nexport const CAMERA_DISTANCE = 400\nexport const CAMERA_FOCUS_DURATION_MS = 600\n\n// ---------------------------------------------------------------------------\n// Link particle\n// ---------------------------------------------------------------------------\n\nexport const LINK_PARTICLE_COUNT = 2\nexport const LINK_PARTICLE_WIDTH = 3\nexport const LINK_PARTICLE_SPEED = 0.004\n\n// ---------------------------------------------------------------------------\n// Layout\n// ---------------------------------------------------------------------------\n\nexport const FORCE_LINK_DISTANCE = 80\nexport const FORCE_CHARGE = -420\nexport const FORCE_CENTER_STRENGTH = 0.04\n\n// ---------------------------------------------------------------------------\n// Selection & Dimming\n// ---------------------------------------------------------------------------\n\nexport const DIM_OPACITY = 0.08\nexport const SELECTED_SCALE = 1.4\nexport const NORMAL_OPACITY = 0.9\n\n// ---------------------------------------------------------------------------\n// Labels\n// ---------------------------------------------------------------------------\n\nexport const LABEL_FONT_SIZE = 3\nexport const LABEL_COLOR = '#333'\nexport const LABEL_BG_COLOR = 'rgba(255,255,255,0.85)'\n","/**\n * JETP-025: GraphStatsLegend\n *\n * Floating legend showing node counts by type and edge total.\n */\n\nimport React, { useMemo } from 'react'\nimport { Badge, Space } from 'antd'\nimport type { GraphStats, NodeType } from '../types'\nimport { NODE_COLORS, EDGE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\n\ninterface GraphStatsLegendProps {\n stats: GraphStats\n edgeCount: number\n}\n\nconst LEGEND_LABEL_KEYS: Record<string, 'provenance.legend.reasoning' | 'provenance.legend.action' | 'provenance.legend.file' | 'provenance.legend.task'> = {\n reasoning: 'provenance.legend.reasoning',\n action: 'provenance.legend.action',\n file: 'provenance.legend.file',\n task: 'provenance.legend.task',\n}\n\nconst LEGEND_TYPES: NodeType[] = ['reasoning', 'action', 'file', 'task']\n\nconst statKey = (type: NodeType): keyof GraphStats => {\n const map: Record<NodeType, keyof GraphStats> = {\n agent: 'agent_count',\n action: 'action_count',\n file: 'file_count',\n task: 'task_count',\n reasoning: 'reasoning_count',\n }\n return map[type]\n}\n\nconst GraphStatsLegendInner: React.FC<GraphStatsLegendProps> = ({\n stats,\n edgeCount,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const legendItems = useMemo(() =>\n LEGEND_TYPES.map((type) => ({ type, label: t(LEGEND_LABEL_KEYS[type]) })),\n [t],\n )\n\n return (\n <div\n style={{\n position: 'absolute',\n left: 16,\n bottom: 16,\n zIndex: 10,\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n padding: '10px 14px',\n borderRadius: 10,\n boxShadow: '0 1px 6px rgba(0,0,0,0.08)',\n fontSize: 12,\n lineHeight: 1.8,\n }}\n >\n <Space orientation=\"vertical\" size={2}>\n {legendItems.map(({ type, label }) => {\n const count = stats[statKey(type)] as number\n if (count === 0) return null\n return (\n <div key={type} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Badge color={NODE_COLORS[type]} />\n <span style={{ color: '#555' }}>{label}</span>\n <span style={{ fontWeight: 600, color: '#333' }}>{count}</span>\n </div>\n )\n })}\n {/* JETP-026: references edge legend */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <div\n style={{\n width: 14,\n height: 0,\n borderTop: `2px dashed ${EDGE_COLORS.references}`,\n }}\n />\n <span style={{ color: '#555' }}>{t('provenance.legend.references')}</span>\n </div>\n <div style={{ borderTop: '1px solid #eee', paddingTop: 4, marginTop: 2 }}>\n <span style={{ color: '#999' }}>{t('provenance.legend.edges')}</span>\n <span style={{ fontWeight: 600, color: '#333' }}>{edgeCount}</span>\n <span style={{ color: '#999', marginLeft: 8 }}>\n {t('provenance.legend.depth')}{stats.max_depth}\n </span>\n </div>\n </Space>\n </div>\n )\n}\n\nexport const GraphStatsLegend = React.memo(GraphStatsLegendInner)\n","import { createContext, useContext, useCallback } from 'react'\nimport type { ChatWidgetMessages, ChatWidgetLocale } from './messages.js'\nimport { zhCN, interpolate } from './messages.js'\n\nexport const I18nContext = createContext<ChatWidgetMessages>(zhCN)\n\nexport function useChatWidgetI18n() {\n const messages = useContext(I18nContext)\n\n const locale: ChatWidgetLocale = (messages['locale'] as ChatWidgetLocale) || 'zh-CN'\n\n const t = useCallback(\n (key: keyof ChatWidgetMessages, params?: Record<string, string | number>): string => {\n const template = messages[key] ?? key\n return interpolate(template, params)\n },\n [messages],\n )\n\n return { messages, t, locale }\n}\n","export interface ChatWidgetMessages {\n 'header.title': string\n 'header.icon': string\n 'status.connecting': string\n 'status.running': string\n 'status.compressing': string\n 'status.error': string\n 'status.idle': string\n 'empty.waiting': string\n 'empty.icon': string\n 'round.separator': string\n 'round.status.running': string\n 'round.status.completed': string\n 'round.status.error': string\n 'round.noMessage': string\n 'footer.attribution': string\n 'selection.ask': string\n 'viewer.loading': string\n 'viewer.error': string\n 'viewer.back': string\n 'viewer.defaultTitle': string\n 'viewer.copyFull': string\n 'viewer.copyFullTitle': string\n 'viewer.referenceFile': string\n 'viewer.referenceFileTitle': string\n 'viewer.referencePage': string\n 'viewer.referencePageTitle': string\n 'viewer.download': string\n 'viewer.fullscreen': string\n 'viewer.fullscreenExit': string\n 'viewer.close': string\n 'viewer.unknownType': string\n 'viewer.iframeHint': string\n 'viewer.copySnippet': string\n 'viewer.loadingPdf': string\n 'viewer.pdfPages': string\n 'viewer.loadingKicad': string\n 'viewer.loading3d': string\n 'viewer.loadingStep': string\n 'viewer.3d.wireframe': string\n 'viewer.3d.resetView': string\n 'viewer.gerberTitle': string\n 'viewer.gerberBlobWarning': string\n 'viewer.gerberNoHttpUrl': string\n 'viewer.pdfPreview': string\n 'viewer.htmlPreview': string\n 'viewer.htmlProjectLoading': string\n 'viewer.htmlProjectNoEntry': string\n 'viewer.htmlProjectSizeLimit': string\n 'viewer.htmlStrategyForcedInlineWarning': string\n 'viewer.htmlStrategyFallbackCspWarning': string\n 'viewer.copyFullKicadTitle': string\n 'viewer.zoomIn': string\n 'viewer.zoomOut': string\n 'viewer.zoomReset': string\n 'viewer.loadingWord': string\n 'viewer.loadingExcel': string\n 'viewer.loadingPowerPoint': string\n 'viewer.pptPrev': string\n 'viewer.pptNext': string\n 'viewer.pptSlide': string\n 'viewer.pptThumbnails': string\n 'viewer.excelRows': string\n 'viewer.excelColumns': string\n 'childAgent.status.running': string\n 'childAgent.status.completed': string\n 'hitl.form.defaultTitle': string\n 'hitl.wait.default': string\n 'todo.completed.count': string\n 'todo.blocked.count': string\n 'todo.more': string\n 'todo.header.done': string\n 'tool.phase.generating': string\n 'tool.phase.executing': string\n 'tool.phase.complete': string\n 'tool.phase.error': string\n 'tool.executing': string\n 'tool.mcp.running': string\n 'tool.mcp.success': string\n 'tool.mcp.error': string\n 'form.placeholder.select': string\n 'form.required.default': string\n 'form.submit.submit': string\n 'form.submit.submitting': string\n 'form.requestId': string\n 'pinned.label': string\n 'plan.title': string\n 'plan.step': string\n 'thinking.inProgress': string\n 'thinking.completed': string\n 'split.unreadCount': string\n 'split.askQuestion': string\n 'split.exitFullscreen': string\n 'context.inputPlaceholder': string\n 'context.inputPlaceholderWithFile': string\n 'context.send': string\n 'context.removeReference': string\n 'split.home': string\n 'split.workspace': string\n 'split.annotation': string\n 'split.tabClose': string\n 'split.tabNew': string\n 'workspace.title': string\n 'workspace.searchPlaceholder': string\n 'workspace.empty': string\n 'workspace.downloadAll': string\n 'workspace.recent': string\n 'workspace.open': string\n 'workspace.openInNewTab': string\n 'workspace.download': string\n 'workspace.copyPath': string\n 'workspace.expandAll': string\n 'workspace.collapseAll': string\n 'annotation.title': string\n 'annotation.empty': string\n 'annotation.fileLevelTitle': string\n 'annotation.fileLevelPlaceholder': string\n 'annotation.anchoredPlaceholder': string\n 'annotation.inlineInputPlaceholder': string\n 'annotation.replyPlaceholder': string\n 'annotation.anchorLabel': string\n 'annotation.close': string\n 'annotation.fabLabel': string\n 'annotation.fabHeader': string\n 'annotation.messageCount': string\n 'annotation.anchorInvalid': string\n 'annotation.errorRetry': string\n 'annotation.queuedHint': string\n 'annotation.selectionLabel': string\n 'agentControl.pause': string\n 'agentControl.resume': string\n 'agentControl.stop': string\n 'agentControl.paused': string\n 'agentControl.groupTitle': string\n 'aria.fileNavigation': string\n 'kicad.loadFailed': string\n 'kicad.urlNotReady': string\n 'kicad.loadingEngine': string\n 'kicad.sidebarTitle': string\n 'kicad.sidebarPcb': string\n 'kicad.sidebarSch': string\n 'kicad.sidebarGeneric': string\n 'kicad.viewVisual': string\n 'kicad.viewSource': string\n 'provenance.filter.type.agent': string\n 'provenance.filter.type.action': string\n 'provenance.filter.type.file': string\n 'provenance.filter.type.task': string\n 'provenance.filter.type.reasoning': string\n 'provenance.filter.depth': string\n 'provenance.toolbar.zoomToFit': string\n 'provenance.toolbar.resetCamera': string\n 'provenance.toolbar.refresh': string\n 'provenance.legend.reasoning': string\n 'provenance.legend.action': string\n 'provenance.legend.file': string\n 'provenance.legend.task': string\n 'provenance.legend.references': string\n 'provenance.legend.edges': string\n 'provenance.legend.depth': string\n 'provenance.detail.title': string\n 'provenance.detail.noSelection': string\n 'provenance.detail.label.name': string\n 'provenance.detail.label.id': string\n 'provenance.detail.label.timestamp': string\n 'provenance.detail.label.agentId': string\n 'provenance.detail.label.instanceId': string\n 'provenance.detail.label.level': string\n 'provenance.detail.label.status': string\n 'provenance.detail.label.tool': string\n 'provenance.detail.label.purpose': string\n 'provenance.detail.label.duration': string\n 'provenance.detail.label.path': string\n 'provenance.detail.label.operation': string\n 'provenance.detail.label.taskId': string\n 'provenance.detail.label.description': string\n 'provenance.detail.label.model': string\n 'provenance.detail.label.tokenCount': string\n 'provenance.detail.label.reasoningPreview': string\n 'provenance.detail.relatedEdges': string\n 'provenance.page.noSessionHint': string\n 'provenance.page.loading': string\n 'provenance.page.emptyGraph': string\n 'provenance.drawer.emptyGraph': string\n 'provenance.graph.edgeType.references': string\n 'toolResult.label': string\n 'toolResult.expandAll': string\n 'toolResult.searchSummary': string\n 'toolResult.scrapeSummary': string\n 'toolResult.more': string\n 'plan.status.active': string\n 'pinned.noMessage': string\n 'viewer.fallback.unknownType': string\n 'viewer.fallback.download': string\n 'fileSize.B': string\n 'fileSize.KB': string\n 'fileSize.MB': string\n 'thinking.title': string\n 'thinking.step': string\n 'viewer.stepHint': string\n 'viewer.threeHint': string\n 'reference.header': string\n 'history.noMessage': string\n 'agent.defaultName': string\n 'error.unknown': string\n 'locale': string\n 'skill.inlineLabel': string\n 'skill.empty': string\n 'skill.searchPlaceholder': string\n 'skill.removeLabel': string\n 'skill.loading': string\n 'skill.loadError': string\n 'skill.loadMore': string\n 'skill.selectorLabel': string\n 'pool.idle': string\n 'pool.collaborating': string\n /** JETP-083 WS3.7.7 follow-up: badge text when at least one agent is\n * paused on a HIL response (no RUNNING agents). ``{{count}}`` = number\n * of paused agents. */\n 'pool.awaiting': string\n 'pool.title': string\n 'pool.empty': string\n 'pool.state.running': string\n /** JETP-083 WS3.7.7 follow-up: agent-row state label for an agent that\n * is blocked inside ``_await_genui_blocking`` waiting on a human HIL\n * reply. Distinguishes from ``running`` / ``completed`` / ``lost``;\n * mapped from backend ``state=\"PAUSED\"``. */\n 'pool.state.paused': string\n 'pool.state.completed': string\n 'pool.state.lost': string\n 'pool.state.unknown': string\n 'input.placeholder': string\n 'input.placeholderLoading': string\n 'discussion.title': string\n 'discussion.empty': string\n 'discussion.active': string\n 'discussion.resolved': string\n 'discussion.archived': string\n 'round.foreign.label': string\n 'round.foreign.unread': string\n 'round.foreign.expand': string\n 'sidebar.mainChat': string\n 'sidebar.chat': string\n 'sidebar.fileQA': string\n 'sidebar.selectionQA': string\n 'sessionList.title': string\n 'sessionList.newSession': string\n 'sessionList.logout': string\n 'sessionList.loading': string\n 'sessionList.empty': string\n 'sessionList.unsupported': string\n 'sessionList.untitled': string\n 'sessionList.deleteTitle': string\n 'sessionList.deleteConfirm': string\n 'sessionList.prevPage': string\n 'sessionList.nextPage': string\n 'sessionList.pageInfo': string\n // ModelPicker (composer 内的\"本次发送使用的模型\"切换器)\n 'modelPicker.menu.head': string\n 'modelPicker.menu.aria': string\n 'modelPicker.auto.title': string\n 'modelPicker.auto.hint.knownChannel': string\n 'modelPicker.auto.hint.knownBasename': string\n 'modelPicker.auto.hint.fallback': string\n 'modelPicker.row.hint.channelMulti': string\n 'modelPicker.row.hint.channelSingle': string\n 'modelPicker.row.hint.versionMulti': string\n 'modelPicker.fallback.placeholder': string\n 'modelPicker.inert.title': string\n 'modelPicker.guestLocked.label': string\n 'modelPicker.guestLocked.title': string\n 'modelPicker.loadingList': string\n 'modelPicker.trigger.title.stale': string\n 'modelPicker.trigger.title.agentDefault.withChannel': string\n 'modelPicker.trigger.title.agentDefault': string\n 'modelPicker.trigger.title.current': string\n 'modelPicker.row.title.pickDefault': string\n 'modelPicker.row.title.pick': string\n 'modelPicker.chip.aria': string\n 'modelPicker.chip.title.available': string\n 'modelPicker.chip.title.unavailable': string\n // ── Picker UX v2:搜索 + 模态 tab + 最近 + 家族分组 ──\n 'modelPicker.search.placeholder': string\n 'modelPicker.search.aria': string\n 'modelPicker.search.clear.aria': string\n 'modelPicker.modality.aria': string\n 'modelPicker.modality.all': string\n 'modelPicker.modality.chat': string\n 'modelPicker.modality.image': string\n 'modelPicker.modality.video': string\n 'modelPicker.modality.audio': string\n 'modelPicker.modality.embedding': string\n 'modelPicker.modality.realtime': string\n 'modelPicker.section.recent': string\n 'modelPicker.section.vendor': string\n 'modelPicker.section.toggle.expand': string\n 'modelPicker.section.toggle.collapse': string\n 'modelPicker.empty.title': string\n 'modelPicker.empty.hint': string\n 'modelPicker.vendor.openai': string\n 'modelPicker.vendor.anthropic': string\n 'modelPicker.vendor.google': string\n 'modelPicker.vendor.xai': string\n 'modelPicker.vendor.alibaba': string\n 'modelPicker.vendor.zhipu': string\n 'modelPicker.vendor.moonshot': string\n 'modelPicker.vendor.bytedance': string\n 'modelPicker.vendor.deepseek': string\n 'modelPicker.vendor.minimax': string\n 'modelPicker.vendor.openrouter': string\n 'modelPicker.vendor.xiaomi': string\n 'modelPicker.vendor.other': string\n // Capability badges (v2.x: 每个模型尾部的小图标)\n 'modelPicker.cap.aria': string\n 'modelPicker.cap.image.title': string\n 'modelPicker.cap.video.native.title': string\n 'modelPicker.cap.video.derived.title': string\n 'modelPicker.cap.audio.title': string\n 'modelPicker.cap.tools.title': string\n 'modelPicker.cap.imageGen.title': string\n 'modelPicker.cap.videoGen.title': string\n 'modelPicker.cap.audioGen.title': string\n // CWRF-013 Phase 4 P2-T00 — `jr-primitives` i18n namespace\n // (spec drift D-I18N-01: rather than pull in `react-i18next` + `i18next`\n // as the spec D9 originally proposed, we extend the existing chat-widget\n // in-house i18n. Same key semantics, zero new dependency.)\n 'jr.confirmDialog.cancel': string\n 'jr.confirmDialog.confirm': string\n 'jr.confirmDialog.loading': string\n}\n\nexport const zhCN: ChatWidgetMessages = {\n 'header.title': 'YumiAI',\n 'header.icon': '',\n 'status.connecting': '连接中...',\n 'status.running': '执行中...',\n 'status.compressing': '上下文压缩中...',\n 'status.error': '连接错误',\n 'status.idle': '待命',\n 'empty.waiting': '等待对话开始...',\n 'empty.icon': '',\n 'round.separator': '上一轮对话',\n 'round.status.running': '执行中',\n 'round.status.completed': '已完成',\n 'round.status.error': '执行失败',\n 'round.noMessage': '(无消息)',\n 'footer.attribution': '',\n 'selection.ask': '问一下',\n 'viewer.loading': '加载中...',\n 'viewer.error': '无法获取文件内容',\n 'viewer.back': '← 返回',\n 'viewer.defaultTitle': '文件预览',\n 'viewer.copyFull': '复制全文',\n 'viewer.copyFullTitle': '复制全文到剪贴板并引用',\n 'viewer.referenceFile': '引用此文件',\n 'viewer.referenceFileTitle': '引用此文件',\n 'viewer.referencePage': '引用当前页面',\n 'viewer.referencePageTitle': '引用当前页面到对话',\n 'viewer.download': '下载',\n 'viewer.fullscreen': '全屏 (⌘L)',\n 'viewer.fullscreenExit': '退出全屏',\n 'viewer.close': '关闭',\n 'viewer.unknownType': '未知类型',\n 'viewer.iframeHint': 'iframe 内容无法直接选中文本,请使用上方「引用此文件」按钮',\n 'viewer.copySnippet': '复制片段',\n 'viewer.loadingPdf': '加载 PDF 查看器...',\n 'viewer.pdfPages': '共 {{count}} 页',\n 'viewer.loadingKicad': '加载 KiCad 查看器...',\n 'viewer.loading3d': '加载 3D 查看器...',\n 'viewer.loadingStep': '加载 STEP 查看器...',\n 'viewer.gerberTitle': 'DFX Copilot — Gerber 预览',\n 'viewer.gerberBlobWarning':\n 'DFX Copilot 需要从公网可访问的地址拉取文件。当前为本地 blob/data URL,iframe 内无法使用。请在 Adapter 中返回 content_url,或实现 getResourceUrl 提供 HTTPS 预签名链接。',\n 'viewer.gerberNoHttpUrl':\n '当前资源地址不是 http(s),无法嵌入 DFX Copilot。请使用直链或预签名 URL。',\n 'viewer.pdfPreview': 'PDF 预览',\n 'viewer.htmlPreview': 'HTML 预览',\n 'viewer.htmlProjectLoading': '正在加载 HTML 项目文件…',\n 'viewer.htmlProjectNoEntry': 'HTML 项目缺少入口文件(如 index.html),无法预览',\n 'viewer.htmlProjectSizeLimit': 'HTML 项目超出大小限制,仅显示入口文件',\n 'viewer.htmlStrategyForcedInlineWarning': '检测到 ESM 模块,但已强制 inline 策略,可能加载失败',\n 'viewer.htmlStrategyFallbackCspWarning': '宿主 CSP 禁止 blob:,已自动降级到 inline 策略',\n 'viewer.copyFullKicadTitle': '复制全文 KiCad 原文到剪贴板并引用,粘贴到输入框即可带入',\n 'viewer.zoomIn': '放大',\n 'viewer.zoomOut': '缩小',\n 'viewer.zoomReset': '重置',\n 'viewer.loadingWord': '加载 Word 查看器...',\n 'viewer.loadingExcel': '加载 Excel 查看器...',\n 'viewer.loadingPowerPoint': '加载 PowerPoint 查看器...',\n 'viewer.pptPrev': '‹ 上一页',\n 'viewer.pptNext': '下一页 ›',\n 'viewer.pptSlide': '幻灯片',\n 'viewer.pptThumbnails': '缩略图',\n 'viewer.excelRows': '行',\n 'viewer.excelColumns': '列',\n 'childAgent.status.running': '执行中',\n 'childAgent.status.completed': '已完成',\n 'hitl.form.defaultTitle': '请填写表单',\n 'hitl.wait.default': '等待用户输入...',\n 'todo.completed.count': '已完成 {{completed}}/{{total}}',\n 'todo.blocked.count': '{{count}} 项阻塞',\n 'todo.more': '+ {{count}} 更多',\n 'todo.header.done': '已完成',\n 'tool.phase.generating': '生成中',\n 'tool.phase.executing': '执行中',\n 'tool.phase.complete': '完成',\n 'tool.phase.error': '失败',\n 'tool.executing': '执行工具: {{name}}',\n 'tool.mcp.running': '执行中',\n 'tool.mcp.success': '完成',\n 'tool.mcp.error': '失败',\n 'form.placeholder.select': '请选择',\n 'form.required.default': '此项为必填项',\n 'form.submit.submit': '提交',\n 'form.submit.submitting': '提交中...',\n 'form.requestId': '请求 ID: ',\n 'pinned.label': '置顶',\n 'plan.title': '执行计划',\n 'plan.step': '步骤 {{index}}',\n 'thinking.inProgress': '思考中...',\n 'thinking.completed': '思考完成',\n 'split.unreadCount': '{{count}} 条新消息',\n 'split.askQuestion': '提问 (⌘/)',\n 'split.exitFullscreen': '退出全屏 (Esc)',\n 'context.inputPlaceholder': '在这里提问…',\n 'context.inputPlaceholderWithFile': '关于 {{fileName}} 提问…',\n 'context.send': '发送',\n 'context.removeReference': '移除引用',\n 'split.home': '主对话',\n 'split.workspace': '工作空间',\n 'split.annotation': '批注',\n 'split.tabClose': '关闭标签页',\n 'split.tabNew': '新标签页',\n 'workspace.title': '工作空间',\n 'workspace.searchPlaceholder': '搜索文件…',\n 'workspace.empty': '暂无文件',\n 'workspace.downloadAll': '打包下载全部文件',\n 'workspace.recent': '最近修改',\n 'workspace.open': '打开',\n 'workspace.openInNewTab': '在新标签页打开',\n 'workspace.download': '下载',\n 'workspace.copyPath': '复制路径',\n 'workspace.expandAll': '展开全部',\n 'workspace.collapseAll': '折叠全部',\n 'annotation.title': '批注',\n 'annotation.empty': '暂无批注',\n 'annotation.fileLevelTitle': '文件对话',\n 'annotation.fileLevelPlaceholder': '关于此文件提问…',\n 'annotation.anchoredPlaceholder': '关于所选内容提问…',\n 'annotation.inlineInputPlaceholder': '就此处提问…',\n 'annotation.replyPlaceholder': '继续追问…',\n 'annotation.anchorLabel': '锚点: {{text}}',\n 'annotation.close': '关闭',\n 'annotation.fabLabel': '文件批注',\n 'annotation.fabHeader': '{{fileName}} · 文件对话',\n 'annotation.messageCount': '{{count}} 条消息',\n 'annotation.anchorInvalid': '锚点已失效',\n 'annotation.errorRetry': '发送失败,点击重试',\n 'annotation.queuedHint': '排队中,请稍候…',\n 'annotation.selectionLabel': '选中内容',\n 'agentControl.pause': '暂停',\n 'agentControl.resume': '继续',\n 'agentControl.stop': '停止',\n 'agentControl.paused': '已暂停',\n 'agentControl.groupTitle': '工作组',\n 'aria.fileNavigation': '文件导航',\n 'kicad.loadFailed': 'KiCanvas 加载失败,已切换至源码视图',\n 'kicad.urlNotReady': '资源 URL 未就绪,当前显示源码',\n 'kicad.loadingEngine': '加载 KiCanvas 可视化引擎...',\n 'kicad.sidebarTitle': 'KiCanvas 侧栏提供:属性、符号/封装列表、文档信息等',\n 'kicad.sidebarPcb': 'PCB:侧栏可查属性、封装列表',\n 'kicad.sidebarSch': 'SCH:侧栏可查符号/子图属性',\n 'kicad.sidebarGeneric': '侧栏查看属性',\n 'kicad.viewVisual': '可视化',\n 'kicad.viewSource': '源码',\n 'provenance.filter.type.agent': '智能体',\n 'provenance.filter.type.action': '工具',\n 'provenance.filter.type.file': '文件',\n 'provenance.filter.type.task': '任务',\n 'provenance.filter.type.reasoning': '推理',\n 'provenance.filter.depth': '深度:',\n 'provenance.toolbar.zoomToFit': '自适应',\n 'provenance.toolbar.resetCamera': '重置视角',\n 'provenance.toolbar.refresh': '刷新',\n 'provenance.legend.reasoning': '推理',\n 'provenance.legend.action': '工具',\n 'provenance.legend.file': '文件',\n 'provenance.legend.task': '任务',\n 'provenance.legend.references': '引用',\n 'provenance.legend.edges': '边: ',\n 'provenance.legend.depth': '深度: ',\n 'provenance.detail.title': '节点详情',\n 'provenance.detail.noSelection': '未选中节点',\n 'provenance.detail.label.name': '名称',\n 'provenance.detail.label.id': 'ID',\n 'provenance.detail.label.timestamp': '时间',\n 'provenance.detail.label.agentId': 'Agent ID',\n 'provenance.detail.label.instanceId': '实例 ID',\n 'provenance.detail.label.level': '层级',\n 'provenance.detail.label.status': '状态',\n 'provenance.detail.label.tool': '工具',\n 'provenance.detail.label.purpose': '目的',\n 'provenance.detail.label.duration': '耗时',\n 'provenance.detail.label.path': '路径',\n 'provenance.detail.label.operation': '操作',\n 'provenance.detail.label.taskId': '任务 ID',\n 'provenance.detail.label.description': '描述',\n 'provenance.detail.label.model': '模型',\n 'provenance.detail.label.tokenCount': 'Token 数',\n 'provenance.detail.label.reasoningPreview': '推理预览',\n 'provenance.detail.relatedEdges': '关联边 ({{count}})',\n 'provenance.page.noSessionHint': '请通过 URL 参数指定会话: ?session_id=NNN',\n 'provenance.page.loading': '加载推理图谱...',\n 'provenance.page.emptyGraph': '当前会话暂无图谱数据',\n 'provenance.drawer.emptyGraph': '暂无图谱数据',\n 'provenance.graph.edgeType.references': '引用',\n 'toolResult.label': '执行结果',\n 'toolResult.expandAll': '展开全部 ({{count}} 行)',\n 'toolResult.searchSummary': '搜索结果 · {{count}} 条',\n 'toolResult.scrapeSummary': '抓取结果 · {{title}}',\n 'toolResult.more': '+{{count}} more',\n 'plan.status.active': '执行中',\n 'pinned.noMessage': '(无消息内容)',\n 'viewer.fallback.unknownType': '未知类型',\n 'viewer.fallback.download': '下载文件',\n 'fileSize.B': '{{size}} B',\n 'fileSize.KB': '{{size}} KB',\n 'fileSize.MB': '{{size}} MB',\n 'thinking.title': '思考推理',\n 'thinking.step': '步骤 {{step}}',\n 'viewer.stepHint': '鼠标拖拽旋转,滚轮缩放,右键平移',\n 'viewer.threeHint': '鼠标拖拽旋转,滚轮缩放,右键平移',\n 'viewer.3d.wireframe': '线框模式',\n 'viewer.3d.resetView': '重置视角',\n 'reference.header': '[引用文件: {{fileName}}]',\n 'history.noMessage': '(历史消息)',\n 'agent.defaultName': '助手',\n 'error.unknown': '未知错误',\n 'locale': 'zh-CN',\n 'skill.inlineLabel': '先查看并使用{{name}}技能,去解决:',\n 'skill.empty': '暂无可用技能',\n 'skill.searchPlaceholder': '搜索技能...',\n 'skill.removeLabel': '移除技能',\n 'skill.loading': '加载中...',\n 'skill.loadError': '加载技能失败',\n 'skill.loadMore': '加载更多',\n 'skill.selectorLabel': '技能选择',\n 'pool.idle': '待命',\n 'pool.collaborating': '{{count}} 协作中',\n 'pool.awaiting': '{{count}} 等待人工',\n 'pool.title': '智能体池',\n 'pool.empty': '暂无活跃智能体',\n 'pool.state.running': '执行中',\n 'pool.state.paused': '等待人工',\n 'pool.state.completed': '已完成',\n 'pool.state.lost': '已失联',\n 'pool.state.unknown': '未知',\n 'input.placeholder': '输入消息,/ 选择技能',\n 'input.placeholderLoading': '等待回复中…',\n 'discussion.title': '讨论',\n 'discussion.empty': '暂无讨论',\n 'discussion.active': '进行中',\n 'discussion.resolved': '已结论',\n 'discussion.archived': '已归档',\n 'round.foreign.label': '来自其他窗口的对话',\n 'round.foreign.unread': '{{count}} 条新消息',\n 'round.foreign.expand': '点击展开',\n 'sidebar.mainChat': '主对话',\n 'sidebar.chat': '对话',\n 'sidebar.fileQA': '文件问答',\n 'sidebar.selectionQA': '选区问答',\n 'sessionList.title': '历史会话',\n 'sessionList.newSession': '+ 新会话',\n 'sessionList.logout': '退出',\n 'sessionList.loading': '加载中...',\n 'sessionList.empty': '暂无会话',\n 'sessionList.unsupported': '当前 adapter 未实现 listSessions',\n 'sessionList.untitled': '无标题',\n 'sessionList.deleteTitle': '删除会话',\n 'sessionList.deleteConfirm': '确定删除该会话?',\n 'sessionList.prevPage': '←',\n 'sessionList.nextPage': '→',\n 'sessionList.pageInfo': '第 {page} / {totalPages} 页',\n 'modelPicker.menu.head': '本次使用的模型',\n 'modelPicker.menu.aria': '选择本次使用的模型',\n 'modelPicker.auto.title': '默认(跟随 Agent)',\n 'modelPicker.auto.hint.knownChannel': '当前 Agent 默认:{{name}} · {{channel}}',\n 'modelPicker.auto.hint.knownBasename': '当前 Agent 默认:{{name}}',\n 'modelPicker.auto.hint.fallback': '使用 Agent 注册的默认模型,跨子 Agent 自动切换',\n 'modelPicker.row.hint.channelMulti': '{{available}}/{{total}} 个渠道可用',\n 'modelPicker.row.hint.channelSingle': '渠道:{{channel}}',\n 'modelPicker.row.hint.versionMulti': '{{count}} 个版本可用',\n 'modelPicker.fallback.placeholder': '默认模型',\n 'modelPicker.inert.title': '模型选择当前不可用',\n 'modelPicker.guestLocked.label': '默认模型 · 登录后可选',\n 'modelPicker.guestLocked.title': '登录后可在多个模型间切换;游客先用默认模型即可开干。',\n 'modelPicker.loadingList': '加载模型清单…',\n 'modelPicker.trigger.title.stale': '{{name}}(已不在清单中,发送时仍会尝试使用)',\n 'modelPicker.trigger.title.agentDefault.withChannel':\n '当前 Agent 默认:{{name}} · {{channel}}(发送时跟随 Agent)',\n 'modelPicker.trigger.title.agentDefault': '当前 Agent 默认:{{name}}(发送时跟随 Agent)',\n 'modelPicker.trigger.title.current': '当前模型:{{name}}',\n 'modelPicker.row.title.pickDefault': '选默认渠道({{hint}})',\n 'modelPicker.row.title.pick': '选用 {{name}}',\n 'modelPicker.chip.aria': '{{title}} 渠道',\n 'modelPicker.chip.title.available': '渠道 {{channel}} · 模型 {{name}}',\n 'modelPicker.chip.title.unavailable': '渠道 {{channel}} · 当前不可用',\n 'modelPicker.search.placeholder': '搜索模型,如 gpt5、claude opus…',\n 'modelPicker.search.aria': '搜索模型',\n 'modelPicker.search.clear.aria': '清空搜索',\n 'modelPicker.modality.aria': '按能力筛选',\n 'modelPicker.modality.all': '全部',\n 'modelPicker.modality.chat': '对话',\n 'modelPicker.modality.image': '图像',\n 'modelPicker.modality.video': '视频',\n 'modelPicker.modality.audio': '语音',\n 'modelPicker.modality.embedding': '向量',\n 'modelPicker.modality.realtime': '实时',\n 'modelPicker.section.recent': '最近使用',\n 'modelPicker.section.vendor': '{{vendor}}',\n 'modelPicker.section.toggle.expand': '展开 {{vendor}}',\n 'modelPicker.section.toggle.collapse': '折叠 {{vendor}}',\n 'modelPicker.empty.title': '没有匹配的模型',\n 'modelPicker.empty.hint': '试试清空搜索或换一个能力分类',\n 'modelPicker.vendor.openai': 'OpenAI',\n 'modelPicker.vendor.anthropic': 'Anthropic',\n 'modelPicker.vendor.google': 'Google',\n 'modelPicker.vendor.xai': 'xAI',\n 'modelPicker.vendor.alibaba': '阿里',\n 'modelPicker.vendor.zhipu': '智谱',\n 'modelPicker.vendor.moonshot': '月之暗面',\n 'modelPicker.vendor.bytedance': '字节',\n 'modelPicker.vendor.deepseek': 'DeepSeek',\n 'modelPicker.vendor.minimax': 'MiniMax',\n 'modelPicker.vendor.openrouter': 'OpenRouter',\n 'modelPicker.vendor.xiaomi': '小米',\n 'modelPicker.vendor.other': '其他',\n 'modelPicker.cap.aria': '模型能力',\n 'modelPicker.cap.image.title': '图像理解(可读取图片输入)',\n 'modelPicker.cap.video.native.title': '原生视频推理',\n 'modelPicker.cap.video.derived.title': '视频推理(通过图像理解能力衍生,按帧采样处理)',\n 'modelPicker.cap.audio.title': '语音输入理解',\n 'modelPicker.cap.tools.title': '工具调用 / Function Call',\n 'modelPicker.cap.imageGen.title': '图像生成',\n 'modelPicker.cap.videoGen.title': '视频生成',\n 'modelPicker.cap.audioGen.title': '音频生成 / TTS / 音乐合成',\n 'jr.confirmDialog.cancel': '取消',\n 'jr.confirmDialog.confirm': '确认',\n 'jr.confirmDialog.loading': '处理中',\n}\n\nexport const enUS: ChatWidgetMessages = {\n 'header.title': 'AI Assistant',\n 'header.icon': '',\n 'status.connecting': 'Connecting...',\n 'status.running': 'Running...',\n 'status.compressing': 'Compressing context...',\n 'status.error': 'Connection error',\n 'status.idle': 'Idle',\n 'empty.waiting': 'Waiting for conversation...',\n 'empty.icon': '',\n 'round.separator': 'Previous round',\n 'round.status.running': 'Running',\n 'round.status.completed': 'Completed',\n 'round.status.error': 'Failed',\n 'round.noMessage': '(no message)',\n 'footer.attribution': '',\n 'selection.ask': 'Ask',\n 'viewer.loading': 'Loading...',\n 'viewer.error': 'Failed to load file content',\n 'viewer.back': '← Back',\n 'viewer.defaultTitle': 'File Preview',\n 'viewer.copyFull': 'Copy full',\n 'viewer.copyFullTitle': 'Copy full content to clipboard',\n 'viewer.referenceFile': 'Reference file',\n 'viewer.referenceFileTitle': 'Reference this file',\n 'viewer.referencePage': 'Reference page',\n 'viewer.referencePageTitle': 'Reference this page in chat',\n 'viewer.download': 'Download',\n 'viewer.fullscreen': 'Fullscreen (⌘L)',\n 'viewer.fullscreenExit': 'Exit fullscreen',\n 'viewer.close': 'Close',\n 'viewer.unknownType': 'Unknown type',\n 'viewer.iframeHint': 'iframe content cannot be selected directly. Use the \"Reference file\" button above.',\n 'viewer.copySnippet': 'Copy snippet',\n 'viewer.loadingPdf': 'Loading PDF viewer...',\n 'viewer.pdfPages': '{{count}} pages',\n 'viewer.loadingKicad': 'Loading KiCad viewer...',\n 'viewer.loading3d': 'Loading 3D viewer...',\n 'viewer.loadingStep': 'Loading STEP viewer...',\n 'viewer.gerberTitle': 'DFX Copilot — Gerber preview',\n 'viewer.gerberBlobWarning':\n 'DFX Copilot must fetch the file from a public URL. Local blob/data URLs cannot be used inside a cross-origin iframe. Return content_url from getResourceContent or implement getResourceUrl with an HTTPS presigned link.',\n 'viewer.gerberNoHttpUrl':\n 'The resource URL is not http(s); it cannot be passed to DFX Copilot. Use a direct or presigned URL.',\n 'viewer.pdfPreview': 'PDF Preview',\n 'viewer.htmlPreview': 'HTML Preview',\n 'viewer.htmlProjectLoading': 'Loading HTML project files…',\n 'viewer.htmlProjectNoEntry': 'HTML project is missing an entry file (e.g. index.html); cannot render',\n 'viewer.htmlProjectSizeLimit': 'HTML project exceeds size limit; only the entry file is rendered',\n 'viewer.htmlStrategyForcedInlineWarning': 'ESM modules detected, but inline strategy is forced; imports may fail',\n 'viewer.htmlStrategyFallbackCspWarning': 'Host CSP blocks blob: URLs; automatically falling back to inline strategy',\n 'viewer.copyFullKicadTitle': 'Copy full KiCad source to clipboard and reference',\n 'viewer.zoomIn': 'Zoom in',\n 'viewer.zoomOut': 'Zoom out',\n 'viewer.zoomReset': 'Reset',\n 'viewer.loadingWord': 'Loading Word viewer...',\n 'viewer.loadingExcel': 'Loading Excel viewer...',\n 'viewer.loadingPowerPoint': 'Loading PowerPoint viewer...',\n 'viewer.pptPrev': '‹ Prev',\n 'viewer.pptNext': 'Next ›',\n 'viewer.pptSlide': 'Slide',\n 'viewer.pptThumbnails': 'Thumbnails',\n 'viewer.excelRows': 'rows',\n 'viewer.excelColumns': 'columns',\n 'childAgent.status.running': 'Running',\n 'childAgent.status.completed': 'Completed',\n 'hitl.form.defaultTitle': 'Please fill the form',\n 'hitl.wait.default': 'Waiting for user input...',\n 'todo.completed.count': '{{completed}}/{{total}} completed',\n 'todo.blocked.count': '{{count}} blocked',\n 'todo.more': '+ {{count}} more',\n 'todo.header.done': 'Done',\n 'tool.phase.generating': 'Generating',\n 'tool.phase.executing': 'Executing',\n 'tool.phase.complete': 'Complete',\n 'tool.phase.error': 'Failed',\n 'tool.executing': 'Execute tool: {{name}}',\n 'tool.mcp.running': 'Running',\n 'tool.mcp.success': 'Complete',\n 'tool.mcp.error': 'Failed',\n 'form.placeholder.select': 'Please select',\n 'form.required.default': 'This field is required',\n 'form.submit.submit': 'Submit',\n 'form.submit.submitting': 'Submitting...',\n 'form.requestId': 'Request ID: ',\n 'pinned.label': 'Pinned',\n 'plan.title': 'Execution Plan',\n 'plan.step': 'Step {{index}}',\n 'thinking.inProgress': 'Thinking...',\n 'thinking.completed': 'Thinking completed',\n 'split.unreadCount': '{{count}} new messages',\n 'split.askQuestion': 'Ask (⌘/)',\n 'split.exitFullscreen': 'Exit fullscreen (Esc)',\n 'context.inputPlaceholder': 'Ask here...',\n 'context.inputPlaceholderWithFile': 'Ask about {{fileName}}...',\n 'context.send': 'Send',\n 'context.removeReference': 'Remove reference',\n 'split.home': 'Main Chat',\n 'split.workspace': 'Workspace',\n 'split.annotation': 'Annotations',\n 'split.tabClose': 'Close tab',\n 'split.tabNew': 'New tab',\n 'workspace.title': 'Workspace',\n 'workspace.searchPlaceholder': 'Search files...',\n 'workspace.empty': 'No files yet',\n 'workspace.downloadAll': 'Download all files as zip',\n 'workspace.recent': 'Recent changes',\n 'workspace.open': 'Open',\n 'workspace.openInNewTab': 'Open in new tab',\n 'workspace.download': 'Download',\n 'workspace.copyPath': 'Copy path',\n 'workspace.expandAll': 'Expand all',\n 'workspace.collapseAll': 'Collapse all',\n 'annotation.title': 'Annotations',\n 'annotation.empty': 'No annotations',\n 'annotation.fileLevelTitle': 'File Conversation',\n 'annotation.fileLevelPlaceholder': 'Ask about this file...',\n 'annotation.anchoredPlaceholder': 'Ask about selection...',\n 'annotation.inlineInputPlaceholder': 'Ask about this...',\n 'annotation.replyPlaceholder': 'Follow up...',\n 'annotation.anchorLabel': 'Anchor: {{text}}',\n 'annotation.close': 'Close',\n 'annotation.fabLabel': 'File annotation',\n 'annotation.fabHeader': '{{fileName}} · File Conversation',\n 'annotation.messageCount': '{{count}} messages',\n 'annotation.anchorInvalid': 'Anchor invalidated',\n 'annotation.errorRetry': 'Send failed, click to retry',\n 'annotation.queuedHint': 'Queued, please wait...',\n 'annotation.selectionLabel': 'Selected text',\n 'agentControl.pause': 'Pause',\n 'agentControl.resume': 'Resume',\n 'agentControl.stop': 'Stop',\n 'agentControl.paused': 'Paused',\n 'agentControl.groupTitle': 'Agent Group',\n 'aria.fileNavigation': 'File navigation',\n 'kicad.loadFailed': 'KiCanvas load failed, switched to source view',\n 'kicad.urlNotReady': 'Resource URL not ready, showing source',\n 'kicad.loadingEngine': 'Loading KiCanvas engine...',\n 'kicad.sidebarTitle': 'KiCanvas sidebar: properties, symbol/footprint list, docs',\n 'kicad.sidebarPcb': 'PCB: view properties, footprint list',\n 'kicad.sidebarSch': 'SCH: view symbol/sub-sheet properties',\n 'kicad.sidebarGeneric': 'View properties',\n 'kicad.viewVisual': 'Visual',\n 'kicad.viewSource': 'Source',\n 'provenance.filter.type.agent': 'Agent',\n 'provenance.filter.type.action': 'Action',\n 'provenance.filter.type.file': 'File',\n 'provenance.filter.type.task': 'Task',\n 'provenance.filter.type.reasoning': 'Reasoning',\n 'provenance.filter.depth': 'Depth:',\n 'provenance.toolbar.zoomToFit': 'Zoom to fit',\n 'provenance.toolbar.resetCamera': 'Reset camera',\n 'provenance.toolbar.refresh': 'Refresh',\n 'provenance.legend.reasoning': 'Reasoning',\n 'provenance.legend.action': 'Action',\n 'provenance.legend.file': 'File',\n 'provenance.legend.task': 'Task',\n 'provenance.legend.references': 'References',\n 'provenance.legend.edges': 'Edges: ',\n 'provenance.legend.depth': 'Depth: ',\n 'provenance.detail.title': 'Node details',\n 'provenance.detail.noSelection': 'No node selected',\n 'provenance.detail.label.name': 'Name',\n 'provenance.detail.label.id': 'ID',\n 'provenance.detail.label.timestamp': 'Timestamp',\n 'provenance.detail.label.agentId': 'Agent ID',\n 'provenance.detail.label.instanceId': 'Instance ID',\n 'provenance.detail.label.level': 'Level',\n 'provenance.detail.label.status': 'Status',\n 'provenance.detail.label.tool': 'Tool',\n 'provenance.detail.label.purpose': 'Purpose',\n 'provenance.detail.label.duration': 'Duration',\n 'provenance.detail.label.path': 'Path',\n 'provenance.detail.label.operation': 'Operation',\n 'provenance.detail.label.taskId': 'Task ID',\n 'provenance.detail.label.description': 'Description',\n 'provenance.detail.label.model': 'Model',\n 'provenance.detail.label.tokenCount': 'Token count',\n 'provenance.detail.label.reasoningPreview': 'Reasoning preview',\n 'provenance.detail.relatedEdges': 'Related edges ({{count}})',\n 'provenance.page.noSessionHint': 'Please specify session via URL: ?session_id=NNN',\n 'provenance.page.loading': 'Loading provenance graph...',\n 'provenance.page.emptyGraph': 'No graph data for this session',\n 'provenance.drawer.emptyGraph': 'No graph data',\n 'provenance.graph.edgeType.references': 'References',\n 'toolResult.label': 'Result',\n 'toolResult.expandAll': 'Expand all ({{count}} lines)',\n 'toolResult.searchSummary': 'Search results · {{count}}',\n 'toolResult.scrapeSummary': 'Scrape result · {{title}}',\n 'toolResult.more': '+{{count}} more',\n 'plan.status.active': 'Running',\n 'pinned.noMessage': '(no message content)',\n 'viewer.fallback.unknownType': 'Unknown type',\n 'viewer.fallback.download': 'Download file',\n 'fileSize.B': '{{size}} B',\n 'fileSize.KB': '{{size}} KB',\n 'fileSize.MB': '{{size}} MB',\n 'thinking.title': 'Thinking',\n 'thinking.step': 'Step {{step}}',\n 'viewer.stepHint': 'Drag to rotate, scroll to zoom, right-click to pan',\n 'viewer.threeHint': 'Drag to rotate, scroll to zoom, right-click to pan',\n 'viewer.3d.wireframe': 'Wireframe',\n 'viewer.3d.resetView': 'Reset view',\n 'reference.header': '[Reference: {{fileName}}]',\n 'history.noMessage': '(history message)',\n 'agent.defaultName': 'Assistant',\n 'error.unknown': 'Unknown error',\n 'locale': 'en-US',\n 'skill.inlineLabel': 'First check and use the {{name}} skill to solve: ',\n 'skill.empty': 'No skills available',\n 'skill.searchPlaceholder': 'Search skills...',\n 'skill.removeLabel': 'Remove skill',\n 'skill.loading': 'Loading...',\n 'skill.loadError': 'Failed to load skills',\n 'skill.loadMore': 'Load more',\n 'skill.selectorLabel': 'Skill selector',\n 'pool.idle': 'Idle',\n 'pool.collaborating': '{{count}} working',\n 'pool.awaiting': '{{count}} awaiting human',\n 'pool.title': 'Agent Pool',\n 'pool.empty': 'No active agents',\n 'pool.state.running': 'Running',\n 'pool.state.paused': 'Awaiting human',\n 'pool.state.completed': 'Completed',\n 'pool.state.lost': 'Lost',\n 'pool.state.unknown': 'Unknown',\n 'input.placeholder': 'Type a message, / for skills',\n 'input.placeholderLoading': 'Waiting for response…',\n 'discussion.title': 'Discussions',\n 'discussion.empty': 'No discussions',\n 'discussion.active': 'Active',\n 'discussion.resolved': 'Resolved',\n 'discussion.archived': 'Archived',\n 'round.foreign.label': 'Conversation from another tab',\n 'round.foreign.unread': '{{count}} new messages',\n 'round.foreign.expand': 'Click to expand',\n 'sidebar.mainChat': 'Main chat',\n 'sidebar.chat': 'Chat',\n 'sidebar.fileQA': 'File Q&A',\n 'sidebar.selectionQA': 'Selection Q&A',\n 'sessionList.title': 'Sessions',\n 'sessionList.newSession': '+ New chat',\n 'sessionList.logout': 'Logout',\n 'sessionList.loading': 'Loading...',\n 'sessionList.empty': 'No sessions yet',\n 'sessionList.unsupported': 'Adapter does not implement listSessions',\n 'sessionList.untitled': 'Untitled',\n 'sessionList.deleteTitle': 'Delete session',\n 'sessionList.deleteConfirm': 'Delete this session?',\n 'sessionList.prevPage': '←',\n 'sessionList.nextPage': '→',\n 'sessionList.pageInfo': 'Page {page} / {totalPages}',\n 'modelPicker.menu.head': 'Model for this turn',\n 'modelPicker.menu.aria': 'Choose the model for this turn',\n 'modelPicker.auto.title': 'Default (follow agent)',\n 'modelPicker.auto.hint.knownChannel': 'Agent default: {{name}} · {{channel}}',\n 'modelPicker.auto.hint.knownBasename': 'Agent default: {{name}}',\n 'modelPicker.auto.hint.fallback':\n \"Use the agent's registered default model; sub-agents follow automatically\",\n 'modelPicker.row.hint.channelMulti': '{{available}} of {{total}} channels available',\n 'modelPicker.row.hint.channelSingle': 'Channel: {{channel}}',\n 'modelPicker.row.hint.versionMulti': '{{count}} versions available',\n 'modelPicker.fallback.placeholder': 'Default model',\n 'modelPicker.inert.title': 'Model picker is unavailable',\n 'modelPicker.guestLocked.label': 'Default model · sign in to choose',\n 'modelPicker.guestLocked.title':\n 'Signed-in users can switch among multiple models. As a guest you start with the default — sign in any time to swap.',\n 'modelPicker.loadingList': 'Loading model list…',\n 'modelPicker.trigger.title.stale':\n '{{name}} (no longer listed — will still be attempted on send)',\n 'modelPicker.trigger.title.agentDefault.withChannel':\n 'Agent default: {{name}} · {{channel}} (sent value follows the agent)',\n 'modelPicker.trigger.title.agentDefault':\n 'Agent default: {{name}} (sent value follows the agent)',\n 'modelPicker.trigger.title.current': 'Current model: {{name}}',\n 'modelPicker.row.title.pickDefault': 'Use default channel ({{hint}})',\n 'modelPicker.row.title.pick': 'Use {{name}}',\n 'modelPicker.chip.aria': '{{title}} channels',\n 'modelPicker.chip.title.available': 'Channel {{channel}} · model {{name}}',\n 'modelPicker.chip.title.unavailable': 'Channel {{channel}} · currently unavailable',\n 'modelPicker.search.placeholder': 'Search models — e.g. gpt5, claude opus…',\n 'modelPicker.search.aria': 'Search models',\n 'modelPicker.search.clear.aria': 'Clear search',\n 'modelPicker.modality.aria': 'Filter by capability',\n 'modelPicker.modality.all': 'All',\n 'modelPicker.modality.chat': 'Chat',\n 'modelPicker.modality.image': 'Image',\n 'modelPicker.modality.video': 'Video',\n 'modelPicker.modality.audio': 'Audio',\n 'modelPicker.modality.embedding': 'Embedding',\n 'modelPicker.modality.realtime': 'Realtime',\n 'modelPicker.section.recent': 'Recent',\n 'modelPicker.section.vendor': '{{vendor}}',\n 'modelPicker.section.toggle.expand': 'Expand {{vendor}}',\n 'modelPicker.section.toggle.collapse': 'Collapse {{vendor}}',\n 'modelPicker.empty.title': 'No models match',\n 'modelPicker.empty.hint': 'Try clearing the search or switching capability',\n 'modelPicker.vendor.openai': 'OpenAI',\n 'modelPicker.vendor.anthropic': 'Anthropic',\n 'modelPicker.vendor.google': 'Google',\n 'modelPicker.vendor.xai': 'xAI',\n 'modelPicker.vendor.alibaba': 'Alibaba',\n 'modelPicker.vendor.zhipu': 'Zhipu',\n 'modelPicker.vendor.moonshot': 'Moonshot',\n 'modelPicker.vendor.bytedance': 'ByteDance',\n 'modelPicker.vendor.deepseek': 'DeepSeek',\n 'modelPicker.vendor.minimax': 'MiniMax',\n 'modelPicker.vendor.openrouter': 'OpenRouter',\n 'modelPicker.vendor.xiaomi': 'Xiaomi',\n 'modelPicker.vendor.other': 'Other',\n 'modelPicker.cap.aria': 'Model capabilities',\n 'modelPicker.cap.image.title': 'Vision (accepts image input)',\n 'modelPicker.cap.video.native.title': 'Native video understanding',\n 'modelPicker.cap.video.derived.title': 'Video understanding (derived from vision via frame sampling)',\n 'modelPicker.cap.audio.title': 'Audio input understanding',\n 'modelPicker.cap.tools.title': 'Tool calling / function call',\n 'modelPicker.cap.imageGen.title': 'Image generation',\n 'modelPicker.cap.videoGen.title': 'Video generation',\n 'modelPicker.cap.audioGen.title': 'Audio generation / TTS / music synthesis',\n 'jr.confirmDialog.cancel': 'Cancel',\n 'jr.confirmDialog.confirm': 'Confirm',\n 'jr.confirmDialog.loading': 'Processing',\n}\n\nexport type ChatWidgetLocale = 'zh-CN' | 'en-US'\n\nconst builtinMessages: Record<ChatWidgetLocale, ChatWidgetMessages> = {\n 'zh-CN': zhCN,\n 'en-US': enUS,\n}\n\nexport function resolveMessages(\n locale: ChatWidgetLocale = 'zh-CN',\n overrides?: Partial<ChatWidgetMessages>,\n): ChatWidgetMessages {\n const base = builtinMessages[locale] ?? zhCN\n if (!overrides) return base\n return { ...base, ...overrides }\n}\n\nexport function interpolate(\n template: string,\n params?: Record<string, string | number>,\n): string {\n if (!params) return template\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) =>\n String(params[key] ?? ''),\n )\n}\n","/**\n * JETP-025: NodeDetailPanel\n *\n * Drawer panel showing detailed information about a selected graph node.\n * Uses antd Drawer + Descriptions for consistent JetForge styling.\n */\n\nimport React, { useMemo } from 'react'\nimport { Drawer, Descriptions, Tag, Typography, Space, Badge } from 'antd'\nimport type { ProvenanceGraphSnapshot, NodeType, ProvenanceNode } from '../types'\nimport { NODE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\nimport type { ChatWidgetMessages } from '../../i18n'\n\nconst { Text, Paragraph } = Typography\n\ninterface NodeDetailPanelProps {\n open: boolean\n nodeId: string | null\n graph: ProvenanceGraphSnapshot\n onClose: () => void\n}\n\nconst TYPE_LABEL_KEYS: Record<NodeType, keyof ChatWidgetMessages> = {\n agent: 'provenance.filter.type.agent',\n action: 'provenance.filter.type.action',\n file: 'provenance.filter.type.file',\n task: 'provenance.filter.type.task',\n reasoning: 'provenance.filter.type.reasoning',\n}\n\nfunction findNode(graph: ProvenanceGraphSnapshot, nodeId: string): ProvenanceNode | null {\n const all = [\n ...graph.nodes.agents,\n ...graph.nodes.actions,\n ...graph.nodes.files,\n ...graph.nodes.tasks,\n ...graph.nodes.reasonings,\n ]\n return all.find((n) => n.id === nodeId) ?? null\n}\n\nfunction formatTimestamp(ts: number): string {\n return new Date(ts).toLocaleString('zh-CN')\n}\n\nfunction formatDuration(ms: number | null | undefined): string {\n if (ms == null) return '-'\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\nconst NodeDetailPanelInner: React.FC<NodeDetailPanelProps> = ({\n open,\n nodeId,\n graph,\n onClose,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const node = useMemo(() => (nodeId ? findNode(graph, nodeId) : null), [graph, nodeId])\n\n const relatedEdges = useMemo(() => {\n if (!nodeId) return []\n return graph.edges.filter((e) => e.source === nodeId || e.target === nodeId)\n }, [graph.edges, nodeId])\n\n if (!node) {\n return (\n <Drawer title={t('provenance.detail.title')} open={open} onClose={onClose} width={360}>\n <Text type=\"secondary\">{t('provenance.detail.noSelection')}</Text>\n </Drawer>\n )\n }\n\n return (\n <Drawer\n title={\n <Space>\n <Badge color={NODE_COLORS[node.type]} />\n <span>{t(TYPE_LABEL_KEYS[node.type])}</span>\n <Tag>{node.type}</Tag>\n </Space>\n }\n open={open}\n onClose={onClose}\n width={380}\n destroyOnHidden\n >\n <Descriptions column={1} size=\"small\" bordered>\n <Descriptions.Item label={t('provenance.detail.label.name')}>\n <Text strong>{node.label}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.id')}>\n <Text code copyable>{node.id}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.timestamp')}>{formatTimestamp(node.timestamp)}</Descriptions.Item>\n\n {node.type === 'agent' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.agentId')}>\n <Text code>{node.agent_id}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.instanceId')}>{node.agent_instance_id}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.level')}>{node.level}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag color={node.status === 'running' ? 'processing' : node.status === 'completed' ? 'success' : 'error'}>\n {node.status ?? 'unknown'}\n </Tag>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'action' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.tool')}>{node.tool_name}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.purpose')}>{node.task_purpose || '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag color={node.status === 'success' ? 'success' : node.status === 'error' ? 'error' : 'processing'}>\n {node.status}\n </Tag>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.duration')}>{formatDuration(node.duration_ms)}</Descriptions.Item>\n </>\n )}\n\n {node.type === 'file' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.path')}>\n <Text code>{node.git_path}</Text>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.operation')}>\n <Tag color={node.operation === 'create' ? 'green' : node.operation === 'delete' ? 'red' : 'blue'}>\n {node.operation}\n </Tag>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'task' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.taskId')}>{node.task_id}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.status')}>\n <Tag>{node.status}</Tag>\n </Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.description')}>\n <Paragraph ellipsis={{ rows: 3 }}>{node.description}</Paragraph>\n </Descriptions.Item>\n </>\n )}\n\n {node.type === 'reasoning' && (\n <>\n <Descriptions.Item label={t('provenance.detail.label.model')}>{node.model || '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.tokenCount')}>{node.token_count ?? '-'}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.duration')}>{formatDuration(node.duration_ms)}</Descriptions.Item>\n <Descriptions.Item label={t('provenance.detail.label.reasoningPreview')}>\n <Paragraph ellipsis={{ rows: 5 }}>{node.content_preview || '(empty)'}</Paragraph>\n </Descriptions.Item>\n </>\n )}\n </Descriptions>\n\n {relatedEdges.length > 0 && (\n <>\n <Text strong style={{ display: 'block', marginTop: 16, marginBottom: 8 }}>\n {t('provenance.detail.relatedEdges', { count: relatedEdges.length })}\n </Text>\n <Space orientation=\"vertical\" size={4} style={{ width: '100%' }}>\n {relatedEdges.slice(0, 20).map((e, i) => (\n <div key={i} style={{ fontSize: 12, color: '#666' }}>\n <Tag color=\"default\" style={{ fontSize: 11 }}>{e.type}</Tag>\n {e.source === nodeId ? `→ ${e.target}` : `← ${e.source}`}\n </div>\n ))}\n </Space>\n </>\n )}\n </Drawer>\n )\n}\n\nexport const NodeDetailPanel = React.memo(NodeDetailPanelInner)\n","import React from 'react'\nimport { I18nContext } from '../i18n'\nimport type { ChatWidgetMessages, ChatWidgetLocale } from '../i18n'\nimport { resolveMessages } from '../i18n'\n\ninterface ProvenanceI18nProviderProps {\n locale?: ChatWidgetLocale\n messages?: Partial<ChatWidgetMessages>\n children: React.ReactNode\n}\n\nexport const ProvenanceI18nProvider: React.FC<ProvenanceI18nProviderProps> = ({\n locale = 'zh-CN',\n messages: overrides,\n children,\n}) => {\n const resolved = React.useMemo(\n () => resolveMessages(locale, overrides),\n [locale, overrides],\n )\n\n return (\n <I18nContext.Provider value={resolved}>\n {children}\n </I18nContext.Provider>\n )\n}\n","/**\n * JETP-025: FilterBar\n *\n * Provides controls for filtering the provenance graph:\n * - Node type toggle (multi-select)\n * - Depth filter (N-hop from selected node)\n */\n\nimport React, { useCallback, useMemo } from 'react'\nimport { Checkbox, Slider, Space, Typography, Badge } from 'antd'\nimport type { NodeType } from '../types'\nimport { NODE_COLORS } from '../constants'\nimport { useChatWidgetI18n } from '../../i18n'\n\nconst { Text } = Typography\n\ninterface FilterBarProps {\n visibleTypes: Set<NodeType>\n onVisibleTypesChange: (types: Set<NodeType>) => void\n depth: number\n onDepthChange: (depth: number) => void\n hasSelection: boolean\n}\n\nconst ALL_TYPES: NodeType[] = ['agent', 'action', 'file', 'task', 'reasoning']\n\nconst TYPE_LABEL_KEYS: Record<NodeType, 'provenance.filter.type.agent' | 'provenance.filter.type.action' | 'provenance.filter.type.file' | 'provenance.filter.type.task' | 'provenance.filter.type.reasoning'> = {\n agent: 'provenance.filter.type.agent',\n action: 'provenance.filter.type.action',\n file: 'provenance.filter.type.file',\n task: 'provenance.filter.type.task',\n reasoning: 'provenance.filter.type.reasoning',\n}\n\nconst FilterBarInner: React.FC<FilterBarProps> = ({\n visibleTypes,\n onVisibleTypesChange,\n depth,\n onDepthChange,\n hasSelection,\n}) => {\n const { t } = useChatWidgetI18n()\n\n const typeOptions = useMemo(() => ALL_TYPES.map((tp) => ({\n label: (\n <Space size={4}>\n <Badge color={NODE_COLORS[tp]} />\n <span>{t(TYPE_LABEL_KEYS[tp])}</span>\n </Space>\n ),\n value: tp as string,\n })), [t])\n\n const handleTypeChange = useCallback(\n (values: string[]) => {\n onVisibleTypesChange(new Set(values as NodeType[]))\n },\n [onVisibleTypesChange],\n )\n\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n padding: '8px 16px',\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n borderBottom: '1px solid #eee',\n }}\n >\n <Checkbox.Group\n options={typeOptions}\n value={Array.from(visibleTypes)}\n onChange={handleTypeChange}\n />\n\n {hasSelection && (\n <Space size={8} style={{ marginLeft: 'auto' }}>\n <Text type=\"secondary\" style={{ fontSize: 12 }}>\n {t('provenance.filter.depth')}\n </Text>\n <Slider\n min={1}\n max={5}\n value={depth}\n onChange={onDepthChange}\n style={{ width: 100 }}\n tooltip={{ open: false }}\n />\n <Text style={{ fontSize: 12, minWidth: 20 }}>{depth}</Text>\n </Space>\n )}\n </div>\n )\n}\n\nexport const FilterBar = React.memo(FilterBarInner)\n","/**\n * JETP-025: GraphToolbar\n *\n * Floating toolbar with zoom-to-fit, reset camera, and refresh controls.\n */\n\nimport React from 'react'\nimport { Button, Space, Tooltip } from 'antd'\nimport {\n ExpandOutlined,\n ReloadOutlined,\n AimOutlined,\n} from '@ant-design/icons'\nimport { useChatWidgetI18n } from '../../i18n'\n\ninterface GraphToolbarProps {\n onZoomToFit: () => void\n onResetCamera: () => void\n onRefresh: () => void\n loading?: boolean\n}\n\nconst GraphToolbarInner: React.FC<GraphToolbarProps> = ({\n onZoomToFit,\n onResetCamera,\n onRefresh,\n loading,\n}) => {\n const { t } = useChatWidgetI18n()\n\n return (\n <div\n style={{\n position: 'absolute',\n right: 16,\n top: 16,\n zIndex: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n }}\n >\n <Space orientation=\"vertical\" size={4}>\n <Tooltip title={t('provenance.toolbar.zoomToFit')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<ExpandOutlined />}\n onClick={onZoomToFit}\n style={toolBtnStyle}\n />\n </Tooltip>\n <Tooltip title={t('provenance.toolbar.resetCamera')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<AimOutlined />}\n onClick={onResetCamera}\n style={toolBtnStyle}\n />\n </Tooltip>\n <Tooltip title={t('provenance.toolbar.refresh')} placement=\"left\">\n <Button\n type=\"text\"\n icon={<ReloadOutlined />}\n onClick={onRefresh}\n loading={loading}\n style={toolBtnStyle}\n />\n </Tooltip>\n </Space>\n </div>\n )\n}\n\nconst toolBtnStyle: React.CSSProperties = {\n background: 'rgba(255,255,255,0.92)',\n backdropFilter: 'blur(8px)',\n boxShadow: '0 1px 4px rgba(0,0,0,0.08)',\n borderRadius: 8,\n width: 36,\n height: 36,\n}\n\nexport const GraphToolbar = React.memo(GraphToolbarInner)\n"],"mappings":"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","names":["import_react","import_antd","import_react","THREE","SpriteText","ForceGraph3D","React","import_react","import_react","import_jsx_runtime","React","import_react","import_antd","import_jsx_runtime","React","import_jsx_runtime","React","import_react","import_jsx_runtime","React","import_react","import_antd","import_jsx_runtime","Text","TYPE_LABEL_KEYS","React","import_react","import_antd","import_jsx_runtime","React"]}