agentfootprint-lens 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -275,12 +275,26 @@ var import_jsx_runtime = require("react/jsx-runtime");
275
275
  function MessagesPanel({
276
276
  timeline,
277
277
  onToolCallClick,
278
- systemPrompt
278
+ systemPrompt,
279
+ selectedIterKey
279
280
  }) {
280
281
  const t = useLensTheme();
282
+ const scrollRef = (0, import_react.useRef)(null);
283
+ (0, import_react.useEffect)(() => {
284
+ if (!selectedIterKey || !scrollRef.current) return;
285
+ const target = scrollRef.current.querySelector(
286
+ `[data-iter-key="${CSS.escape(selectedIterKey)}"]`
287
+ );
288
+ if (!target) return;
289
+ target.scrollIntoView({ block: "start", behavior: "smooth" });
290
+ target.setAttribute("data-iter-selected", "true");
291
+ const h = window.setTimeout(() => target.removeAttribute("data-iter-selected"), 1200);
292
+ return () => window.clearTimeout(h);
293
+ }, [selectedIterKey]);
281
294
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
282
295
  "div",
283
296
  {
297
+ ref: scrollRef,
284
298
  "data-fp-lens": "messages-panel",
285
299
  style: {
286
300
  display: "flex",
@@ -367,7 +381,15 @@ function TurnBlock({
367
381
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
368
382
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TurnHeader, { turn }),
369
383
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserBubble, { text: turn.userPrompt }),
370
- turn.iterations.map((iter) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IterationBlock, { iter, onToolCallClick }, iter.index)),
384
+ turn.iterations.map((iter) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
385
+ IterationBlock,
386
+ {
387
+ iter,
388
+ turnIndex: turn.index,
389
+ onToolCallClick
390
+ },
391
+ iter.index
392
+ )),
371
393
  turn.finalContent && turn.iterations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { fontSize: 11, color: t.textSubtle, textAlign: "center" }, children: [
372
394
  "turn ",
373
395
  turn.index + 1,
@@ -429,27 +451,51 @@ function UserBubble({ text }) {
429
451
  }
430
452
  function IterationBlock({
431
453
  iter,
454
+ turnIndex,
432
455
  onToolCallClick
433
456
  }) {
434
457
  const t = useLensTheme();
435
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
436
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IterationBadge, { iter }),
437
- iter.assistantContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
438
- "div",
439
- {
440
- style: {
441
- background: t.bgElev,
442
- border: `1px solid ${t.border}`,
443
- borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,
444
- padding: "10px 14px",
445
- maxWidth: 820,
446
- whiteSpace: "pre-wrap"
447
- },
448
- children: iter.assistantContent
449
- }
450
- ),
451
- iter.toolCalls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, paddingLeft: 12 }, children: iter.toolCalls.map((tc) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolCallCard, { invocation: tc, onClick: onToolCallClick }, tc.id)) })
452
- ] });
458
+ const key = `${turnIndex}.${iter.index}`;
459
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
460
+ "div",
461
+ {
462
+ "data-iter-key": key,
463
+ "data-turn-index": turnIndex,
464
+ "data-iter-index": iter.index,
465
+ style: {
466
+ display: "flex",
467
+ flexDirection: "column",
468
+ gap: 6,
469
+ // When the parent adds data-iter-selected (via IterationStrip
470
+ // click), pulse a soft ring using the accent color. Subtle so
471
+ // the chat itself stays readable.
472
+ padding: 8,
473
+ margin: -8,
474
+ borderRadius: t.radius,
475
+ outline: "2px solid transparent",
476
+ outlineOffset: 2,
477
+ transition: "outline-color 180ms ease, background 180ms ease"
478
+ },
479
+ children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IterationBadge, { iter }),
481
+ iter.assistantContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
482
+ "div",
483
+ {
484
+ style: {
485
+ background: t.bgElev,
486
+ border: `1px solid ${t.border}`,
487
+ borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,
488
+ padding: "10px 14px",
489
+ maxWidth: 820,
490
+ whiteSpace: "pre-wrap"
491
+ },
492
+ children: iter.assistantContent
493
+ }
494
+ ),
495
+ iter.toolCalls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6, paddingLeft: 12 }, children: iter.toolCalls.map((tc) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolCallCard, { invocation: tc, onClick: onToolCallClick }, tc.id)) })
496
+ ]
497
+ }
498
+ );
453
499
  }
454
500
  function IterationBadge({ iter }) {
455
501
  const t = useLensTheme();
@@ -884,6 +930,12 @@ function AgentLens({
884
930
  fontFamily: t.fontSans
885
931
  },
886
932
  children: [
933
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: `
934
+ [data-iter-selected="true"] {
935
+ outline-color: currentColor !important;
936
+ background: color-mix(in srgb, currentColor 8%, transparent);
937
+ }
938
+ ` }),
887
939
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { gridArea: "strip" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
888
940
  IterationStrip,
889
941
  {
@@ -897,6 +949,7 @@ function AgentLens({
897
949
  {
898
950
  timeline,
899
951
  onToolCallClick: handleToolClick,
952
+ selectedIterKey,
900
953
  ...derivedSystemPrompt && { systemPrompt: derivedSystemPrompt }
901
954
  }
902
955
  ) }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AgentLens.tsx","../src/adapters/fromAgentSnapshot.ts","../src/panels/MessagesPanel.tsx","../src/theme/useLensTheme.ts","../src/panels/IterationStrip.tsx","../src/panels/ToolCallInspector.tsx","../src/adapters/LiveTimelineBuilder.ts","../src/adapters/useLiveTimeline.ts"],"sourcesContent":["/**\n * agentfootprint-lens — public entry.\n *\n * See through your agent's decisions: messages, prompts, tool calls,\n * decision scope, cost — all in one timeline.\n */\n\n// Top-level shell — the 99% consumer entry point.\nexport { AgentLens } from \"./AgentLens\";\nexport type { AgentLensProps } from \"./AgentLens\";\n\n// Individual panels — for consumers who want to compose their own layout.\nexport { MessagesPanel } from \"./panels/MessagesPanel\";\nexport type { MessagesPanelProps } from \"./panels/MessagesPanel\";\nexport { IterationStrip } from \"./panels/IterationStrip\";\nexport type { IterationStripProps } from \"./panels/IterationStrip\";\nexport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nexport type { ToolCallInspectorProps } from \"./panels/ToolCallInspector\";\n\n// Primary path: collect during traversal via the builder/hook. This is\n// the footprintjs-idiomatic approach — ingest emit events as they fire,\n// build the AgentTimeline incrementally, live-update the UI mid-run.\nexport { LiveTimelineBuilder } from \"./adapters/LiveTimelineBuilder\";\nexport { useLiveTimeline } from \"./adapters/useLiveTimeline\";\nexport type { UseLiveTimelineResult } from \"./adapters/useLiveTimeline\";\n\n// Fallback path: parse a completed snapshot (e.g. an imported trace, or\n// a run that finished before Lens was wired up). Still useful — but the\n// live path is preferred for in-app debugging because it respects the\n// \"no post-process\" principle (every field is written once, when its\n// source event fires during traversal).\nexport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\n\nexport type {\n AgentTimeline,\n AgentTurn,\n AgentIteration,\n AgentMessage,\n AgentToolInvocation,\n AgentToolCallStub,\n} from \"./adapters/types\";\n\n// Theme — the resolved palette the panels render against.\n// Consumers shouldn't need to use this directly; it's available for\n// custom panel authors who want to match the Lens look.\nexport { useLensTheme, resolve as resolveLensTheme } from \"./theme/useLensTheme\";\nexport type { LensTheme } from \"./theme/useLensTheme\";\n","/**\n * <AgentLens> — top-level shell.\n *\n * Composes the three v0.1 surfaces: IterationStrip (top), MessagesPanel\n * (center, primary), ToolCallInspector (right sidebar). Selection state\n * is internal; parent apps can hook into `onToolCallClick` to drive\n * external drill-downs (e.g. open a footprint-explainable-ui drawer\n * scoped to the tool's flowchart execution).\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Usage (zero-boilerplate):\n *\n * import { AgentLens } from 'agentfootprint-lens';\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n *\n * <FootprintTheme tokens={dark ? coolDark : coolLight}>\n * <AgentLens runtimeSnapshot={agent.getSnapshot()} />\n * </FootprintTheme>\n *\n * No Lens-specific theme prop — tokens flow from the standard\n * FootprintTheme context. The drill-in drawer (explainable-ui) reads\n * the same context, so chat + trace stay in sync when the consumer\n * flips themes.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useMemo, useState } from \"react\";\nimport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\nimport type {\n AgentToolInvocation,\n AgentTimeline,\n} from \"./adapters/types\";\nimport { MessagesPanel } from \"./panels/MessagesPanel\";\nimport { IterationStrip } from \"./panels/IterationStrip\";\nimport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nimport { useLensTheme } from \"./theme/useLensTheme\";\n\nexport interface AgentLensProps {\n /**\n * Raw runtimeSnapshot from `agent.getSnapshot()`. Lens parses this\n * into an agent-shaped AgentTimeline internally. Pass `null` when a\n * run hasn't happened yet — Lens renders an empty state.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly runtimeSnapshot?: any | null;\n /**\n * Pre-parsed timeline, for callers who want to run the adapter once\n * upstream and share the result. Overrides `runtimeSnapshot` when set.\n */\n readonly timeline?: AgentTimeline;\n /**\n * Optional system prompt to render in the collapsible preamble of\n * MessagesPanel. Usually `runtimeSnapshot.sharedState.systemPrompt`\n * or the agent's configured base prompt.\n */\n readonly systemPrompt?: string;\n /**\n * Called when the user clicks a tool call in either the Inspector or\n * the inline Messages tool-call card. Parent can use this to open a\n * drawer rendering `<ExplainableShell>` from footprint-explainable-ui\n * scoped to that tool's internal flowchart execution — the\n * composition seam between Lens (agent view) and explainable-ui\n * (tool-internal view).\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function AgentLens({\n runtimeSnapshot,\n timeline: providedTimeline,\n systemPrompt,\n onToolCallClick,\n}: AgentLensProps) {\n const t = useLensTheme();\n const timeline = useMemo<AgentTimeline | null>(() => {\n if (providedTimeline) return providedTimeline;\n if (!runtimeSnapshot) return null;\n return fromAgentSnapshot(runtimeSnapshot);\n }, [providedTimeline, runtimeSnapshot]);\n\n const [selectedToolId, setSelectedToolId] = useState<string | null>(null);\n const [selectedIterKey, setSelectedIterKey] = useState<string | null>(null);\n\n function handleToolClick(inv: AgentToolInvocation) {\n setSelectedToolId(inv.id);\n setSelectedIterKey(`${inv.turnIndex}.${inv.iterationIndex}`);\n onToolCallClick?.(inv);\n }\n\n if (!timeline) {\n return (\n <div\n data-fp-lens=\"empty\"\n style={{\n padding: 32,\n color: t.textMuted,\n fontFamily: t.fontSans,\n textAlign: \"center\",\n background: t.bg,\n }}\n >\n No agent run to show yet. Pass <code>runtimeSnapshot</code> after the agent runs.\n </div>\n );\n }\n\n const derivedSystemPrompt =\n systemPrompt ??\n (typeof timeline.rawSnapshot?.sharedState?.systemPrompt === \"string\"\n ? (timeline.rawSnapshot.sharedState.systemPrompt as string)\n : undefined);\n\n return (\n <div\n data-fp-lens=\"shell\"\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 320px\",\n gridTemplateRows: \"auto 1fr\",\n gridTemplateAreas: '\"strip strip\" \"messages inspector\"',\n height: \"100%\",\n minHeight: 0,\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n }}\n >\n <div style={{ gridArea: \"strip\" }}>\n <IterationStrip\n timeline={timeline}\n selectedKey={selectedIterKey}\n onSelect={setSelectedIterKey}\n />\n </div>\n <div style={{ gridArea: \"messages\", minHeight: 0, overflow: \"hidden\" }}>\n <MessagesPanel\n timeline={timeline}\n onToolCallClick={handleToolClick}\n {...(derivedSystemPrompt && { systemPrompt: derivedSystemPrompt })}\n />\n </div>\n <div\n style={{\n gridArea: \"inspector\",\n minHeight: 0,\n overflow: \"hidden\",\n borderLeft: `1px solid ${t.border}`,\n }}\n >\n <ToolCallInspector\n timeline={timeline}\n selectedId={selectedToolId}\n onSelect={handleToolClick}\n />\n </div>\n </div>\n );\n}\n","/**\n * fromAgentSnapshot — turn an agentfootprint runtimeSnapshot into the\n * agent-shaped AgentTimeline Lens renders against.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * The raw snapshot is flowchart-shaped (stages, commitLog, subflowResults).\n * Lens needs agent-shape: turns[] → iterations[] → {messages, toolCalls,\n * decision, tokens, latency, visibleTools}. That's what this file does.\n *\n * Derivation strategy (all sources already present — no library change\n * needed):\n * • `sharedState.messages[]` — canonical conversation\n * • `commitLog` entries for `call-llm` / `streaming-call-llm` — per-iter\n * LLM request+response (model, tokens, duration, stop reason)\n * • `commitLog` entries for `execute-tool-calls` — per-iter tool outputs\n * and decision updates\n * • `sf-instructions-to-llm` snapshots — matched instruction ids +\n * injection counts per iter\n * • `sf-tools` snapshots — tool list visible to the LLM that iter\n *\n * Turn boundaries are inferred by walking `messages[]` and grouping\n * everything between user messages into one turn. Iteration boundaries\n * are the LLM call events within a turn.\n * ─────────────────────────────────────────────────────────────────────────\n */\n\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySnapshot = any;\n\nexport function fromAgentSnapshot(runtime: AnySnapshot): AgentTimeline {\n const shared = runtime?.sharedState ?? {};\n const rawMessages: RawMessage[] = shared.messages ?? [];\n const messages = rawMessages.map(normalizeMessage);\n\n const commitLog = Array.isArray(runtime?.commitLog) ? runtime.commitLog : [];\n const llmCalls = extractLLMCalls(commitLog);\n const toolExecs = extractToolExecutions(commitLog);\n const instructionEvals = extractInstructionEvals(commitLog);\n const toolResolves = extractToolResolves(commitLog);\n\n const turns = assembleTurns(messages, llmCalls, toolExecs, instructionEvals, toolResolves);\n const allTools = turns.flatMap((t) => t.iterations.flatMap((i) => i.toolCalls));\n\n return {\n turns,\n messages,\n tools: allTools,\n finalDecision: (shared.decision as Record<string, unknown>) ?? {},\n rawSnapshot: runtime,\n };\n}\n\n// ── Normalize ─────────────────────────────────────────────────────────\n\ninterface RawMessage {\n role: string;\n content: string | unknown;\n toolCalls?: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n toolCallId?: string;\n}\n\nfunction normalizeMessage(m: RawMessage): AgentMessage {\n const role = ((): AgentMessage[\"role\"] => {\n if (m.role === \"system\" || m.role === \"user\" || m.role === \"assistant\" || m.role === \"tool\")\n return m.role;\n return \"user\";\n })();\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return {\n role,\n content,\n ...(m.toolCalls?.length ? { toolCalls: m.toolCalls } : {}),\n ...(m.toolCallId ? { toolCallId: m.toolCallId } : {}),\n };\n}\n\n// ── Extract from commitLog ────────────────────────────────────────────\n\ninterface RawCommit {\n stageId?: string;\n stage?: string;\n runtimeStageId?: string;\n updates?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trace?: any;\n}\n\ninterface LLMCall {\n iterationIndex: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCallsRequested: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n}\n\nfunction extractLLMCalls(commitLog: RawCommit[]): LLMCall[] {\n const out: LLMCall[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"call-llm\" && id !== \"streaming-call-llm\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const rawResponse =\n (u[\"adapterRawResponse\"] as Record<string, unknown> | undefined) ??\n (u[\"llmResponse\"] as Record<string, unknown> | undefined);\n const usage = rawResponse?.usage as\n | { inputTokens?: number; outputTokens?: number }\n | undefined;\n out.push({\n iterationIndex: iter,\n model: rawResponse?.model as string | undefined,\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n durationMs: (u[\"callDurationMs\"] as number | undefined) ?? undefined,\n stopReason: rawResponse?.stopReason as string | undefined,\n assistantContent: (rawResponse?.content as string | undefined) ?? \"\",\n toolCallsRequested:\n (rawResponse?.toolCalls as LLMCall[\"toolCallsRequested\"] | undefined) ?? [],\n });\n }\n return out;\n}\n\ninterface ToolExec {\n iterationIndex: number;\n toolCalls: AgentToolInvocation[];\n}\n\nfunction extractToolExecutions(commitLog: RawCommit[]): ToolExec[] {\n const out: ToolExec[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"execute-tool-calls\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n // agentfootprint stores parsed tool calls + their results via\n // tool-start / tool-end emit events + the tool-role messages appended\n // to `messages`. Simplest stable derivation: walk messages right\n // after this commit and collect the tool-result entries.\n // For v0.1 we emit the tool call stubs; full resolution happens at\n // the assembler step where we have both sides in hand.\n const rawCalls = u[\"toolCalls\"] as LLMCall[\"toolCallsRequested\"] | undefined;\n const stubs: AgentToolInvocation[] = (rawCalls ?? []).map((c) => ({\n id: c.id,\n name: c.name,\n arguments: c.arguments ?? {},\n result: \"\", // filled in during assembly\n iterationIndex: iter,\n turnIndex: 0, // reassigned during assembly\n decisionUpdate: u[\"updatedDecision\"] as Record<string, unknown> | undefined,\n }));\n out.push({ iterationIndex: iter, toolCalls: stubs });\n }\n return out;\n}\n\ninterface InstructionEval {\n iterationIndex: number;\n matchedInstructions?: string[];\n promptInjectionCount: number;\n toolInjectionCount: number;\n}\n\nfunction extractInstructionEvals(commitLog: RawCommit[]): InstructionEval[] {\n const out: InstructionEval[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"evaluate-instructions\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const matchedRaw = u[\"matchedInstructions\"];\n const matched = parseMatched(matchedRaw);\n const promptInj = Array.isArray(u[\"promptInjections\"]) ? u[\"promptInjections\"].length : 0;\n const toolInj = Array.isArray(u[\"toolInjections\"]) ? u[\"toolInjections\"].length : 0;\n out.push({\n iterationIndex: iter,\n ...(matched.length > 0 && { matchedInstructions: matched }),\n promptInjectionCount: promptInj,\n toolInjectionCount: toolInj,\n });\n }\n return out;\n}\n\nfunction parseMatched(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v.filter((x) => typeof x === \"string\");\n if (typeof v === \"string\") {\n // format: \"N matched: id1, id2, id3...\"\n const m = v.match(/:\\s*(.+)/);\n if (!m) return [];\n return m[1]\n .split(\",\")\n .map((s) => s.trim().replace(/\\.{3}$/, \"\"))\n .filter(Boolean);\n }\n return [];\n}\n\ninterface ToolResolve {\n iterationIndex: number;\n visibleTools: string[];\n}\n\nfunction extractToolResolves(commitLog: RawCommit[]): ToolResolve[] {\n const out: ToolResolve[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"resolve-tools\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const descs = u[\"toolDescriptions\"] as Array<{ name: string }> | undefined;\n out.push({\n iterationIndex: iter,\n visibleTools: (descs ?? []).map((d) => d.name),\n });\n }\n return out;\n}\n\n// ── Assemble turns ────────────────────────────────────────────────────\n\nfunction assembleTurns(\n messages: AgentMessage[],\n llmCalls: LLMCall[],\n toolExecs: ToolExec[],\n instructionEvals: InstructionEval[],\n toolResolves: ToolResolve[],\n): AgentTurn[] {\n // Build a per-iteration map (flat across turns) then split by turn.\n // For a fresh agent instance, iter counts restart every turn — but\n // because commitLog is cumulative, iter numbers across commitLog are\n // monotonically increasing over the whole execution. So we group\n // iterations by the message boundary they fall in.\n //\n // Algorithm: walk messages in order. Each user message starts a new\n // turn. Each assistant message that has toolCalls (or is the final)\n // consumes the next LLM call from llmCalls. Tool-role messages that\n // follow bind to the most recent assistant message's toolCalls.\n\n const turns: AgentTurn[] = [];\n let currentTurn: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n } | null = null;\n let llmIdx = 0;\n const toolExecByIter = new Map(toolExecs.map((t) => [t.iterationIndex, t]));\n const instrByIter = new Map(instructionEvals.map((i) => [i.iterationIndex, i]));\n const visibleByIter = new Map(toolResolves.map((t) => [t.iterationIndex, t]));\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n currentTurn = {\n index: turns.length,\n userPrompt: msg.content,\n iterations: [],\n finalContent: \"\",\n };\n continue;\n }\n if (!currentTurn) continue; // skip system prompt + anything before first user\n\n if (msg.role === \"assistant\") {\n const call = llmCalls[llmIdx];\n llmIdx++;\n const iterIndex = call?.iterationIndex ?? currentTurn.iterations.length + 1;\n const exec = toolExecByIter.get(iterIndex);\n const instr = instrByIter.get(iterIndex);\n const visible = visibleByIter.get(iterIndex);\n\n const toolCalls: AgentToolInvocation[] = (exec?.toolCalls ?? []).map((tc) => ({\n ...tc,\n turnIndex: currentTurn!.index,\n }));\n\n const iteration: AgentIteration = {\n index: iterIndex,\n ...(call?.model && { model: call.model }),\n ...(call?.inputTokens !== undefined && { inputTokens: call.inputTokens }),\n ...(call?.outputTokens !== undefined && { outputTokens: call.outputTokens }),\n ...(call?.durationMs !== undefined && { durationMs: call.durationMs }),\n ...(call?.stopReason && { stopReason: call.stopReason }),\n assistantContent: call?.assistantContent ?? msg.content,\n toolCalls,\n decisionAtStart: {}, // TODO(phase-2): derive from pre-iter commit\n ...(instr?.matchedInstructions && { matchedInstructions: instr.matchedInstructions }),\n visibleTools: visible?.visibleTools ?? [],\n };\n\n currentTurn.iterations.push(iteration);\n if (!toolCalls.length) currentTurn.finalContent = iteration.assistantContent;\n continue;\n }\n\n if (msg.role === \"tool\" && msg.toolCallId) {\n // Bind the result string back to the matching tool invocation in\n // the latest iteration.\n const iter = currentTurn.iterations[currentTurn.iterations.length - 1];\n if (!iter) continue;\n const idx = iter.toolCalls.findIndex((tc) => tc.id === msg.toolCallId);\n if (idx < 0) continue;\n const updated = { ...iter.toolCalls[idx], result: msg.content };\n // Rewrite via mutation — iter is readonly at the type level but we\n // own this intermediate structure during assembly.\n (iter.toolCalls as AgentToolInvocation[])[idx] = updated;\n }\n }\n\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n return turns;\n}\n\nfunction finalizeTurn(t: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n}): AgentTurn {\n const totalInputTokens = t.iterations.reduce((s, i) => s + (i.inputTokens ?? 0), 0);\n const totalOutputTokens = t.iterations.reduce((s, i) => s + (i.outputTokens ?? 0), 0);\n const totalDurationMs = t.iterations.reduce((s, i) => s + (i.durationMs ?? 0), 0);\n return {\n index: t.index,\n userPrompt: t.userPrompt,\n iterations: t.iterations,\n finalContent: t.finalContent,\n totalInputTokens,\n totalOutputTokens,\n totalDurationMs,\n };\n}\n","/**\n * MessagesPanel — the primary Lens surface. Chat-shaped view of an agent\n * run with turn boundaries, iteration markers, and expandable tool calls.\n *\n * Data comes from `fromAgentSnapshot(runtimeSnapshot).turns`. Each turn\n * is:\n * • one user message\n * • one or more assistant iterations (each may request N tool calls)\n * • tool role bubbles bound to their assistant parent\n * • final assistant bubble\n *\n * Theme is read via `useLensTheme()` which maps FootprintTheme tokens\n * into Lens's semantic palette. Consumers get free light/dark support\n * by wrapping their app in `<FootprintTheme tokens={coolLight|coolDark}>`\n * — no Lens-specific theme API to learn.\n */\nimport { useState } from \"react\";\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface MessagesPanelProps {\n readonly timeline: AgentTimeline;\n /**\n * Called when the user clicks a tool-call card. Host app surfaces it\n * in the Tool Call Inspector. When omitted, clicking is a no-op.\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n /** Optional system-prompt text to render in the collapsible preamble. */\n readonly systemPrompt?: string;\n}\n\nexport function MessagesPanel({\n timeline,\n onToolCallClick,\n systemPrompt,\n}: MessagesPanelProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"messages-panel\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n padding: \"16px 24px\",\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n fontSize: 14,\n lineHeight: 1.55,\n minHeight: 0,\n overflow: \"auto\",\n }}\n >\n {systemPrompt && <SystemBubble text={systemPrompt} />}\n {timeline.turns.map((turn) => (\n <TurnBlock key={turn.index} turn={turn} onToolCallClick={onToolCallClick} />\n ))}\n </div>\n );\n}\n\nfunction SystemBubble({ text }: { text: string }) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = text.slice(0, 140).replace(/\\s+/g, \" \") + (text.length > 140 ? \"…\" : \"\");\n return (\n <div\n style={{\n alignSelf: \"center\",\n width: \"100%\",\n maxWidth: 880,\n border: `1px dashed ${t.border}`,\n borderRadius: t.radius,\n padding: \"8px 12px\",\n background: t.bgElev,\n fontSize: 12,\n color: t.textMuted,\n }}\n >\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: t.textMuted,\n cursor: \"pointer\",\n padding: 0,\n font: \"inherit\",\n }}\n >\n <strong>SYSTEM</strong> {open ? \"▾\" : \"▸\"} {open ? \"\" : preview}\n </button>\n {open && (\n <pre\n style={{\n marginTop: 8,\n whiteSpace: \"pre-wrap\",\n fontFamily: t.fontMono,\n fontSize: 11,\n color: t.text,\n }}\n >\n {text}\n </pre>\n )}\n </div>\n );\n}\n\nfunction TurnBlock({\n turn,\n onToolCallClick,\n}: {\n turn: AgentTurn;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <TurnHeader turn={turn} />\n <UserBubble text={turn.userPrompt} />\n {turn.iterations.map((iter) => (\n <IterationBlock key={iter.index} iter={iter} onToolCallClick={onToolCallClick} />\n ))}\n {turn.finalContent && turn.iterations.length > 0 && (\n <div style={{ fontSize: 11, color: t.textSubtle, textAlign: \"center\" }}>\n turn {turn.index + 1} final · {turn.iterations.length} iter · {turn.totalInputTokens}→\n {turn.totalOutputTokens} tok · {(turn.totalDurationMs / 1000).toFixed(1)}s\n </div>\n )}\n </div>\n );\n}\n\nfunction TurnHeader({ turn }: { turn: AgentTurn }) {\n const t = useLensTheme();\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n color: t.textSubtle,\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n }}\n >\n <div style={{ flex: 1, height: 1, background: t.border }} />\n <span>Turn {turn.index + 1}</span>\n <div style={{ flex: 1, height: 1, background: t.border }} />\n </div>\n );\n}\n\nfunction UserBubble({ text }: { text: string }) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <div\n style={{\n background: `color-mix(in srgb, ${t.accent} 18%, ${t.bgElev})`,\n border: `1px solid ${t.border}`,\n color: t.text,\n maxWidth: 720,\n padding: \"10px 14px\",\n borderRadius: `${t.radius} ${t.radius} 2px ${t.radius}`,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {text}\n </div>\n </div>\n );\n}\n\nfunction IterationBlock({\n iter,\n onToolCallClick,\n}: {\n iter: AgentIteration;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <IterationBadge iter={iter} />\n {iter.assistantContent && (\n <div\n style={{\n background: t.bgElev,\n border: `1px solid ${t.border}`,\n borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,\n padding: \"10px 14px\",\n maxWidth: 820,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {iter.assistantContent}\n </div>\n )}\n {iter.toolCalls.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, paddingLeft: 12 }}>\n {iter.toolCalls.map((tc) => (\n <ToolCallCard key={tc.id} invocation={tc} onClick={onToolCallClick} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction IterationBadge({ iter }: { iter: AgentIteration }) {\n const t = useLensTheme();\n const bits: string[] = [`iter ${iter.index}`];\n if (iter.model) bits.push(iter.model);\n if (iter.inputTokens !== undefined)\n bits.push(`${iter.inputTokens}→${iter.outputTokens ?? \"?\"} tok`);\n if (iter.durationMs !== undefined) bits.push(`${(iter.durationMs / 1000).toFixed(2)}s`);\n if (iter.stopReason) bits.push(iter.stopReason);\n return (\n <div\n style={{\n alignSelf: \"flex-start\",\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n fontFamily: t.fontMono,\n }}\n >\n {bits.join(\" · \")}\n </div>\n );\n}\n\nfunction ToolCallCard({\n invocation,\n onClick,\n}: {\n invocation: AgentToolInvocation;\n onClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = shortArgs(invocation.arguments);\n const errored = invocation.error === true;\n return (\n <div\n style={{\n border: `1px solid ${errored ? t.error : t.border}`,\n borderLeft: `3px solid ${errored ? t.error : t.accent}`,\n borderRadius: 6,\n background: t.bg,\n overflow: \"hidden\",\n }}\n >\n <div\n onClick={() => {\n setOpen((v) => !v);\n onClick?.(invocation);\n }}\n style={{\n padding: \"8px 12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {invocation.name}\n </span>\n <span style={{ color: t.textMuted }}>({preview})</span>\n <span style={{ flex: 1 }} />\n {invocation.decisionUpdate && Object.keys(invocation.decisionUpdate).length > 0 && (\n <span\n style={{\n fontSize: 10,\n padding: \"1px 6px\",\n borderRadius: 3,\n background: `color-mix(in srgb, ${t.warning} 20%, transparent)`,\n color: t.warning,\n fontFamily: t.fontSans,\n fontWeight: 600,\n textTransform: \"uppercase\",\n }}\n >\n decisionUpdate\n </span>\n )}\n <span style={{ color: t.textSubtle }}>{open ? \"▾\" : \"▸\"}</span>\n </div>\n {open && (\n <div style={{ padding: \"8px 12px\", borderTop: `1px solid ${t.border}` }}>\n <Label t={t}>args</Label>\n <JsonBlock value={invocation.arguments} />\n {invocation.result && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n result\n </Label>\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: errored ? t.error : t.text,\n maxHeight: 280,\n overflow: \"auto\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {invocation.result}\n </pre>\n </>\n )}\n {invocation.decisionUpdate &&\n Object.keys(invocation.decisionUpdate).length > 0 && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n decisionUpdate\n </Label>\n <JsonBlock value={invocation.decisionUpdate} />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction Label({\n t,\n children,\n style,\n}: {\n t: ReturnType<typeof useLensTheme>;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) {\n return (\n <div\n style={{\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n marginBottom: 4,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction JsonBlock({ value }: { value: unknown }) {\n const t = useLensTheme();\n return (\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: t.text,\n maxHeight: 200,\n overflow: \"auto\",\n }}\n >\n {JSON.stringify(value, null, 2)}\n </pre>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"\";\n if (keys.length === 1) {\n const v = args[keys[0]];\n if (typeof v === \"string\" && v.length < 40) return `${keys[0]}: \"${v}\"`;\n }\n return keys.join(\", \");\n}\n\nexport { ToolCallCard };\n\nfunction _assertUnused(_: AgentMessage) {\n // Exported type is referenced from ./index.ts; keeping the import\n // for bundler tree-shaking consistency without introducing a new\n // linter warning on a \"used-elsewhere\" type import.\n void _;\n}\n_assertUnused;\n","/**\n * useLensTheme — single source of truth for Lens colors + sizing.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Theme pass-through contract (IMPORTANT for consumers):\n *\n * Lens does NOT invent its own theme system. It reads tokens from the\n * FootprintTheme context already defined in `footprint-explainable-ui`.\n * A consumer app that wraps its tree in:\n *\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n * <FootprintTheme tokens={theme === 'light' ? coolLight : coolDark}>\n * <AgentLens runtimeSnapshot={snap} />\n * </FootprintTheme>\n *\n * …gets both Lens AND the drill-down explainable-ui drawer themed from the\n * same token bag. No separate `theme` prop, no duplicate palette, no\n * drift between the two views when the user flips light/dark.\n *\n * If no FootprintTheme provider is mounted, Lens falls back to cool-dark\n * defaults — the same defaults explainable-ui uses, so it looks correct\n * out of the box without configuration.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useFootprintTheme, coolDark } from \"footprint-explainable-ui\";\nimport type { ThemeTokens } from \"footprint-explainable-ui\";\n\n/**\n * The resolved color palette + sizing tokens Lens renders against.\n * Always defined — callers never need to null-check.\n */\nexport interface LensTheme {\n readonly bg: string;\n readonly bgElev: string;\n readonly bgHover: string;\n readonly border: string;\n readonly borderStrong: string;\n readonly text: string;\n readonly textMuted: string;\n readonly textSubtle: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly error: string;\n readonly fontSans: string;\n readonly fontMono: string;\n readonly radius: string;\n}\n\n/**\n * Read tokens from FootprintTheme context (if present) and map them\n * into Lens's semantic palette. Missing tokens fall back to coolDark.\n */\nexport function useLensTheme(): LensTheme {\n const ctx = useFootprintTheme();\n return resolve(ctx);\n}\n\n/** Pure mapping — exported for unit tests + non-hook call sites. */\nexport function resolve(tokens: ThemeTokens | undefined): LensTheme {\n const t = tokens ?? {};\n const c = t.colors ?? coolDark.colors ?? {};\n const fallback = coolDark.colors ?? {};\n return {\n bg: c.bgPrimary ?? fallback.bgPrimary ?? \"#0f172a\",\n bgElev: c.bgSecondary ?? fallback.bgSecondary ?? \"#1e293b\",\n bgHover: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n border: c.border ?? fallback.border ?? \"#334155\",\n borderStrong: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n text: c.textPrimary ?? fallback.textPrimary ?? \"#f8fafc\",\n textMuted: c.textSecondary ?? fallback.textSecondary ?? \"#94a3b8\",\n textSubtle: c.textMuted ?? fallback.textMuted ?? \"#64748b\",\n accent: c.primary ?? fallback.primary ?? \"#6366f1\",\n success: c.success ?? fallback.success ?? \"#22c55e\",\n warning: c.warning ?? fallback.warning ?? \"#f59e0b\",\n error: c.error ?? fallback.error ?? \"#ef4444\",\n fontSans: t.fontFamily?.sans ?? coolDark.fontFamily?.sans ?? \"system-ui, sans-serif\",\n fontMono: t.fontFamily?.mono ?? coolDark.fontFamily?.mono ?? \"ui-monospace, monospace\",\n radius: t.radius ?? coolDark.radius ?? \"8px\",\n };\n}\n","/**\n * IterationStrip — horizontal ribbon of LLM calls across the run, one\n * chip per iteration. Click to scroll/pin MessagesPanel to that iter.\n *\n * v0.1 is display-only with the selection callback; parent app owns the\n * scroll behavior.\n */\nimport type { AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface IterationStripProps {\n readonly timeline: AgentTimeline;\n readonly selectedKey?: string | null;\n readonly onSelect?: (key: string) => void;\n}\n\nexport function IterationStrip({ timeline, selectedKey, onSelect }: IterationStripProps) {\n const t = useLensTheme();\n const chips = timeline.turns.flatMap((turn) =>\n turn.iterations.map((iter) => ({\n key: `${turn.index}.${iter.index}`,\n turn: turn.index + 1,\n iter: iter.index,\n label: chipLabel(iter),\n tools: iter.toolCalls.length,\n durationMs: iter.durationMs ?? 0,\n stopReason: iter.stopReason,\n })),\n );\n\n return (\n <div\n data-fp-lens=\"iteration-strip\"\n style={{\n display: \"flex\",\n gap: 4,\n padding: \"8px 12px\",\n overflowX: \"auto\",\n borderBottom: `1px solid ${t.border}`,\n background: t.bgElev,\n }}\n >\n {chips.length === 0 && (\n <span style={{ color: t.textSubtle, fontSize: 11 }}>No iterations yet.</span>\n )}\n {chips.map((c) => {\n const active = c.key === selectedKey;\n const isFinal = c.stopReason === \"stop\" || c.stopReason === \"end_turn\";\n return (\n <button\n key={c.key}\n onClick={() => onSelect?.(c.key)}\n style={{\n background: active ? t.accent : \"transparent\",\n color: active ? \"#fff\" : t.textMuted,\n border: `1px solid ${active ? t.accent : t.border}`,\n borderRadius: 4,\n padding: \"4px 8px\",\n fontSize: 11,\n fontFamily: \"ui-monospace, monospace\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n title={`turn ${c.turn} · iter ${c.iter} · ${c.tools} tool call${\n c.tools === 1 ? \"\" : \"s\"\n }${c.stopReason ? ` · ${c.stopReason}` : \"\"}`}\n >\n t{c.turn}.i{c.iter} · {c.label} {isFinal ? \"✓\" : \"\"}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction chipLabel(iter: { toolCalls: readonly unknown[]; durationMs?: number }): string {\n const d = iter.durationMs ?? 0;\n const secs = d >= 1000 ? `${(d / 1000).toFixed(1)}s` : `${Math.round(d)}ms`;\n const toolBit = iter.toolCalls.length > 0 ? `${iter.toolCalls.length}t` : \"final\";\n return `${secs} · ${toolBit}`;\n}\n","/**\n * ToolCallInspector — flat sidebar list of every tool invocation in the\n * run. Primary workflow: skim for errors, click to focus a specific\n * call (mirrors MessagesPanel's selection).\n *\n * v0.1 minimum — name, args preview, latency, error badge. Drill-in to\n * the tool's underlying footprintjs flowchart via explainable-ui is a\n * phase-2 item (requires surfacing per-tool sub-snapshots).\n */\nimport type { AgentToolInvocation, AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface ToolCallInspectorProps {\n readonly timeline: AgentTimeline;\n readonly selectedId?: string | null;\n readonly onSelect?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function ToolCallInspector({\n timeline,\n selectedId,\n onSelect,\n}: ToolCallInspectorProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"tool-call-inspector\"\n style={{\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n display: \"flex\",\n flexDirection: \"column\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"10px 14px\",\n borderBottom: `1px solid ${t.border}`,\n fontSize: 11,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n background: t.bgElev,\n }}\n >\n Tool calls · {timeline.tools.length}\n </div>\n <div style={{ overflow: \"auto\", flex: 1 }}>\n {timeline.tools.length === 0 && (\n <div style={{ padding: 14, color: t.textSubtle, fontSize: 12 }}>\n No tool calls yet.\n </div>\n )}\n {timeline.tools.map((tc) => {\n const active = tc.id === selectedId;\n const errored = tc.error === true;\n return (\n <button\n key={tc.id}\n onClick={() => onSelect?.(tc)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n textAlign: \"left\",\n padding: \"8px 12px\",\n background: active ? t.bgHover : \"transparent\",\n border: \"none\",\n borderLeft: `3px solid ${\n active ? t.accent : errored ? t.error : \"transparent\"\n }`,\n borderBottom: `1px solid ${t.border}`,\n color: t.text,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: 8,\n alignItems: \"baseline\",\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {tc.name}\n </span>\n <span\n style={{ color: t.textSubtle, fontSize: 10, marginLeft: \"auto\" }}\n >\n t{tc.turnIndex + 1}.i{tc.iterationIndex}\n {tc.durationMs !== undefined && ` · ${Math.round(tc.durationMs)}ms`}\n </span>\n </div>\n <div\n style={{\n fontSize: 10,\n color: t.textMuted,\n marginTop: 2,\n fontFamily: t.fontMono,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {shortArgs(tc.arguments)}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"— no args —\";\n return keys\n .map((k) => {\n const v = args[k];\n if (typeof v === \"string\") return `${k}: \"${v.length > 20 ? v.slice(0, 20) + \"…\" : v}\"`;\n if (typeof v === \"number\" || typeof v === \"boolean\") return `${k}: ${v}`;\n return `${k}: …`;\n })\n .join(\", \");\n}\n","/**\n * LiveTimelineBuilder — ingests agentfootprint emit events AS THEY HAPPEN\n * and accumulates the `AgentTimeline` incrementally. Zero post-processing:\n * every field is set as the corresponding event fires during traversal.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Why this exists\n *\n * footprintjs's core principle: \"collect during traversal, never post-\n * process.\" Walking `commitLog` after the run to reconstruct the agent\n * view is valid but it re-traverses data that already flowed past. The\n * Builder is the correct shape — it's a recorder that subscribes to the\n * stream of events the agent already emits and writes each field exactly\n * once, when the source-of-truth event fires.\n *\n * Consumer wiring (from a React app):\n *\n * const builder = useMemo(() => new LiveTimelineBuilder(), []);\n * const [timeline, setTimeline] = useState(builder.getTimeline());\n * // In Neo's runTurn onEvent:\n * await agent.run(prompt, {\n * onEvent: (e) => {\n * builder.ingest(e);\n * setTimeline(builder.getTimeline());\n * },\n * });\n * <AgentLens timeline={timeline} />\n *\n * Or via the `useLiveTimeline()` React hook below — same mechanics, less\n * boilerplate.\n *\n * The events consumed are all `agentfootprint.stream.*` (llm_start,\n * llm_end, tool_start, tool_end) + `agentfootprint.agent.turn_complete`.\n * User messages are captured by calling `startTurn(userPrompt)` before\n * each `agent.run()` invocation — that's the one piece the event stream\n * doesn't carry (agent.run() is where the user message enters the\n * system, not an event emission).\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// Minimal shape we need from an agent event — structural only, no direct\n// dep on agentfootprint's event type (which may evolve).\ninterface AgentEventLike {\n readonly type: string;\n readonly toolName?: string;\n readonly toolCallId?: string;\n readonly args?: Record<string, unknown>;\n readonly result?: { content?: string; error?: boolean } | string;\n readonly iteration?: number;\n readonly content?: string;\n readonly toolCallCount?: number;\n readonly model?: string;\n readonly usage?: { inputTokens?: number; outputTokens?: number };\n readonly stopReason?: string;\n readonly durationMs?: number;\n readonly iterations?: number;\n readonly reason?: string;\n}\n\ninterface MutableTurn {\n index: number;\n userPrompt: string;\n iterations: MutableIteration[];\n finalContent: string;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalDurationMs: number;\n startMs: number;\n}\n\ninterface MutableIteration {\n index: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCalls: MutableTool[];\n decisionAtStart: Record<string, unknown>;\n matchedInstructions?: string[];\n visibleTools: string[];\n startMs: number;\n}\n\ninterface MutableTool {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result: string;\n error?: boolean;\n decisionUpdate?: Record<string, unknown>;\n iterationIndex: number;\n turnIndex: number;\n durationMs?: number;\n startMs: number;\n}\n\nexport class LiveTimelineBuilder {\n private turns: MutableTurn[] = [];\n private currentTurn: MutableTurn | null = null;\n private currentIter: MutableIteration | null = null;\n private toolByCallId = new Map<string, MutableTool>();\n private messages: AgentMessage[] = [];\n private systemPrompt: string | undefined;\n private finalDecision: Record<string, unknown> = {};\n\n /**\n * Begin a new turn. Call this BEFORE `agent.run(userPrompt)` so the\n * user's prompt appears alongside the iterations it produced. Safe to\n * call even mid-conversation — it closes the previous turn cleanly.\n */\n startTurn(userPrompt: string): void {\n if (this.currentTurn) this.commitCurrentTurn();\n this.currentTurn = {\n index: this.turns.length,\n userPrompt,\n iterations: [],\n finalContent: \"\",\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalDurationMs: 0,\n startMs: Date.now(),\n };\n this.messages.push({ role: \"user\", content: userPrompt });\n }\n\n /**\n * Optional — attach the system prompt so MessagesPanel can render it\n * in the collapsible preamble. Usually set once at agent construction.\n */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n /**\n * Feed one agent stream event. Safe to call for unknown events; we\n * ignore anything we don't recognize.\n */\n ingest(event: AgentEventLike | unknown): void {\n const e = event as AgentEventLike;\n if (!e || typeof e.type !== \"string\") return;\n switch (e.type) {\n case \"llm_start\":\n case \"agentfootprint.stream.llm_start\":\n this.onLLMStart(e);\n return;\n case \"llm_end\":\n case \"agentfootprint.stream.llm_end\":\n this.onLLMEnd(e);\n return;\n case \"tool_start\":\n case \"agentfootprint.stream.tool_start\":\n this.onToolStart(e);\n return;\n case \"tool_end\":\n case \"agentfootprint.stream.tool_end\":\n this.onToolEnd(e);\n return;\n case \"turn_end\":\n case \"agentfootprint.agent.turn_complete\":\n this.commitCurrentTurn();\n return;\n default:\n return;\n }\n }\n\n private onLLMStart(e: AgentEventLike): void {\n if (!this.currentTurn) return;\n const iterNum = e.iteration ?? this.currentTurn.iterations.length + 1;\n this.currentIter = {\n index: iterNum,\n assistantContent: \"\",\n toolCalls: [],\n decisionAtStart: {},\n visibleTools: [],\n startMs: Date.now(),\n };\n this.currentTurn.iterations.push(this.currentIter);\n }\n\n private onLLMEnd(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n this.currentIter.assistantContent = e.content ?? this.currentIter.assistantContent;\n if (e.model) this.currentIter.model = e.model;\n if (e.usage?.inputTokens !== undefined) this.currentIter.inputTokens = e.usage.inputTokens;\n if (e.usage?.outputTokens !== undefined) this.currentIter.outputTokens = e.usage.outputTokens;\n if (e.stopReason) this.currentIter.stopReason = e.stopReason;\n this.currentIter.durationMs = e.durationMs ?? Date.now() - this.currentIter.startMs;\n\n // Aggregate into turn totals.\n this.currentTurn.totalInputTokens += this.currentIter.inputTokens ?? 0;\n this.currentTurn.totalOutputTokens += this.currentIter.outputTokens ?? 0;\n this.currentTurn.totalDurationMs += this.currentIter.durationMs ?? 0;\n\n // Assistant message for the chat view.\n if (this.currentIter.assistantContent) {\n this.messages.push({ role: \"assistant\", content: this.currentIter.assistantContent });\n }\n // If no tool calls follow, this iteration's content IS the turn's final answer.\n if ((e.toolCallCount ?? 0) === 0) {\n this.currentTurn.finalContent = this.currentIter.assistantContent;\n }\n }\n\n private onToolStart(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n const tool: MutableTool = {\n id: e.toolCallId ?? `tool-${this.currentIter.toolCalls.length}`,\n name: e.toolName ?? \"unknown\",\n arguments: e.args ?? {},\n result: \"\",\n iterationIndex: this.currentIter.index,\n turnIndex: this.currentTurn.index,\n startMs: Date.now(),\n };\n this.currentIter.toolCalls.push(tool);\n this.toolByCallId.set(tool.id, tool);\n }\n\n private onToolEnd(e: AgentEventLike): void {\n const tool = this.toolByCallId.get(e.toolCallId ?? \"\");\n if (!tool) return;\n const r = e.result;\n if (typeof r === \"string\") {\n tool.result = r;\n } else if (r && typeof r === \"object\") {\n tool.result = r.content ?? \"\";\n if (r.error === true) tool.error = true;\n }\n tool.durationMs = e.durationMs ?? Date.now() - tool.startMs;\n // Record the tool-role message so MessagesPanel can render it.\n this.messages.push({ role: \"tool\", content: tool.result, toolCallId: tool.id });\n }\n\n private commitCurrentTurn(): void {\n if (!this.currentTurn) return;\n this.turns.push(this.currentTurn);\n this.currentTurn = null;\n this.currentIter = null;\n }\n\n /**\n * Snapshot the current state as an immutable `AgentTimeline`. Safe to\n * call at any point — mid-run gives you the partial state so Lens can\n * live-update.\n */\n getTimeline(): AgentTimeline {\n const allTurns = [...this.turns];\n if (this.currentTurn) allTurns.push(this.currentTurn);\n const tools: AgentToolInvocation[] = [];\n const frozenTurns: AgentTurn[] = allTurns.map((t) => {\n const iterations: AgentIteration[] = t.iterations.map((i) => {\n const tcs = i.toolCalls.map((tc) => ({ ...tc } as AgentToolInvocation));\n tools.push(...tcs);\n return { ...i, toolCalls: tcs } as AgentIteration;\n });\n return { ...t, iterations } as AgentTurn;\n });\n return {\n turns: frozenTurns,\n messages: [...this.messages],\n tools,\n finalDecision: { ...this.finalDecision },\n rawSnapshot: null,\n };\n }\n\n /**\n * Fold in a final `decision` scope after the run — useful when\n * the consumer wants the Decision Ribbon (phase-2) to reflect the\n * post-run state. Safe no-op during the run itself.\n */\n setFinalDecision(decision: Record<string, unknown>): void {\n this.finalDecision = decision;\n }\n\n /** Get the optional system prompt for the Messages preamble. */\n getSystemPrompt(): string | undefined {\n return this.systemPrompt;\n }\n\n /** Wipe state. Useful when the consumer starts a fresh conversation. */\n reset(): void {\n this.turns = [];\n this.currentTurn = null;\n this.currentIter = null;\n this.toolByCallId.clear();\n this.messages = [];\n this.finalDecision = {};\n }\n}\n","/**\n * useLiveTimeline — React hook wrapper around LiveTimelineBuilder.\n *\n * The hook owns a stable builder across renders and returns:\n * • `timeline` — current state (re-renders on every `ingest` call)\n * • `ingest` — feed an agentfootprint stream event\n * • `startTurn`, `setSystemPrompt`, `setFinalDecision`, `reset` — forward methods\n *\n * Usage:\n *\n * const lens = useLiveTimeline();\n * <AgentLens timeline={lens.timeline} />\n *\n * // Before agent.run():\n * lens.startTurn(userPrompt);\n * await agent.run(userPrompt, { onEvent: lens.ingest });\n *\n * The hook keeps the agent-shaped view in sync AS events fire — Lens\n * updates incrementally during the run, not only after it completes.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { LiveTimelineBuilder } from \"./LiveTimelineBuilder\";\nimport type { AgentTimeline } from \"./types\";\n\nexport interface UseLiveTimelineResult {\n readonly timeline: AgentTimeline;\n readonly ingest: (event: unknown) => void;\n readonly startTurn: (userPrompt: string) => void;\n readonly setSystemPrompt: (prompt: string) => void;\n readonly setFinalDecision: (decision: Record<string, unknown>) => void;\n readonly reset: () => void;\n /** Escape hatch — exposed for integrations that need builder internals. */\n readonly builder: LiveTimelineBuilder;\n}\n\nexport function useLiveTimeline(): UseLiveTimelineResult {\n const builderRef = useRef<LiveTimelineBuilder | null>(null);\n if (!builderRef.current) builderRef.current = new LiveTimelineBuilder();\n const builder = builderRef.current;\n\n const [timeline, setTimeline] = useState<AgentTimeline>(() => builder.getTimeline());\n\n const sync = useCallback(() => {\n setTimeline(builder.getTimeline());\n }, [builder]);\n\n const ingest = useCallback(\n (event: unknown) => {\n builder.ingest(event);\n sync();\n },\n [builder, sync],\n );\n\n const startTurn = useCallback(\n (userPrompt: string) => {\n builder.startTurn(userPrompt);\n sync();\n },\n [builder, sync],\n );\n\n const setSystemPrompt = useCallback(\n (prompt: string) => {\n builder.setSystemPrompt(prompt);\n sync();\n },\n [builder, sync],\n );\n\n const setFinalDecision = useCallback(\n (decision: Record<string, unknown>) => {\n builder.setFinalDecision(decision);\n sync();\n },\n [builder, sync],\n );\n\n const reset = useCallback(() => {\n builder.reset();\n sync();\n }, [builder, sync]);\n\n return useMemo(\n () => ({ timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder }),\n [timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder],\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime","shortArgs","import_jsx_runtime","import_react"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/AgentLens.tsx","../src/adapters/fromAgentSnapshot.ts","../src/panels/MessagesPanel.tsx","../src/theme/useLensTheme.ts","../src/panels/IterationStrip.tsx","../src/panels/ToolCallInspector.tsx","../src/adapters/LiveTimelineBuilder.ts","../src/adapters/useLiveTimeline.ts"],"sourcesContent":["/**\n * agentfootprint-lens — public entry.\n *\n * See through your agent's decisions: messages, prompts, tool calls,\n * decision scope, cost — all in one timeline.\n */\n\n// Top-level shell — the 99% consumer entry point.\nexport { AgentLens } from \"./AgentLens\";\nexport type { AgentLensProps } from \"./AgentLens\";\n\n// Individual panels — for consumers who want to compose their own layout.\nexport { MessagesPanel } from \"./panels/MessagesPanel\";\nexport type { MessagesPanelProps } from \"./panels/MessagesPanel\";\nexport { IterationStrip } from \"./panels/IterationStrip\";\nexport type { IterationStripProps } from \"./panels/IterationStrip\";\nexport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nexport type { ToolCallInspectorProps } from \"./panels/ToolCallInspector\";\n\n// Primary path: collect during traversal via the builder/hook. This is\n// the footprintjs-idiomatic approach — ingest emit events as they fire,\n// build the AgentTimeline incrementally, live-update the UI mid-run.\nexport { LiveTimelineBuilder } from \"./adapters/LiveTimelineBuilder\";\nexport { useLiveTimeline } from \"./adapters/useLiveTimeline\";\nexport type { UseLiveTimelineResult } from \"./adapters/useLiveTimeline\";\n\n// Fallback path: parse a completed snapshot (e.g. an imported trace, or\n// a run that finished before Lens was wired up). Still useful — but the\n// live path is preferred for in-app debugging because it respects the\n// \"no post-process\" principle (every field is written once, when its\n// source event fires during traversal).\nexport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\n\nexport type {\n AgentTimeline,\n AgentTurn,\n AgentIteration,\n AgentMessage,\n AgentToolInvocation,\n AgentToolCallStub,\n} from \"./adapters/types\";\n\n// Theme — the resolved palette the panels render against.\n// Consumers shouldn't need to use this directly; it's available for\n// custom panel authors who want to match the Lens look.\nexport { useLensTheme, resolve as resolveLensTheme } from \"./theme/useLensTheme\";\nexport type { LensTheme } from \"./theme/useLensTheme\";\n","/**\n * <AgentLens> — top-level shell.\n *\n * Composes the three v0.1 surfaces: IterationStrip (top), MessagesPanel\n * (center, primary), ToolCallInspector (right sidebar). Selection state\n * is internal; parent apps can hook into `onToolCallClick` to drive\n * external drill-downs (e.g. open a footprint-explainable-ui drawer\n * scoped to the tool's flowchart execution).\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Usage (zero-boilerplate):\n *\n * import { AgentLens } from 'agentfootprint-lens';\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n *\n * <FootprintTheme tokens={dark ? coolDark : coolLight}>\n * <AgentLens runtimeSnapshot={agent.getSnapshot()} />\n * </FootprintTheme>\n *\n * No Lens-specific theme prop — tokens flow from the standard\n * FootprintTheme context. The drill-in drawer (explainable-ui) reads\n * the same context, so chat + trace stay in sync when the consumer\n * flips themes.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useMemo, useState } from \"react\";\nimport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\nimport type {\n AgentToolInvocation,\n AgentTimeline,\n} from \"./adapters/types\";\nimport { MessagesPanel } from \"./panels/MessagesPanel\";\nimport { IterationStrip } from \"./panels/IterationStrip\";\nimport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nimport { useLensTheme } from \"./theme/useLensTheme\";\n\nexport interface AgentLensProps {\n /**\n * Raw runtimeSnapshot from `agent.getSnapshot()`. Lens parses this\n * into an agent-shaped AgentTimeline internally. Pass `null` when a\n * run hasn't happened yet — Lens renders an empty state.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly runtimeSnapshot?: any | null;\n /**\n * Pre-parsed timeline, for callers who want to run the adapter once\n * upstream and share the result. Overrides `runtimeSnapshot` when set.\n */\n readonly timeline?: AgentTimeline;\n /**\n * Optional system prompt to render in the collapsible preamble of\n * MessagesPanel. Usually `runtimeSnapshot.sharedState.systemPrompt`\n * or the agent's configured base prompt.\n */\n readonly systemPrompt?: string;\n /**\n * Called when the user clicks a tool call in either the Inspector or\n * the inline Messages tool-call card. Parent can use this to open a\n * drawer rendering `<ExplainableShell>` from footprint-explainable-ui\n * scoped to that tool's internal flowchart execution — the\n * composition seam between Lens (agent view) and explainable-ui\n * (tool-internal view).\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function AgentLens({\n runtimeSnapshot,\n timeline: providedTimeline,\n systemPrompt,\n onToolCallClick,\n}: AgentLensProps) {\n const t = useLensTheme();\n const timeline = useMemo<AgentTimeline | null>(() => {\n if (providedTimeline) return providedTimeline;\n if (!runtimeSnapshot) return null;\n return fromAgentSnapshot(runtimeSnapshot);\n }, [providedTimeline, runtimeSnapshot]);\n\n const [selectedToolId, setSelectedToolId] = useState<string | null>(null);\n const [selectedIterKey, setSelectedIterKey] = useState<string | null>(null);\n\n function handleToolClick(inv: AgentToolInvocation) {\n setSelectedToolId(inv.id);\n setSelectedIterKey(`${inv.turnIndex}.${inv.iterationIndex}`);\n onToolCallClick?.(inv);\n }\n\n if (!timeline) {\n return (\n <div\n data-fp-lens=\"empty\"\n style={{\n padding: 32,\n color: t.textMuted,\n fontFamily: t.fontSans,\n textAlign: \"center\",\n background: t.bg,\n }}\n >\n No agent run to show yet. Pass <code>runtimeSnapshot</code> after the agent runs.\n </div>\n );\n }\n\n const derivedSystemPrompt =\n systemPrompt ??\n (typeof timeline.rawSnapshot?.sharedState?.systemPrompt === \"string\"\n ? (timeline.rawSnapshot.sharedState.systemPrompt as string)\n : undefined);\n\n return (\n <div\n data-fp-lens=\"shell\"\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 320px\",\n gridTemplateRows: \"auto 1fr\",\n gridTemplateAreas: '\"strip strip\" \"messages inspector\"',\n height: \"100%\",\n minHeight: 0,\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n }}\n >\n {/* One-off stylesheet for the selected-iter pulse. Inline-style can't\n target a data attribute, and this rule is stable (doesn't depend\n on tokens — `currentColor` picks up whatever text color the\n active theme resolves). */}\n <style>{`\n [data-iter-selected=\"true\"] {\n outline-color: currentColor !important;\n background: color-mix(in srgb, currentColor 8%, transparent);\n }\n `}</style>\n <div style={{ gridArea: \"strip\" }}>\n <IterationStrip\n timeline={timeline}\n selectedKey={selectedIterKey}\n onSelect={setSelectedIterKey}\n />\n </div>\n <div style={{ gridArea: \"messages\", minHeight: 0, overflow: \"hidden\" }}>\n <MessagesPanel\n timeline={timeline}\n onToolCallClick={handleToolClick}\n selectedIterKey={selectedIterKey}\n {...(derivedSystemPrompt && { systemPrompt: derivedSystemPrompt })}\n />\n </div>\n <div\n style={{\n gridArea: \"inspector\",\n minHeight: 0,\n overflow: \"hidden\",\n borderLeft: `1px solid ${t.border}`,\n }}\n >\n <ToolCallInspector\n timeline={timeline}\n selectedId={selectedToolId}\n onSelect={handleToolClick}\n />\n </div>\n </div>\n );\n}\n","/**\n * fromAgentSnapshot — turn an agentfootprint runtimeSnapshot into the\n * agent-shaped AgentTimeline Lens renders against.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * The raw snapshot is flowchart-shaped (stages, commitLog, subflowResults).\n * Lens needs agent-shape: turns[] → iterations[] → {messages, toolCalls,\n * decision, tokens, latency, visibleTools}. That's what this file does.\n *\n * Derivation strategy (all sources already present — no library change\n * needed):\n * • `sharedState.messages[]` — canonical conversation\n * • `commitLog` entries for `call-llm` / `streaming-call-llm` — per-iter\n * LLM request+response (model, tokens, duration, stop reason)\n * • `commitLog` entries for `execute-tool-calls` — per-iter tool outputs\n * and decision updates\n * • `sf-instructions-to-llm` snapshots — matched instruction ids +\n * injection counts per iter\n * • `sf-tools` snapshots — tool list visible to the LLM that iter\n *\n * Turn boundaries are inferred by walking `messages[]` and grouping\n * everything between user messages into one turn. Iteration boundaries\n * are the LLM call events within a turn.\n * ─────────────────────────────────────────────────────────────────────────\n */\n\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySnapshot = any;\n\nexport function fromAgentSnapshot(runtime: AnySnapshot): AgentTimeline {\n const shared = runtime?.sharedState ?? {};\n const rawMessages: RawMessage[] = shared.messages ?? [];\n const messages = rawMessages.map(normalizeMessage);\n\n const commitLog = Array.isArray(runtime?.commitLog) ? runtime.commitLog : [];\n const llmCalls = extractLLMCalls(commitLog);\n const toolExecs = extractToolExecutions(commitLog);\n const instructionEvals = extractInstructionEvals(commitLog);\n const toolResolves = extractToolResolves(commitLog);\n\n const turns = assembleTurns(messages, llmCalls, toolExecs, instructionEvals, toolResolves);\n const allTools = turns.flatMap((t) => t.iterations.flatMap((i) => i.toolCalls));\n\n return {\n turns,\n messages,\n tools: allTools,\n finalDecision: (shared.decision as Record<string, unknown>) ?? {},\n rawSnapshot: runtime,\n };\n}\n\n// ── Normalize ─────────────────────────────────────────────────────────\n\ninterface RawMessage {\n role: string;\n content: string | unknown;\n toolCalls?: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n toolCallId?: string;\n}\n\nfunction normalizeMessage(m: RawMessage): AgentMessage {\n const role = ((): AgentMessage[\"role\"] => {\n if (m.role === \"system\" || m.role === \"user\" || m.role === \"assistant\" || m.role === \"tool\")\n return m.role;\n return \"user\";\n })();\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return {\n role,\n content,\n ...(m.toolCalls?.length ? { toolCalls: m.toolCalls } : {}),\n ...(m.toolCallId ? { toolCallId: m.toolCallId } : {}),\n };\n}\n\n// ── Extract from commitLog ────────────────────────────────────────────\n\ninterface RawCommit {\n stageId?: string;\n stage?: string;\n runtimeStageId?: string;\n updates?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trace?: any;\n}\n\ninterface LLMCall {\n iterationIndex: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCallsRequested: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n}\n\nfunction extractLLMCalls(commitLog: RawCommit[]): LLMCall[] {\n const out: LLMCall[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"call-llm\" && id !== \"streaming-call-llm\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const rawResponse =\n (u[\"adapterRawResponse\"] as Record<string, unknown> | undefined) ??\n (u[\"llmResponse\"] as Record<string, unknown> | undefined);\n const usage = rawResponse?.usage as\n | { inputTokens?: number; outputTokens?: number }\n | undefined;\n out.push({\n iterationIndex: iter,\n model: rawResponse?.model as string | undefined,\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n durationMs: (u[\"callDurationMs\"] as number | undefined) ?? undefined,\n stopReason: rawResponse?.stopReason as string | undefined,\n assistantContent: (rawResponse?.content as string | undefined) ?? \"\",\n toolCallsRequested:\n (rawResponse?.toolCalls as LLMCall[\"toolCallsRequested\"] | undefined) ?? [],\n });\n }\n return out;\n}\n\ninterface ToolExec {\n iterationIndex: number;\n toolCalls: AgentToolInvocation[];\n}\n\nfunction extractToolExecutions(commitLog: RawCommit[]): ToolExec[] {\n const out: ToolExec[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"execute-tool-calls\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n // agentfootprint stores parsed tool calls + their results via\n // tool-start / tool-end emit events + the tool-role messages appended\n // to `messages`. Simplest stable derivation: walk messages right\n // after this commit and collect the tool-result entries.\n // For v0.1 we emit the tool call stubs; full resolution happens at\n // the assembler step where we have both sides in hand.\n const rawCalls = u[\"toolCalls\"] as LLMCall[\"toolCallsRequested\"] | undefined;\n const stubs: AgentToolInvocation[] = (rawCalls ?? []).map((c) => ({\n id: c.id,\n name: c.name,\n arguments: c.arguments ?? {},\n result: \"\", // filled in during assembly\n iterationIndex: iter,\n turnIndex: 0, // reassigned during assembly\n decisionUpdate: u[\"updatedDecision\"] as Record<string, unknown> | undefined,\n }));\n out.push({ iterationIndex: iter, toolCalls: stubs });\n }\n return out;\n}\n\ninterface InstructionEval {\n iterationIndex: number;\n matchedInstructions?: string[];\n promptInjectionCount: number;\n toolInjectionCount: number;\n}\n\nfunction extractInstructionEvals(commitLog: RawCommit[]): InstructionEval[] {\n const out: InstructionEval[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"evaluate-instructions\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const matchedRaw = u[\"matchedInstructions\"];\n const matched = parseMatched(matchedRaw);\n const promptInj = Array.isArray(u[\"promptInjections\"]) ? u[\"promptInjections\"].length : 0;\n const toolInj = Array.isArray(u[\"toolInjections\"]) ? u[\"toolInjections\"].length : 0;\n out.push({\n iterationIndex: iter,\n ...(matched.length > 0 && { matchedInstructions: matched }),\n promptInjectionCount: promptInj,\n toolInjectionCount: toolInj,\n });\n }\n return out;\n}\n\nfunction parseMatched(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v.filter((x) => typeof x === \"string\");\n if (typeof v === \"string\") {\n // format: \"N matched: id1, id2, id3...\"\n const m = v.match(/:\\s*(.+)/);\n if (!m) return [];\n return m[1]\n .split(\",\")\n .map((s) => s.trim().replace(/\\.{3}$/, \"\"))\n .filter(Boolean);\n }\n return [];\n}\n\ninterface ToolResolve {\n iterationIndex: number;\n visibleTools: string[];\n}\n\nfunction extractToolResolves(commitLog: RawCommit[]): ToolResolve[] {\n const out: ToolResolve[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"resolve-tools\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const descs = u[\"toolDescriptions\"] as Array<{ name: string }> | undefined;\n out.push({\n iterationIndex: iter,\n visibleTools: (descs ?? []).map((d) => d.name),\n });\n }\n return out;\n}\n\n// ── Assemble turns ────────────────────────────────────────────────────\n\nfunction assembleTurns(\n messages: AgentMessage[],\n llmCalls: LLMCall[],\n toolExecs: ToolExec[],\n instructionEvals: InstructionEval[],\n toolResolves: ToolResolve[],\n): AgentTurn[] {\n // Build a per-iteration map (flat across turns) then split by turn.\n // For a fresh agent instance, iter counts restart every turn — but\n // because commitLog is cumulative, iter numbers across commitLog are\n // monotonically increasing over the whole execution. So we group\n // iterations by the message boundary they fall in.\n //\n // Algorithm: walk messages in order. Each user message starts a new\n // turn. Each assistant message that has toolCalls (or is the final)\n // consumes the next LLM call from llmCalls. Tool-role messages that\n // follow bind to the most recent assistant message's toolCalls.\n\n const turns: AgentTurn[] = [];\n let currentTurn: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n } | null = null;\n let llmIdx = 0;\n const toolExecByIter = new Map(toolExecs.map((t) => [t.iterationIndex, t]));\n const instrByIter = new Map(instructionEvals.map((i) => [i.iterationIndex, i]));\n const visibleByIter = new Map(toolResolves.map((t) => [t.iterationIndex, t]));\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n currentTurn = {\n index: turns.length,\n userPrompt: msg.content,\n iterations: [],\n finalContent: \"\",\n };\n continue;\n }\n if (!currentTurn) continue; // skip system prompt + anything before first user\n\n if (msg.role === \"assistant\") {\n const call = llmCalls[llmIdx];\n llmIdx++;\n const iterIndex = call?.iterationIndex ?? currentTurn.iterations.length + 1;\n const exec = toolExecByIter.get(iterIndex);\n const instr = instrByIter.get(iterIndex);\n const visible = visibleByIter.get(iterIndex);\n\n const toolCalls: AgentToolInvocation[] = (exec?.toolCalls ?? []).map((tc) => ({\n ...tc,\n turnIndex: currentTurn!.index,\n }));\n\n const iteration: AgentIteration = {\n index: iterIndex,\n ...(call?.model && { model: call.model }),\n ...(call?.inputTokens !== undefined && { inputTokens: call.inputTokens }),\n ...(call?.outputTokens !== undefined && { outputTokens: call.outputTokens }),\n ...(call?.durationMs !== undefined && { durationMs: call.durationMs }),\n ...(call?.stopReason && { stopReason: call.stopReason }),\n assistantContent: call?.assistantContent ?? msg.content,\n toolCalls,\n decisionAtStart: {}, // TODO(phase-2): derive from pre-iter commit\n ...(instr?.matchedInstructions && { matchedInstructions: instr.matchedInstructions }),\n visibleTools: visible?.visibleTools ?? [],\n };\n\n currentTurn.iterations.push(iteration);\n if (!toolCalls.length) currentTurn.finalContent = iteration.assistantContent;\n continue;\n }\n\n if (msg.role === \"tool\" && msg.toolCallId) {\n // Bind the result string back to the matching tool invocation in\n // the latest iteration.\n const iter = currentTurn.iterations[currentTurn.iterations.length - 1];\n if (!iter) continue;\n const idx = iter.toolCalls.findIndex((tc) => tc.id === msg.toolCallId);\n if (idx < 0) continue;\n const updated = { ...iter.toolCalls[idx], result: msg.content };\n // Rewrite via mutation — iter is readonly at the type level but we\n // own this intermediate structure during assembly.\n (iter.toolCalls as AgentToolInvocation[])[idx] = updated;\n }\n }\n\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n return turns;\n}\n\nfunction finalizeTurn(t: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n}): AgentTurn {\n const totalInputTokens = t.iterations.reduce((s, i) => s + (i.inputTokens ?? 0), 0);\n const totalOutputTokens = t.iterations.reduce((s, i) => s + (i.outputTokens ?? 0), 0);\n const totalDurationMs = t.iterations.reduce((s, i) => s + (i.durationMs ?? 0), 0);\n return {\n index: t.index,\n userPrompt: t.userPrompt,\n iterations: t.iterations,\n finalContent: t.finalContent,\n totalInputTokens,\n totalOutputTokens,\n totalDurationMs,\n };\n}\n","/**\n * MessagesPanel — the primary Lens surface. Chat-shaped view of an agent\n * run with turn boundaries, iteration markers, and expandable tool calls.\n *\n * Data comes from `fromAgentSnapshot(runtimeSnapshot).turns`. Each turn\n * is:\n * • one user message\n * • one or more assistant iterations (each may request N tool calls)\n * • tool role bubbles bound to their assistant parent\n * • final assistant bubble\n *\n * Theme is read via `useLensTheme()` which maps FootprintTheme tokens\n * into Lens's semantic palette. Consumers get free light/dark support\n * by wrapping their app in `<FootprintTheme tokens={coolLight|coolDark}>`\n * — no Lens-specific theme API to learn.\n */\nimport { useEffect, useRef, useState } from \"react\";\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface MessagesPanelProps {\n readonly timeline: AgentTimeline;\n /**\n * Called when the user clicks a tool-call card. Host app surfaces it\n * in the Tool Call Inspector. When omitted, clicking is a no-op.\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n /** Optional system-prompt text to render in the collapsible preamble. */\n readonly systemPrompt?: string;\n /**\n * The currently-selected iteration key in the parent shell, format\n * `\"<turnIndex>.<iterIndex>\"` (e.g. `\"0.3\"` for turn 1, iter 3).\n * When this changes, the panel scrolls the matching iteration block\n * into view and flashes a highlight for 1.2s so the user sees the\n * jump. No-op when undefined.\n */\n readonly selectedIterKey?: string | null;\n}\n\nexport function MessagesPanel({\n timeline,\n onToolCallClick,\n systemPrompt,\n selectedIterKey,\n}: MessagesPanelProps) {\n const t = useLensTheme();\n const scrollRef = useRef<HTMLDivElement | null>(null);\n\n // Scroll + highlight when selectedIterKey changes. The highlight is a\n // CSS class toggled on the target block; we pulse it via a one-shot\n // timer rather than CSS animation so it behaves the same in both\n // themes and survives re-renders mid-pulse.\n useEffect(() => {\n if (!selectedIterKey || !scrollRef.current) return;\n const target = scrollRef.current.querySelector<HTMLDivElement>(\n `[data-iter-key=\"${CSS.escape(selectedIterKey)}\"]`,\n );\n if (!target) return;\n target.scrollIntoView({ block: \"start\", behavior: \"smooth\" });\n target.setAttribute(\"data-iter-selected\", \"true\");\n const h = window.setTimeout(() => target.removeAttribute(\"data-iter-selected\"), 1200);\n return () => window.clearTimeout(h);\n }, [selectedIterKey]);\n\n return (\n <div\n ref={scrollRef}\n data-fp-lens=\"messages-panel\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n padding: \"16px 24px\",\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n fontSize: 14,\n lineHeight: 1.55,\n minHeight: 0,\n overflow: \"auto\",\n }}\n >\n {systemPrompt && <SystemBubble text={systemPrompt} />}\n {timeline.turns.map((turn) => (\n <TurnBlock key={turn.index} turn={turn} onToolCallClick={onToolCallClick} />\n ))}\n </div>\n );\n}\n\nfunction SystemBubble({ text }: { text: string }) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = text.slice(0, 140).replace(/\\s+/g, \" \") + (text.length > 140 ? \"…\" : \"\");\n return (\n <div\n style={{\n alignSelf: \"center\",\n width: \"100%\",\n maxWidth: 880,\n border: `1px dashed ${t.border}`,\n borderRadius: t.radius,\n padding: \"8px 12px\",\n background: t.bgElev,\n fontSize: 12,\n color: t.textMuted,\n }}\n >\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: t.textMuted,\n cursor: \"pointer\",\n padding: 0,\n font: \"inherit\",\n }}\n >\n <strong>SYSTEM</strong> {open ? \"▾\" : \"▸\"} {open ? \"\" : preview}\n </button>\n {open && (\n <pre\n style={{\n marginTop: 8,\n whiteSpace: \"pre-wrap\",\n fontFamily: t.fontMono,\n fontSize: 11,\n color: t.text,\n }}\n >\n {text}\n </pre>\n )}\n </div>\n );\n}\n\nfunction TurnBlock({\n turn,\n onToolCallClick,\n}: {\n turn: AgentTurn;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <TurnHeader turn={turn} />\n <UserBubble text={turn.userPrompt} />\n {turn.iterations.map((iter) => (\n <IterationBlock\n key={iter.index}\n iter={iter}\n turnIndex={turn.index}\n onToolCallClick={onToolCallClick}\n />\n ))}\n {turn.finalContent && turn.iterations.length > 0 && (\n <div style={{ fontSize: 11, color: t.textSubtle, textAlign: \"center\" }}>\n turn {turn.index + 1} final · {turn.iterations.length} iter · {turn.totalInputTokens}→\n {turn.totalOutputTokens} tok · {(turn.totalDurationMs / 1000).toFixed(1)}s\n </div>\n )}\n </div>\n );\n}\n\nfunction TurnHeader({ turn }: { turn: AgentTurn }) {\n const t = useLensTheme();\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n color: t.textSubtle,\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n }}\n >\n <div style={{ flex: 1, height: 1, background: t.border }} />\n <span>Turn {turn.index + 1}</span>\n <div style={{ flex: 1, height: 1, background: t.border }} />\n </div>\n );\n}\n\nfunction UserBubble({ text }: { text: string }) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <div\n style={{\n background: `color-mix(in srgb, ${t.accent} 18%, ${t.bgElev})`,\n border: `1px solid ${t.border}`,\n color: t.text,\n maxWidth: 720,\n padding: \"10px 14px\",\n borderRadius: `${t.radius} ${t.radius} 2px ${t.radius}`,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {text}\n </div>\n </div>\n );\n}\n\nfunction IterationBlock({\n iter,\n turnIndex,\n onToolCallClick,\n}: {\n iter: AgentIteration;\n turnIndex: number;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const key = `${turnIndex}.${iter.index}`;\n return (\n <div\n data-iter-key={key}\n data-turn-index={turnIndex}\n data-iter-index={iter.index}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n // When the parent adds data-iter-selected (via IterationStrip\n // click), pulse a soft ring using the accent color. Subtle so\n // the chat itself stays readable.\n padding: 8,\n margin: -8,\n borderRadius: t.radius,\n outline: \"2px solid transparent\",\n outlineOffset: 2,\n transition: \"outline-color 180ms ease, background 180ms ease\",\n }}\n >\n <IterationBadge iter={iter} />\n {iter.assistantContent && (\n <div\n style={{\n background: t.bgElev,\n border: `1px solid ${t.border}`,\n borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,\n padding: \"10px 14px\",\n maxWidth: 820,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {iter.assistantContent}\n </div>\n )}\n {iter.toolCalls.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, paddingLeft: 12 }}>\n {iter.toolCalls.map((tc) => (\n <ToolCallCard key={tc.id} invocation={tc} onClick={onToolCallClick} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction IterationBadge({ iter }: { iter: AgentIteration }) {\n const t = useLensTheme();\n const bits: string[] = [`iter ${iter.index}`];\n if (iter.model) bits.push(iter.model);\n if (iter.inputTokens !== undefined)\n bits.push(`${iter.inputTokens}→${iter.outputTokens ?? \"?\"} tok`);\n if (iter.durationMs !== undefined) bits.push(`${(iter.durationMs / 1000).toFixed(2)}s`);\n if (iter.stopReason) bits.push(iter.stopReason);\n return (\n <div\n style={{\n alignSelf: \"flex-start\",\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n fontFamily: t.fontMono,\n }}\n >\n {bits.join(\" · \")}\n </div>\n );\n}\n\nfunction ToolCallCard({\n invocation,\n onClick,\n}: {\n invocation: AgentToolInvocation;\n onClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = shortArgs(invocation.arguments);\n const errored = invocation.error === true;\n return (\n <div\n style={{\n border: `1px solid ${errored ? t.error : t.border}`,\n borderLeft: `3px solid ${errored ? t.error : t.accent}`,\n borderRadius: 6,\n background: t.bg,\n overflow: \"hidden\",\n }}\n >\n <div\n onClick={() => {\n setOpen((v) => !v);\n onClick?.(invocation);\n }}\n style={{\n padding: \"8px 12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {invocation.name}\n </span>\n <span style={{ color: t.textMuted }}>({preview})</span>\n <span style={{ flex: 1 }} />\n {invocation.decisionUpdate && Object.keys(invocation.decisionUpdate).length > 0 && (\n <span\n style={{\n fontSize: 10,\n padding: \"1px 6px\",\n borderRadius: 3,\n background: `color-mix(in srgb, ${t.warning} 20%, transparent)`,\n color: t.warning,\n fontFamily: t.fontSans,\n fontWeight: 600,\n textTransform: \"uppercase\",\n }}\n >\n decisionUpdate\n </span>\n )}\n <span style={{ color: t.textSubtle }}>{open ? \"▾\" : \"▸\"}</span>\n </div>\n {open && (\n <div style={{ padding: \"8px 12px\", borderTop: `1px solid ${t.border}` }}>\n <Label t={t}>args</Label>\n <JsonBlock value={invocation.arguments} />\n {invocation.result && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n result\n </Label>\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: errored ? t.error : t.text,\n maxHeight: 280,\n overflow: \"auto\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {invocation.result}\n </pre>\n </>\n )}\n {invocation.decisionUpdate &&\n Object.keys(invocation.decisionUpdate).length > 0 && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n decisionUpdate\n </Label>\n <JsonBlock value={invocation.decisionUpdate} />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction Label({\n t,\n children,\n style,\n}: {\n t: ReturnType<typeof useLensTheme>;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) {\n return (\n <div\n style={{\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n marginBottom: 4,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction JsonBlock({ value }: { value: unknown }) {\n const t = useLensTheme();\n return (\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: t.text,\n maxHeight: 200,\n overflow: \"auto\",\n }}\n >\n {JSON.stringify(value, null, 2)}\n </pre>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"\";\n if (keys.length === 1) {\n const v = args[keys[0]];\n if (typeof v === \"string\" && v.length < 40) return `${keys[0]}: \"${v}\"`;\n }\n return keys.join(\", \");\n}\n\nexport { ToolCallCard };\n\nfunction _assertUnused(_: AgentMessage) {\n // Exported type is referenced from ./index.ts; keeping the import\n // for bundler tree-shaking consistency without introducing a new\n // linter warning on a \"used-elsewhere\" type import.\n void _;\n}\n_assertUnused;\n","/**\n * useLensTheme — single source of truth for Lens colors + sizing.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Theme pass-through contract (IMPORTANT for consumers):\n *\n * Lens does NOT invent its own theme system. It reads tokens from the\n * FootprintTheme context already defined in `footprint-explainable-ui`.\n * A consumer app that wraps its tree in:\n *\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n * <FootprintTheme tokens={theme === 'light' ? coolLight : coolDark}>\n * <AgentLens runtimeSnapshot={snap} />\n * </FootprintTheme>\n *\n * …gets both Lens AND the drill-down explainable-ui drawer themed from the\n * same token bag. No separate `theme` prop, no duplicate palette, no\n * drift between the two views when the user flips light/dark.\n *\n * If no FootprintTheme provider is mounted, Lens falls back to cool-dark\n * defaults — the same defaults explainable-ui uses, so it looks correct\n * out of the box without configuration.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useFootprintTheme, coolDark } from \"footprint-explainable-ui\";\nimport type { ThemeTokens } from \"footprint-explainable-ui\";\n\n/**\n * The resolved color palette + sizing tokens Lens renders against.\n * Always defined — callers never need to null-check.\n */\nexport interface LensTheme {\n readonly bg: string;\n readonly bgElev: string;\n readonly bgHover: string;\n readonly border: string;\n readonly borderStrong: string;\n readonly text: string;\n readonly textMuted: string;\n readonly textSubtle: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly error: string;\n readonly fontSans: string;\n readonly fontMono: string;\n readonly radius: string;\n}\n\n/**\n * Read tokens from FootprintTheme context (if present) and map them\n * into Lens's semantic palette. Missing tokens fall back to coolDark.\n */\nexport function useLensTheme(): LensTheme {\n const ctx = useFootprintTheme();\n return resolve(ctx);\n}\n\n/** Pure mapping — exported for unit tests + non-hook call sites. */\nexport function resolve(tokens: ThemeTokens | undefined): LensTheme {\n const t = tokens ?? {};\n const c = t.colors ?? coolDark.colors ?? {};\n const fallback = coolDark.colors ?? {};\n return {\n bg: c.bgPrimary ?? fallback.bgPrimary ?? \"#0f172a\",\n bgElev: c.bgSecondary ?? fallback.bgSecondary ?? \"#1e293b\",\n bgHover: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n border: c.border ?? fallback.border ?? \"#334155\",\n borderStrong: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n text: c.textPrimary ?? fallback.textPrimary ?? \"#f8fafc\",\n textMuted: c.textSecondary ?? fallback.textSecondary ?? \"#94a3b8\",\n textSubtle: c.textMuted ?? fallback.textMuted ?? \"#64748b\",\n accent: c.primary ?? fallback.primary ?? \"#6366f1\",\n success: c.success ?? fallback.success ?? \"#22c55e\",\n warning: c.warning ?? fallback.warning ?? \"#f59e0b\",\n error: c.error ?? fallback.error ?? \"#ef4444\",\n fontSans: t.fontFamily?.sans ?? coolDark.fontFamily?.sans ?? \"system-ui, sans-serif\",\n fontMono: t.fontFamily?.mono ?? coolDark.fontFamily?.mono ?? \"ui-monospace, monospace\",\n radius: t.radius ?? coolDark.radius ?? \"8px\",\n };\n}\n","/**\n * IterationStrip — horizontal ribbon of LLM calls across the run, one\n * chip per iteration. Click to scroll/pin MessagesPanel to that iter.\n *\n * v0.1 is display-only with the selection callback; parent app owns the\n * scroll behavior.\n */\nimport type { AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface IterationStripProps {\n readonly timeline: AgentTimeline;\n readonly selectedKey?: string | null;\n readonly onSelect?: (key: string) => void;\n}\n\nexport function IterationStrip({ timeline, selectedKey, onSelect }: IterationStripProps) {\n const t = useLensTheme();\n const chips = timeline.turns.flatMap((turn) =>\n turn.iterations.map((iter) => ({\n key: `${turn.index}.${iter.index}`,\n turn: turn.index + 1,\n iter: iter.index,\n label: chipLabel(iter),\n tools: iter.toolCalls.length,\n durationMs: iter.durationMs ?? 0,\n stopReason: iter.stopReason,\n })),\n );\n\n return (\n <div\n data-fp-lens=\"iteration-strip\"\n style={{\n display: \"flex\",\n gap: 4,\n padding: \"8px 12px\",\n overflowX: \"auto\",\n borderBottom: `1px solid ${t.border}`,\n background: t.bgElev,\n }}\n >\n {chips.length === 0 && (\n <span style={{ color: t.textSubtle, fontSize: 11 }}>No iterations yet.</span>\n )}\n {chips.map((c) => {\n const active = c.key === selectedKey;\n const isFinal = c.stopReason === \"stop\" || c.stopReason === \"end_turn\";\n return (\n <button\n key={c.key}\n onClick={() => onSelect?.(c.key)}\n style={{\n background: active ? t.accent : \"transparent\",\n color: active ? \"#fff\" : t.textMuted,\n border: `1px solid ${active ? t.accent : t.border}`,\n borderRadius: 4,\n padding: \"4px 8px\",\n fontSize: 11,\n fontFamily: \"ui-monospace, monospace\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n title={`turn ${c.turn} · iter ${c.iter} · ${c.tools} tool call${\n c.tools === 1 ? \"\" : \"s\"\n }${c.stopReason ? ` · ${c.stopReason}` : \"\"}`}\n >\n t{c.turn}.i{c.iter} · {c.label} {isFinal ? \"✓\" : \"\"}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction chipLabel(iter: { toolCalls: readonly unknown[]; durationMs?: number }): string {\n const d = iter.durationMs ?? 0;\n const secs = d >= 1000 ? `${(d / 1000).toFixed(1)}s` : `${Math.round(d)}ms`;\n const toolBit = iter.toolCalls.length > 0 ? `${iter.toolCalls.length}t` : \"final\";\n return `${secs} · ${toolBit}`;\n}\n","/**\n * ToolCallInspector — flat sidebar list of every tool invocation in the\n * run. Primary workflow: skim for errors, click to focus a specific\n * call (mirrors MessagesPanel's selection).\n *\n * v0.1 minimum — name, args preview, latency, error badge. Drill-in to\n * the tool's underlying footprintjs flowchart via explainable-ui is a\n * phase-2 item (requires surfacing per-tool sub-snapshots).\n */\nimport type { AgentToolInvocation, AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface ToolCallInspectorProps {\n readonly timeline: AgentTimeline;\n readonly selectedId?: string | null;\n readonly onSelect?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function ToolCallInspector({\n timeline,\n selectedId,\n onSelect,\n}: ToolCallInspectorProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"tool-call-inspector\"\n style={{\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n display: \"flex\",\n flexDirection: \"column\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"10px 14px\",\n borderBottom: `1px solid ${t.border}`,\n fontSize: 11,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n background: t.bgElev,\n }}\n >\n Tool calls · {timeline.tools.length}\n </div>\n <div style={{ overflow: \"auto\", flex: 1 }}>\n {timeline.tools.length === 0 && (\n <div style={{ padding: 14, color: t.textSubtle, fontSize: 12 }}>\n No tool calls yet.\n </div>\n )}\n {timeline.tools.map((tc) => {\n const active = tc.id === selectedId;\n const errored = tc.error === true;\n return (\n <button\n key={tc.id}\n onClick={() => onSelect?.(tc)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n textAlign: \"left\",\n padding: \"8px 12px\",\n background: active ? t.bgHover : \"transparent\",\n border: \"none\",\n borderLeft: `3px solid ${\n active ? t.accent : errored ? t.error : \"transparent\"\n }`,\n borderBottom: `1px solid ${t.border}`,\n color: t.text,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: 8,\n alignItems: \"baseline\",\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {tc.name}\n </span>\n <span\n style={{ color: t.textSubtle, fontSize: 10, marginLeft: \"auto\" }}\n >\n t{tc.turnIndex + 1}.i{tc.iterationIndex}\n {tc.durationMs !== undefined && ` · ${Math.round(tc.durationMs)}ms`}\n </span>\n </div>\n <div\n style={{\n fontSize: 10,\n color: t.textMuted,\n marginTop: 2,\n fontFamily: t.fontMono,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {shortArgs(tc.arguments)}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"— no args —\";\n return keys\n .map((k) => {\n const v = args[k];\n if (typeof v === \"string\") return `${k}: \"${v.length > 20 ? v.slice(0, 20) + \"…\" : v}\"`;\n if (typeof v === \"number\" || typeof v === \"boolean\") return `${k}: ${v}`;\n return `${k}: …`;\n })\n .join(\", \");\n}\n","/**\n * LiveTimelineBuilder — ingests agentfootprint emit events AS THEY HAPPEN\n * and accumulates the `AgentTimeline` incrementally. Zero post-processing:\n * every field is set as the corresponding event fires during traversal.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Why this exists\n *\n * footprintjs's core principle: \"collect during traversal, never post-\n * process.\" Walking `commitLog` after the run to reconstruct the agent\n * view is valid but it re-traverses data that already flowed past. The\n * Builder is the correct shape — it's a recorder that subscribes to the\n * stream of events the agent already emits and writes each field exactly\n * once, when the source-of-truth event fires.\n *\n * Consumer wiring (from a React app):\n *\n * const builder = useMemo(() => new LiveTimelineBuilder(), []);\n * const [timeline, setTimeline] = useState(builder.getTimeline());\n * // In Neo's runTurn onEvent:\n * await agent.run(prompt, {\n * onEvent: (e) => {\n * builder.ingest(e);\n * setTimeline(builder.getTimeline());\n * },\n * });\n * <AgentLens timeline={timeline} />\n *\n * Or via the `useLiveTimeline()` React hook below — same mechanics, less\n * boilerplate.\n *\n * The events consumed are all `agentfootprint.stream.*` (llm_start,\n * llm_end, tool_start, tool_end) + `agentfootprint.agent.turn_complete`.\n * User messages are captured by calling `startTurn(userPrompt)` before\n * each `agent.run()` invocation — that's the one piece the event stream\n * doesn't carry (agent.run() is where the user message enters the\n * system, not an event emission).\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// Minimal shape we need from an agent event — structural only, no direct\n// dep on agentfootprint's event type (which may evolve).\ninterface AgentEventLike {\n readonly type: string;\n readonly toolName?: string;\n readonly toolCallId?: string;\n readonly args?: Record<string, unknown>;\n readonly result?: { content?: string; error?: boolean } | string;\n readonly iteration?: number;\n readonly content?: string;\n readonly toolCallCount?: number;\n readonly model?: string;\n readonly usage?: { inputTokens?: number; outputTokens?: number };\n readonly stopReason?: string;\n readonly durationMs?: number;\n readonly iterations?: number;\n readonly reason?: string;\n}\n\ninterface MutableTurn {\n index: number;\n userPrompt: string;\n iterations: MutableIteration[];\n finalContent: string;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalDurationMs: number;\n startMs: number;\n}\n\ninterface MutableIteration {\n index: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCalls: MutableTool[];\n decisionAtStart: Record<string, unknown>;\n matchedInstructions?: string[];\n visibleTools: string[];\n startMs: number;\n}\n\ninterface MutableTool {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result: string;\n error?: boolean;\n decisionUpdate?: Record<string, unknown>;\n iterationIndex: number;\n turnIndex: number;\n durationMs?: number;\n startMs: number;\n}\n\nexport class LiveTimelineBuilder {\n private turns: MutableTurn[] = [];\n private currentTurn: MutableTurn | null = null;\n private currentIter: MutableIteration | null = null;\n private toolByCallId = new Map<string, MutableTool>();\n private messages: AgentMessage[] = [];\n private systemPrompt: string | undefined;\n private finalDecision: Record<string, unknown> = {};\n\n /**\n * Begin a new turn. Call this BEFORE `agent.run(userPrompt)` so the\n * user's prompt appears alongside the iterations it produced. Safe to\n * call even mid-conversation — it closes the previous turn cleanly.\n */\n startTurn(userPrompt: string): void {\n if (this.currentTurn) this.commitCurrentTurn();\n this.currentTurn = {\n index: this.turns.length,\n userPrompt,\n iterations: [],\n finalContent: \"\",\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalDurationMs: 0,\n startMs: Date.now(),\n };\n this.messages.push({ role: \"user\", content: userPrompt });\n }\n\n /**\n * Optional — attach the system prompt so MessagesPanel can render it\n * in the collapsible preamble. Usually set once at agent construction.\n */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n /**\n * Feed one agent stream event. Safe to call for unknown events; we\n * ignore anything we don't recognize.\n */\n ingest(event: AgentEventLike | unknown): void {\n const e = event as AgentEventLike;\n if (!e || typeof e.type !== \"string\") return;\n switch (e.type) {\n case \"llm_start\":\n case \"agentfootprint.stream.llm_start\":\n this.onLLMStart(e);\n return;\n case \"llm_end\":\n case \"agentfootprint.stream.llm_end\":\n this.onLLMEnd(e);\n return;\n case \"tool_start\":\n case \"agentfootprint.stream.tool_start\":\n this.onToolStart(e);\n return;\n case \"tool_end\":\n case \"agentfootprint.stream.tool_end\":\n this.onToolEnd(e);\n return;\n case \"turn_end\":\n case \"agentfootprint.agent.turn_complete\":\n this.commitCurrentTurn();\n return;\n default:\n return;\n }\n }\n\n private onLLMStart(e: AgentEventLike): void {\n if (!this.currentTurn) return;\n const iterNum = e.iteration ?? this.currentTurn.iterations.length + 1;\n this.currentIter = {\n index: iterNum,\n assistantContent: \"\",\n toolCalls: [],\n decisionAtStart: {},\n visibleTools: [],\n startMs: Date.now(),\n };\n this.currentTurn.iterations.push(this.currentIter);\n }\n\n private onLLMEnd(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n this.currentIter.assistantContent = e.content ?? this.currentIter.assistantContent;\n if (e.model) this.currentIter.model = e.model;\n if (e.usage?.inputTokens !== undefined) this.currentIter.inputTokens = e.usage.inputTokens;\n if (e.usage?.outputTokens !== undefined) this.currentIter.outputTokens = e.usage.outputTokens;\n if (e.stopReason) this.currentIter.stopReason = e.stopReason;\n this.currentIter.durationMs = e.durationMs ?? Date.now() - this.currentIter.startMs;\n\n // Aggregate into turn totals.\n this.currentTurn.totalInputTokens += this.currentIter.inputTokens ?? 0;\n this.currentTurn.totalOutputTokens += this.currentIter.outputTokens ?? 0;\n this.currentTurn.totalDurationMs += this.currentIter.durationMs ?? 0;\n\n // Assistant message for the chat view.\n if (this.currentIter.assistantContent) {\n this.messages.push({ role: \"assistant\", content: this.currentIter.assistantContent });\n }\n // If no tool calls follow, this iteration's content IS the turn's final answer.\n if ((e.toolCallCount ?? 0) === 0) {\n this.currentTurn.finalContent = this.currentIter.assistantContent;\n }\n }\n\n private onToolStart(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n const tool: MutableTool = {\n id: e.toolCallId ?? `tool-${this.currentIter.toolCalls.length}`,\n name: e.toolName ?? \"unknown\",\n arguments: e.args ?? {},\n result: \"\",\n iterationIndex: this.currentIter.index,\n turnIndex: this.currentTurn.index,\n startMs: Date.now(),\n };\n this.currentIter.toolCalls.push(tool);\n this.toolByCallId.set(tool.id, tool);\n }\n\n private onToolEnd(e: AgentEventLike): void {\n const tool = this.toolByCallId.get(e.toolCallId ?? \"\");\n if (!tool) return;\n const r = e.result;\n if (typeof r === \"string\") {\n tool.result = r;\n } else if (r && typeof r === \"object\") {\n tool.result = r.content ?? \"\";\n if (r.error === true) tool.error = true;\n }\n tool.durationMs = e.durationMs ?? Date.now() - tool.startMs;\n // Record the tool-role message so MessagesPanel can render it.\n this.messages.push({ role: \"tool\", content: tool.result, toolCallId: tool.id });\n }\n\n private commitCurrentTurn(): void {\n if (!this.currentTurn) return;\n this.turns.push(this.currentTurn);\n this.currentTurn = null;\n this.currentIter = null;\n }\n\n /**\n * Snapshot the current state as an immutable `AgentTimeline`. Safe to\n * call at any point — mid-run gives you the partial state so Lens can\n * live-update.\n */\n getTimeline(): AgentTimeline {\n const allTurns = [...this.turns];\n if (this.currentTurn) allTurns.push(this.currentTurn);\n const tools: AgentToolInvocation[] = [];\n const frozenTurns: AgentTurn[] = allTurns.map((t) => {\n const iterations: AgentIteration[] = t.iterations.map((i) => {\n const tcs = i.toolCalls.map((tc) => ({ ...tc } as AgentToolInvocation));\n tools.push(...tcs);\n return { ...i, toolCalls: tcs } as AgentIteration;\n });\n return { ...t, iterations } as AgentTurn;\n });\n return {\n turns: frozenTurns,\n messages: [...this.messages],\n tools,\n finalDecision: { ...this.finalDecision },\n rawSnapshot: null,\n };\n }\n\n /**\n * Fold in a final `decision` scope after the run — useful when\n * the consumer wants the Decision Ribbon (phase-2) to reflect the\n * post-run state. Safe no-op during the run itself.\n */\n setFinalDecision(decision: Record<string, unknown>): void {\n this.finalDecision = decision;\n }\n\n /** Get the optional system prompt for the Messages preamble. */\n getSystemPrompt(): string | undefined {\n return this.systemPrompt;\n }\n\n /** Wipe state. Useful when the consumer starts a fresh conversation. */\n reset(): void {\n this.turns = [];\n this.currentTurn = null;\n this.currentIter = null;\n this.toolByCallId.clear();\n this.messages = [];\n this.finalDecision = {};\n }\n}\n","/**\n * useLiveTimeline — React hook wrapper around LiveTimelineBuilder.\n *\n * The hook owns a stable builder across renders and returns:\n * • `timeline` — current state (re-renders on every `ingest` call)\n * • `ingest` — feed an agentfootprint stream event\n * • `startTurn`, `setSystemPrompt`, `setFinalDecision`, `reset` — forward methods\n *\n * Usage:\n *\n * const lens = useLiveTimeline();\n * <AgentLens timeline={lens.timeline} />\n *\n * // Before agent.run():\n * lens.startTurn(userPrompt);\n * await agent.run(userPrompt, { onEvent: lens.ingest });\n *\n * The hook keeps the agent-shaped view in sync AS events fire — Lens\n * updates incrementally during the run, not only after it completes.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { LiveTimelineBuilder } from \"./LiveTimelineBuilder\";\nimport type { AgentTimeline } from \"./types\";\n\nexport interface UseLiveTimelineResult {\n readonly timeline: AgentTimeline;\n readonly ingest: (event: unknown) => void;\n readonly startTurn: (userPrompt: string) => void;\n readonly setSystemPrompt: (prompt: string) => void;\n readonly setFinalDecision: (decision: Record<string, unknown>) => void;\n readonly reset: () => void;\n /** Escape hatch — exposed for integrations that need builder internals. */\n readonly builder: LiveTimelineBuilder;\n}\n\nexport function useLiveTimeline(): UseLiveTimelineResult {\n const builderRef = useRef<LiveTimelineBuilder | null>(null);\n if (!builderRef.current) builderRef.current = new LiveTimelineBuilder();\n const builder = builderRef.current;\n\n const [timeline, setTimeline] = useState<AgentTimeline>(() => builder.getTimeline());\n\n const sync = useCallback(() => {\n setTimeline(builder.getTimeline());\n }, [builder]);\n\n const ingest = useCallback(\n (event: unknown) => {\n builder.ingest(event);\n sync();\n },\n [builder, sync],\n );\n\n const startTurn = useCallback(\n (userPrompt: string) => {\n builder.startTurn(userPrompt);\n sync();\n },\n [builder, sync],\n );\n\n const setSystemPrompt = useCallback(\n (prompt: string) => {\n builder.setSystemPrompt(prompt);\n sync();\n },\n [builder, sync],\n );\n\n const setFinalDecision = useCallback(\n (decision: Record<string, unknown>) => {\n builder.setFinalDecision(decision);\n sync();\n },\n [builder, sync],\n );\n\n const reset = useCallback(() => {\n builder.reset();\n sync();\n }, [builder, sync]);\n\n return useMemo(\n () => ({ timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder }),\n [timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder],\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime","shortArgs","import_jsx_runtime","import_react"]}
package/dist/index.d.cts CHANGED
@@ -116,8 +116,16 @@ interface MessagesPanelProps {
116
116
  readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;
117
117
  /** Optional system-prompt text to render in the collapsible preamble. */
118
118
  readonly systemPrompt?: string;
119
+ /**
120
+ * The currently-selected iteration key in the parent shell, format
121
+ * `"<turnIndex>.<iterIndex>"` (e.g. `"0.3"` for turn 1, iter 3).
122
+ * When this changes, the panel scrolls the matching iteration block
123
+ * into view and flashes a highlight for 1.2s so the user sees the
124
+ * jump. No-op when undefined.
125
+ */
126
+ readonly selectedIterKey?: string | null;
119
127
  }
120
- declare function MessagesPanel({ timeline, onToolCallClick, systemPrompt, }: MessagesPanelProps): react_jsx_runtime.JSX.Element;
128
+ declare function MessagesPanel({ timeline, onToolCallClick, systemPrompt, selectedIterKey, }: MessagesPanelProps): react_jsx_runtime.JSX.Element;
121
129
 
122
130
  interface IterationStripProps {
123
131
  readonly timeline: AgentTimeline;
package/dist/index.d.ts CHANGED
@@ -116,8 +116,16 @@ interface MessagesPanelProps {
116
116
  readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;
117
117
  /** Optional system-prompt text to render in the collapsible preamble. */
118
118
  readonly systemPrompt?: string;
119
+ /**
120
+ * The currently-selected iteration key in the parent shell, format
121
+ * `"<turnIndex>.<iterIndex>"` (e.g. `"0.3"` for turn 1, iter 3).
122
+ * When this changes, the panel scrolls the matching iteration block
123
+ * into view and flashes a highlight for 1.2s so the user sees the
124
+ * jump. No-op when undefined.
125
+ */
126
+ readonly selectedIterKey?: string | null;
119
127
  }
120
- declare function MessagesPanel({ timeline, onToolCallClick, systemPrompt, }: MessagesPanelProps): react_jsx_runtime.JSX.Element;
128
+ declare function MessagesPanel({ timeline, onToolCallClick, systemPrompt, selectedIterKey, }: MessagesPanelProps): react_jsx_runtime.JSX.Element;
121
129
 
122
130
  interface IterationStripProps {
123
131
  readonly timeline: AgentTimeline;
package/dist/index.js CHANGED
@@ -205,7 +205,7 @@ function finalizeTurn(t) {
205
205
  }
206
206
 
207
207
  // src/panels/MessagesPanel.tsx
208
- import { useState } from "react";
208
+ import { useEffect, useRef, useState } from "react";
209
209
 
210
210
  // src/theme/useLensTheme.ts
211
211
  import { useFootprintTheme, coolDark } from "footprint-explainable-ui";
@@ -241,12 +241,26 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
241
241
  function MessagesPanel({
242
242
  timeline,
243
243
  onToolCallClick,
244
- systemPrompt
244
+ systemPrompt,
245
+ selectedIterKey
245
246
  }) {
246
247
  const t = useLensTheme();
248
+ const scrollRef = useRef(null);
249
+ useEffect(() => {
250
+ if (!selectedIterKey || !scrollRef.current) return;
251
+ const target = scrollRef.current.querySelector(
252
+ `[data-iter-key="${CSS.escape(selectedIterKey)}"]`
253
+ );
254
+ if (!target) return;
255
+ target.scrollIntoView({ block: "start", behavior: "smooth" });
256
+ target.setAttribute("data-iter-selected", "true");
257
+ const h = window.setTimeout(() => target.removeAttribute("data-iter-selected"), 1200);
258
+ return () => window.clearTimeout(h);
259
+ }, [selectedIterKey]);
247
260
  return /* @__PURE__ */ jsxs(
248
261
  "div",
249
262
  {
263
+ ref: scrollRef,
250
264
  "data-fp-lens": "messages-panel",
251
265
  style: {
252
266
  display: "flex",
@@ -333,7 +347,15 @@ function TurnBlock({
333
347
  return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
334
348
  /* @__PURE__ */ jsx(TurnHeader, { turn }),
335
349
  /* @__PURE__ */ jsx(UserBubble, { text: turn.userPrompt }),
336
- turn.iterations.map((iter) => /* @__PURE__ */ jsx(IterationBlock, { iter, onToolCallClick }, iter.index)),
350
+ turn.iterations.map((iter) => /* @__PURE__ */ jsx(
351
+ IterationBlock,
352
+ {
353
+ iter,
354
+ turnIndex: turn.index,
355
+ onToolCallClick
356
+ },
357
+ iter.index
358
+ )),
337
359
  turn.finalContent && turn.iterations.length > 0 && /* @__PURE__ */ jsxs("div", { style: { fontSize: 11, color: t.textSubtle, textAlign: "center" }, children: [
338
360
  "turn ",
339
361
  turn.index + 1,
@@ -395,27 +417,51 @@ function UserBubble({ text }) {
395
417
  }
396
418
  function IterationBlock({
397
419
  iter,
420
+ turnIndex,
398
421
  onToolCallClick
399
422
  }) {
400
423
  const t = useLensTheme();
401
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
402
- /* @__PURE__ */ jsx(IterationBadge, { iter }),
403
- iter.assistantContent && /* @__PURE__ */ jsx(
404
- "div",
405
- {
406
- style: {
407
- background: t.bgElev,
408
- border: `1px solid ${t.border}`,
409
- borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,
410
- padding: "10px 14px",
411
- maxWidth: 820,
412
- whiteSpace: "pre-wrap"
413
- },
414
- children: iter.assistantContent
415
- }
416
- ),
417
- iter.toolCalls.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6, paddingLeft: 12 }, children: iter.toolCalls.map((tc) => /* @__PURE__ */ jsx(ToolCallCard, { invocation: tc, onClick: onToolCallClick }, tc.id)) })
418
- ] });
424
+ const key = `${turnIndex}.${iter.index}`;
425
+ return /* @__PURE__ */ jsxs(
426
+ "div",
427
+ {
428
+ "data-iter-key": key,
429
+ "data-turn-index": turnIndex,
430
+ "data-iter-index": iter.index,
431
+ style: {
432
+ display: "flex",
433
+ flexDirection: "column",
434
+ gap: 6,
435
+ // When the parent adds data-iter-selected (via IterationStrip
436
+ // click), pulse a soft ring using the accent color. Subtle so
437
+ // the chat itself stays readable.
438
+ padding: 8,
439
+ margin: -8,
440
+ borderRadius: t.radius,
441
+ outline: "2px solid transparent",
442
+ outlineOffset: 2,
443
+ transition: "outline-color 180ms ease, background 180ms ease"
444
+ },
445
+ children: [
446
+ /* @__PURE__ */ jsx(IterationBadge, { iter }),
447
+ iter.assistantContent && /* @__PURE__ */ jsx(
448
+ "div",
449
+ {
450
+ style: {
451
+ background: t.bgElev,
452
+ border: `1px solid ${t.border}`,
453
+ borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,
454
+ padding: "10px 14px",
455
+ maxWidth: 820,
456
+ whiteSpace: "pre-wrap"
457
+ },
458
+ children: iter.assistantContent
459
+ }
460
+ ),
461
+ iter.toolCalls.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6, paddingLeft: 12 }, children: iter.toolCalls.map((tc) => /* @__PURE__ */ jsx(ToolCallCard, { invocation: tc, onClick: onToolCallClick }, tc.id)) })
462
+ ]
463
+ }
464
+ );
419
465
  }
420
466
  function IterationBadge({ iter }) {
421
467
  const t = useLensTheme();
@@ -850,6 +896,12 @@ function AgentLens({
850
896
  fontFamily: t.fontSans
851
897
  },
852
898
  children: [
899
+ /* @__PURE__ */ jsx4("style", { children: `
900
+ [data-iter-selected="true"] {
901
+ outline-color: currentColor !important;
902
+ background: color-mix(in srgb, currentColor 8%, transparent);
903
+ }
904
+ ` }),
853
905
  /* @__PURE__ */ jsx4("div", { style: { gridArea: "strip" }, children: /* @__PURE__ */ jsx4(
854
906
  IterationStrip,
855
907
  {
@@ -863,6 +915,7 @@ function AgentLens({
863
915
  {
864
916
  timeline,
865
917
  onToolCallClick: handleToolClick,
918
+ selectedIterKey,
866
919
  ...derivedSystemPrompt && { systemPrompt: derivedSystemPrompt }
867
920
  }
868
921
  ) }),
@@ -1071,9 +1124,9 @@ var LiveTimelineBuilder = class {
1071
1124
  };
1072
1125
 
1073
1126
  // src/adapters/useLiveTimeline.ts
1074
- import { useCallback, useMemo as useMemo2, useRef, useState as useState3 } from "react";
1127
+ import { useCallback, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
1075
1128
  function useLiveTimeline() {
1076
- const builderRef = useRef(null);
1129
+ const builderRef = useRef2(null);
1077
1130
  if (!builderRef.current) builderRef.current = new LiveTimelineBuilder();
1078
1131
  const builder = builderRef.current;
1079
1132
  const [timeline, setTimeline] = useState3(() => builder.getTimeline());
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AgentLens.tsx","../src/adapters/fromAgentSnapshot.ts","../src/panels/MessagesPanel.tsx","../src/theme/useLensTheme.ts","../src/panels/IterationStrip.tsx","../src/panels/ToolCallInspector.tsx","../src/adapters/LiveTimelineBuilder.ts","../src/adapters/useLiveTimeline.ts"],"sourcesContent":["/**\n * <AgentLens> — top-level shell.\n *\n * Composes the three v0.1 surfaces: IterationStrip (top), MessagesPanel\n * (center, primary), ToolCallInspector (right sidebar). Selection state\n * is internal; parent apps can hook into `onToolCallClick` to drive\n * external drill-downs (e.g. open a footprint-explainable-ui drawer\n * scoped to the tool's flowchart execution).\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Usage (zero-boilerplate):\n *\n * import { AgentLens } from 'agentfootprint-lens';\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n *\n * <FootprintTheme tokens={dark ? coolDark : coolLight}>\n * <AgentLens runtimeSnapshot={agent.getSnapshot()} />\n * </FootprintTheme>\n *\n * No Lens-specific theme prop — tokens flow from the standard\n * FootprintTheme context. The drill-in drawer (explainable-ui) reads\n * the same context, so chat + trace stay in sync when the consumer\n * flips themes.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useMemo, useState } from \"react\";\nimport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\nimport type {\n AgentToolInvocation,\n AgentTimeline,\n} from \"./adapters/types\";\nimport { MessagesPanel } from \"./panels/MessagesPanel\";\nimport { IterationStrip } from \"./panels/IterationStrip\";\nimport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nimport { useLensTheme } from \"./theme/useLensTheme\";\n\nexport interface AgentLensProps {\n /**\n * Raw runtimeSnapshot from `agent.getSnapshot()`. Lens parses this\n * into an agent-shaped AgentTimeline internally. Pass `null` when a\n * run hasn't happened yet — Lens renders an empty state.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly runtimeSnapshot?: any | null;\n /**\n * Pre-parsed timeline, for callers who want to run the adapter once\n * upstream and share the result. Overrides `runtimeSnapshot` when set.\n */\n readonly timeline?: AgentTimeline;\n /**\n * Optional system prompt to render in the collapsible preamble of\n * MessagesPanel. Usually `runtimeSnapshot.sharedState.systemPrompt`\n * or the agent's configured base prompt.\n */\n readonly systemPrompt?: string;\n /**\n * Called when the user clicks a tool call in either the Inspector or\n * the inline Messages tool-call card. Parent can use this to open a\n * drawer rendering `<ExplainableShell>` from footprint-explainable-ui\n * scoped to that tool's internal flowchart execution — the\n * composition seam between Lens (agent view) and explainable-ui\n * (tool-internal view).\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function AgentLens({\n runtimeSnapshot,\n timeline: providedTimeline,\n systemPrompt,\n onToolCallClick,\n}: AgentLensProps) {\n const t = useLensTheme();\n const timeline = useMemo<AgentTimeline | null>(() => {\n if (providedTimeline) return providedTimeline;\n if (!runtimeSnapshot) return null;\n return fromAgentSnapshot(runtimeSnapshot);\n }, [providedTimeline, runtimeSnapshot]);\n\n const [selectedToolId, setSelectedToolId] = useState<string | null>(null);\n const [selectedIterKey, setSelectedIterKey] = useState<string | null>(null);\n\n function handleToolClick(inv: AgentToolInvocation) {\n setSelectedToolId(inv.id);\n setSelectedIterKey(`${inv.turnIndex}.${inv.iterationIndex}`);\n onToolCallClick?.(inv);\n }\n\n if (!timeline) {\n return (\n <div\n data-fp-lens=\"empty\"\n style={{\n padding: 32,\n color: t.textMuted,\n fontFamily: t.fontSans,\n textAlign: \"center\",\n background: t.bg,\n }}\n >\n No agent run to show yet. Pass <code>runtimeSnapshot</code> after the agent runs.\n </div>\n );\n }\n\n const derivedSystemPrompt =\n systemPrompt ??\n (typeof timeline.rawSnapshot?.sharedState?.systemPrompt === \"string\"\n ? (timeline.rawSnapshot.sharedState.systemPrompt as string)\n : undefined);\n\n return (\n <div\n data-fp-lens=\"shell\"\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 320px\",\n gridTemplateRows: \"auto 1fr\",\n gridTemplateAreas: '\"strip strip\" \"messages inspector\"',\n height: \"100%\",\n minHeight: 0,\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n }}\n >\n <div style={{ gridArea: \"strip\" }}>\n <IterationStrip\n timeline={timeline}\n selectedKey={selectedIterKey}\n onSelect={setSelectedIterKey}\n />\n </div>\n <div style={{ gridArea: \"messages\", minHeight: 0, overflow: \"hidden\" }}>\n <MessagesPanel\n timeline={timeline}\n onToolCallClick={handleToolClick}\n {...(derivedSystemPrompt && { systemPrompt: derivedSystemPrompt })}\n />\n </div>\n <div\n style={{\n gridArea: \"inspector\",\n minHeight: 0,\n overflow: \"hidden\",\n borderLeft: `1px solid ${t.border}`,\n }}\n >\n <ToolCallInspector\n timeline={timeline}\n selectedId={selectedToolId}\n onSelect={handleToolClick}\n />\n </div>\n </div>\n );\n}\n","/**\n * fromAgentSnapshot — turn an agentfootprint runtimeSnapshot into the\n * agent-shaped AgentTimeline Lens renders against.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * The raw snapshot is flowchart-shaped (stages, commitLog, subflowResults).\n * Lens needs agent-shape: turns[] → iterations[] → {messages, toolCalls,\n * decision, tokens, latency, visibleTools}. That's what this file does.\n *\n * Derivation strategy (all sources already present — no library change\n * needed):\n * • `sharedState.messages[]` — canonical conversation\n * • `commitLog` entries for `call-llm` / `streaming-call-llm` — per-iter\n * LLM request+response (model, tokens, duration, stop reason)\n * • `commitLog` entries for `execute-tool-calls` — per-iter tool outputs\n * and decision updates\n * • `sf-instructions-to-llm` snapshots — matched instruction ids +\n * injection counts per iter\n * • `sf-tools` snapshots — tool list visible to the LLM that iter\n *\n * Turn boundaries are inferred by walking `messages[]` and grouping\n * everything between user messages into one turn. Iteration boundaries\n * are the LLM call events within a turn.\n * ─────────────────────────────────────────────────────────────────────────\n */\n\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySnapshot = any;\n\nexport function fromAgentSnapshot(runtime: AnySnapshot): AgentTimeline {\n const shared = runtime?.sharedState ?? {};\n const rawMessages: RawMessage[] = shared.messages ?? [];\n const messages = rawMessages.map(normalizeMessage);\n\n const commitLog = Array.isArray(runtime?.commitLog) ? runtime.commitLog : [];\n const llmCalls = extractLLMCalls(commitLog);\n const toolExecs = extractToolExecutions(commitLog);\n const instructionEvals = extractInstructionEvals(commitLog);\n const toolResolves = extractToolResolves(commitLog);\n\n const turns = assembleTurns(messages, llmCalls, toolExecs, instructionEvals, toolResolves);\n const allTools = turns.flatMap((t) => t.iterations.flatMap((i) => i.toolCalls));\n\n return {\n turns,\n messages,\n tools: allTools,\n finalDecision: (shared.decision as Record<string, unknown>) ?? {},\n rawSnapshot: runtime,\n };\n}\n\n// ── Normalize ─────────────────────────────────────────────────────────\n\ninterface RawMessage {\n role: string;\n content: string | unknown;\n toolCalls?: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n toolCallId?: string;\n}\n\nfunction normalizeMessage(m: RawMessage): AgentMessage {\n const role = ((): AgentMessage[\"role\"] => {\n if (m.role === \"system\" || m.role === \"user\" || m.role === \"assistant\" || m.role === \"tool\")\n return m.role;\n return \"user\";\n })();\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return {\n role,\n content,\n ...(m.toolCalls?.length ? { toolCalls: m.toolCalls } : {}),\n ...(m.toolCallId ? { toolCallId: m.toolCallId } : {}),\n };\n}\n\n// ── Extract from commitLog ────────────────────────────────────────────\n\ninterface RawCommit {\n stageId?: string;\n stage?: string;\n runtimeStageId?: string;\n updates?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trace?: any;\n}\n\ninterface LLMCall {\n iterationIndex: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCallsRequested: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n}\n\nfunction extractLLMCalls(commitLog: RawCommit[]): LLMCall[] {\n const out: LLMCall[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"call-llm\" && id !== \"streaming-call-llm\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const rawResponse =\n (u[\"adapterRawResponse\"] as Record<string, unknown> | undefined) ??\n (u[\"llmResponse\"] as Record<string, unknown> | undefined);\n const usage = rawResponse?.usage as\n | { inputTokens?: number; outputTokens?: number }\n | undefined;\n out.push({\n iterationIndex: iter,\n model: rawResponse?.model as string | undefined,\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n durationMs: (u[\"callDurationMs\"] as number | undefined) ?? undefined,\n stopReason: rawResponse?.stopReason as string | undefined,\n assistantContent: (rawResponse?.content as string | undefined) ?? \"\",\n toolCallsRequested:\n (rawResponse?.toolCalls as LLMCall[\"toolCallsRequested\"] | undefined) ?? [],\n });\n }\n return out;\n}\n\ninterface ToolExec {\n iterationIndex: number;\n toolCalls: AgentToolInvocation[];\n}\n\nfunction extractToolExecutions(commitLog: RawCommit[]): ToolExec[] {\n const out: ToolExec[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"execute-tool-calls\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n // agentfootprint stores parsed tool calls + their results via\n // tool-start / tool-end emit events + the tool-role messages appended\n // to `messages`. Simplest stable derivation: walk messages right\n // after this commit and collect the tool-result entries.\n // For v0.1 we emit the tool call stubs; full resolution happens at\n // the assembler step where we have both sides in hand.\n const rawCalls = u[\"toolCalls\"] as LLMCall[\"toolCallsRequested\"] | undefined;\n const stubs: AgentToolInvocation[] = (rawCalls ?? []).map((c) => ({\n id: c.id,\n name: c.name,\n arguments: c.arguments ?? {},\n result: \"\", // filled in during assembly\n iterationIndex: iter,\n turnIndex: 0, // reassigned during assembly\n decisionUpdate: u[\"updatedDecision\"] as Record<string, unknown> | undefined,\n }));\n out.push({ iterationIndex: iter, toolCalls: stubs });\n }\n return out;\n}\n\ninterface InstructionEval {\n iterationIndex: number;\n matchedInstructions?: string[];\n promptInjectionCount: number;\n toolInjectionCount: number;\n}\n\nfunction extractInstructionEvals(commitLog: RawCommit[]): InstructionEval[] {\n const out: InstructionEval[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"evaluate-instructions\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const matchedRaw = u[\"matchedInstructions\"];\n const matched = parseMatched(matchedRaw);\n const promptInj = Array.isArray(u[\"promptInjections\"]) ? u[\"promptInjections\"].length : 0;\n const toolInj = Array.isArray(u[\"toolInjections\"]) ? u[\"toolInjections\"].length : 0;\n out.push({\n iterationIndex: iter,\n ...(matched.length > 0 && { matchedInstructions: matched }),\n promptInjectionCount: promptInj,\n toolInjectionCount: toolInj,\n });\n }\n return out;\n}\n\nfunction parseMatched(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v.filter((x) => typeof x === \"string\");\n if (typeof v === \"string\") {\n // format: \"N matched: id1, id2, id3...\"\n const m = v.match(/:\\s*(.+)/);\n if (!m) return [];\n return m[1]\n .split(\",\")\n .map((s) => s.trim().replace(/\\.{3}$/, \"\"))\n .filter(Boolean);\n }\n return [];\n}\n\ninterface ToolResolve {\n iterationIndex: number;\n visibleTools: string[];\n}\n\nfunction extractToolResolves(commitLog: RawCommit[]): ToolResolve[] {\n const out: ToolResolve[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"resolve-tools\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const descs = u[\"toolDescriptions\"] as Array<{ name: string }> | undefined;\n out.push({\n iterationIndex: iter,\n visibleTools: (descs ?? []).map((d) => d.name),\n });\n }\n return out;\n}\n\n// ── Assemble turns ────────────────────────────────────────────────────\n\nfunction assembleTurns(\n messages: AgentMessage[],\n llmCalls: LLMCall[],\n toolExecs: ToolExec[],\n instructionEvals: InstructionEval[],\n toolResolves: ToolResolve[],\n): AgentTurn[] {\n // Build a per-iteration map (flat across turns) then split by turn.\n // For a fresh agent instance, iter counts restart every turn — but\n // because commitLog is cumulative, iter numbers across commitLog are\n // monotonically increasing over the whole execution. So we group\n // iterations by the message boundary they fall in.\n //\n // Algorithm: walk messages in order. Each user message starts a new\n // turn. Each assistant message that has toolCalls (or is the final)\n // consumes the next LLM call from llmCalls. Tool-role messages that\n // follow bind to the most recent assistant message's toolCalls.\n\n const turns: AgentTurn[] = [];\n let currentTurn: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n } | null = null;\n let llmIdx = 0;\n const toolExecByIter = new Map(toolExecs.map((t) => [t.iterationIndex, t]));\n const instrByIter = new Map(instructionEvals.map((i) => [i.iterationIndex, i]));\n const visibleByIter = new Map(toolResolves.map((t) => [t.iterationIndex, t]));\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n currentTurn = {\n index: turns.length,\n userPrompt: msg.content,\n iterations: [],\n finalContent: \"\",\n };\n continue;\n }\n if (!currentTurn) continue; // skip system prompt + anything before first user\n\n if (msg.role === \"assistant\") {\n const call = llmCalls[llmIdx];\n llmIdx++;\n const iterIndex = call?.iterationIndex ?? currentTurn.iterations.length + 1;\n const exec = toolExecByIter.get(iterIndex);\n const instr = instrByIter.get(iterIndex);\n const visible = visibleByIter.get(iterIndex);\n\n const toolCalls: AgentToolInvocation[] = (exec?.toolCalls ?? []).map((tc) => ({\n ...tc,\n turnIndex: currentTurn!.index,\n }));\n\n const iteration: AgentIteration = {\n index: iterIndex,\n ...(call?.model && { model: call.model }),\n ...(call?.inputTokens !== undefined && { inputTokens: call.inputTokens }),\n ...(call?.outputTokens !== undefined && { outputTokens: call.outputTokens }),\n ...(call?.durationMs !== undefined && { durationMs: call.durationMs }),\n ...(call?.stopReason && { stopReason: call.stopReason }),\n assistantContent: call?.assistantContent ?? msg.content,\n toolCalls,\n decisionAtStart: {}, // TODO(phase-2): derive from pre-iter commit\n ...(instr?.matchedInstructions && { matchedInstructions: instr.matchedInstructions }),\n visibleTools: visible?.visibleTools ?? [],\n };\n\n currentTurn.iterations.push(iteration);\n if (!toolCalls.length) currentTurn.finalContent = iteration.assistantContent;\n continue;\n }\n\n if (msg.role === \"tool\" && msg.toolCallId) {\n // Bind the result string back to the matching tool invocation in\n // the latest iteration.\n const iter = currentTurn.iterations[currentTurn.iterations.length - 1];\n if (!iter) continue;\n const idx = iter.toolCalls.findIndex((tc) => tc.id === msg.toolCallId);\n if (idx < 0) continue;\n const updated = { ...iter.toolCalls[idx], result: msg.content };\n // Rewrite via mutation — iter is readonly at the type level but we\n // own this intermediate structure during assembly.\n (iter.toolCalls as AgentToolInvocation[])[idx] = updated;\n }\n }\n\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n return turns;\n}\n\nfunction finalizeTurn(t: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n}): AgentTurn {\n const totalInputTokens = t.iterations.reduce((s, i) => s + (i.inputTokens ?? 0), 0);\n const totalOutputTokens = t.iterations.reduce((s, i) => s + (i.outputTokens ?? 0), 0);\n const totalDurationMs = t.iterations.reduce((s, i) => s + (i.durationMs ?? 0), 0);\n return {\n index: t.index,\n userPrompt: t.userPrompt,\n iterations: t.iterations,\n finalContent: t.finalContent,\n totalInputTokens,\n totalOutputTokens,\n totalDurationMs,\n };\n}\n","/**\n * MessagesPanel — the primary Lens surface. Chat-shaped view of an agent\n * run with turn boundaries, iteration markers, and expandable tool calls.\n *\n * Data comes from `fromAgentSnapshot(runtimeSnapshot).turns`. Each turn\n * is:\n * • one user message\n * • one or more assistant iterations (each may request N tool calls)\n * • tool role bubbles bound to their assistant parent\n * • final assistant bubble\n *\n * Theme is read via `useLensTheme()` which maps FootprintTheme tokens\n * into Lens's semantic palette. Consumers get free light/dark support\n * by wrapping their app in `<FootprintTheme tokens={coolLight|coolDark}>`\n * — no Lens-specific theme API to learn.\n */\nimport { useState } from \"react\";\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface MessagesPanelProps {\n readonly timeline: AgentTimeline;\n /**\n * Called when the user clicks a tool-call card. Host app surfaces it\n * in the Tool Call Inspector. When omitted, clicking is a no-op.\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n /** Optional system-prompt text to render in the collapsible preamble. */\n readonly systemPrompt?: string;\n}\n\nexport function MessagesPanel({\n timeline,\n onToolCallClick,\n systemPrompt,\n}: MessagesPanelProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"messages-panel\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n padding: \"16px 24px\",\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n fontSize: 14,\n lineHeight: 1.55,\n minHeight: 0,\n overflow: \"auto\",\n }}\n >\n {systemPrompt && <SystemBubble text={systemPrompt} />}\n {timeline.turns.map((turn) => (\n <TurnBlock key={turn.index} turn={turn} onToolCallClick={onToolCallClick} />\n ))}\n </div>\n );\n}\n\nfunction SystemBubble({ text }: { text: string }) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = text.slice(0, 140).replace(/\\s+/g, \" \") + (text.length > 140 ? \"…\" : \"\");\n return (\n <div\n style={{\n alignSelf: \"center\",\n width: \"100%\",\n maxWidth: 880,\n border: `1px dashed ${t.border}`,\n borderRadius: t.radius,\n padding: \"8px 12px\",\n background: t.bgElev,\n fontSize: 12,\n color: t.textMuted,\n }}\n >\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: t.textMuted,\n cursor: \"pointer\",\n padding: 0,\n font: \"inherit\",\n }}\n >\n <strong>SYSTEM</strong> {open ? \"▾\" : \"▸\"} {open ? \"\" : preview}\n </button>\n {open && (\n <pre\n style={{\n marginTop: 8,\n whiteSpace: \"pre-wrap\",\n fontFamily: t.fontMono,\n fontSize: 11,\n color: t.text,\n }}\n >\n {text}\n </pre>\n )}\n </div>\n );\n}\n\nfunction TurnBlock({\n turn,\n onToolCallClick,\n}: {\n turn: AgentTurn;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <TurnHeader turn={turn} />\n <UserBubble text={turn.userPrompt} />\n {turn.iterations.map((iter) => (\n <IterationBlock key={iter.index} iter={iter} onToolCallClick={onToolCallClick} />\n ))}\n {turn.finalContent && turn.iterations.length > 0 && (\n <div style={{ fontSize: 11, color: t.textSubtle, textAlign: \"center\" }}>\n turn {turn.index + 1} final · {turn.iterations.length} iter · {turn.totalInputTokens}→\n {turn.totalOutputTokens} tok · {(turn.totalDurationMs / 1000).toFixed(1)}s\n </div>\n )}\n </div>\n );\n}\n\nfunction TurnHeader({ turn }: { turn: AgentTurn }) {\n const t = useLensTheme();\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n color: t.textSubtle,\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n }}\n >\n <div style={{ flex: 1, height: 1, background: t.border }} />\n <span>Turn {turn.index + 1}</span>\n <div style={{ flex: 1, height: 1, background: t.border }} />\n </div>\n );\n}\n\nfunction UserBubble({ text }: { text: string }) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <div\n style={{\n background: `color-mix(in srgb, ${t.accent} 18%, ${t.bgElev})`,\n border: `1px solid ${t.border}`,\n color: t.text,\n maxWidth: 720,\n padding: \"10px 14px\",\n borderRadius: `${t.radius} ${t.radius} 2px ${t.radius}`,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {text}\n </div>\n </div>\n );\n}\n\nfunction IterationBlock({\n iter,\n onToolCallClick,\n}: {\n iter: AgentIteration;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <IterationBadge iter={iter} />\n {iter.assistantContent && (\n <div\n style={{\n background: t.bgElev,\n border: `1px solid ${t.border}`,\n borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,\n padding: \"10px 14px\",\n maxWidth: 820,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {iter.assistantContent}\n </div>\n )}\n {iter.toolCalls.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, paddingLeft: 12 }}>\n {iter.toolCalls.map((tc) => (\n <ToolCallCard key={tc.id} invocation={tc} onClick={onToolCallClick} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction IterationBadge({ iter }: { iter: AgentIteration }) {\n const t = useLensTheme();\n const bits: string[] = [`iter ${iter.index}`];\n if (iter.model) bits.push(iter.model);\n if (iter.inputTokens !== undefined)\n bits.push(`${iter.inputTokens}→${iter.outputTokens ?? \"?\"} tok`);\n if (iter.durationMs !== undefined) bits.push(`${(iter.durationMs / 1000).toFixed(2)}s`);\n if (iter.stopReason) bits.push(iter.stopReason);\n return (\n <div\n style={{\n alignSelf: \"flex-start\",\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n fontFamily: t.fontMono,\n }}\n >\n {bits.join(\" · \")}\n </div>\n );\n}\n\nfunction ToolCallCard({\n invocation,\n onClick,\n}: {\n invocation: AgentToolInvocation;\n onClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = shortArgs(invocation.arguments);\n const errored = invocation.error === true;\n return (\n <div\n style={{\n border: `1px solid ${errored ? t.error : t.border}`,\n borderLeft: `3px solid ${errored ? t.error : t.accent}`,\n borderRadius: 6,\n background: t.bg,\n overflow: \"hidden\",\n }}\n >\n <div\n onClick={() => {\n setOpen((v) => !v);\n onClick?.(invocation);\n }}\n style={{\n padding: \"8px 12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {invocation.name}\n </span>\n <span style={{ color: t.textMuted }}>({preview})</span>\n <span style={{ flex: 1 }} />\n {invocation.decisionUpdate && Object.keys(invocation.decisionUpdate).length > 0 && (\n <span\n style={{\n fontSize: 10,\n padding: \"1px 6px\",\n borderRadius: 3,\n background: `color-mix(in srgb, ${t.warning} 20%, transparent)`,\n color: t.warning,\n fontFamily: t.fontSans,\n fontWeight: 600,\n textTransform: \"uppercase\",\n }}\n >\n decisionUpdate\n </span>\n )}\n <span style={{ color: t.textSubtle }}>{open ? \"▾\" : \"▸\"}</span>\n </div>\n {open && (\n <div style={{ padding: \"8px 12px\", borderTop: `1px solid ${t.border}` }}>\n <Label t={t}>args</Label>\n <JsonBlock value={invocation.arguments} />\n {invocation.result && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n result\n </Label>\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: errored ? t.error : t.text,\n maxHeight: 280,\n overflow: \"auto\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {invocation.result}\n </pre>\n </>\n )}\n {invocation.decisionUpdate &&\n Object.keys(invocation.decisionUpdate).length > 0 && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n decisionUpdate\n </Label>\n <JsonBlock value={invocation.decisionUpdate} />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction Label({\n t,\n children,\n style,\n}: {\n t: ReturnType<typeof useLensTheme>;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) {\n return (\n <div\n style={{\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n marginBottom: 4,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction JsonBlock({ value }: { value: unknown }) {\n const t = useLensTheme();\n return (\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: t.text,\n maxHeight: 200,\n overflow: \"auto\",\n }}\n >\n {JSON.stringify(value, null, 2)}\n </pre>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"\";\n if (keys.length === 1) {\n const v = args[keys[0]];\n if (typeof v === \"string\" && v.length < 40) return `${keys[0]}: \"${v}\"`;\n }\n return keys.join(\", \");\n}\n\nexport { ToolCallCard };\n\nfunction _assertUnused(_: AgentMessage) {\n // Exported type is referenced from ./index.ts; keeping the import\n // for bundler tree-shaking consistency without introducing a new\n // linter warning on a \"used-elsewhere\" type import.\n void _;\n}\n_assertUnused;\n","/**\n * useLensTheme — single source of truth for Lens colors + sizing.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Theme pass-through contract (IMPORTANT for consumers):\n *\n * Lens does NOT invent its own theme system. It reads tokens from the\n * FootprintTheme context already defined in `footprint-explainable-ui`.\n * A consumer app that wraps its tree in:\n *\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n * <FootprintTheme tokens={theme === 'light' ? coolLight : coolDark}>\n * <AgentLens runtimeSnapshot={snap} />\n * </FootprintTheme>\n *\n * …gets both Lens AND the drill-down explainable-ui drawer themed from the\n * same token bag. No separate `theme` prop, no duplicate palette, no\n * drift between the two views when the user flips light/dark.\n *\n * If no FootprintTheme provider is mounted, Lens falls back to cool-dark\n * defaults — the same defaults explainable-ui uses, so it looks correct\n * out of the box without configuration.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useFootprintTheme, coolDark } from \"footprint-explainable-ui\";\nimport type { ThemeTokens } from \"footprint-explainable-ui\";\n\n/**\n * The resolved color palette + sizing tokens Lens renders against.\n * Always defined — callers never need to null-check.\n */\nexport interface LensTheme {\n readonly bg: string;\n readonly bgElev: string;\n readonly bgHover: string;\n readonly border: string;\n readonly borderStrong: string;\n readonly text: string;\n readonly textMuted: string;\n readonly textSubtle: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly error: string;\n readonly fontSans: string;\n readonly fontMono: string;\n readonly radius: string;\n}\n\n/**\n * Read tokens from FootprintTheme context (if present) and map them\n * into Lens's semantic palette. Missing tokens fall back to coolDark.\n */\nexport function useLensTheme(): LensTheme {\n const ctx = useFootprintTheme();\n return resolve(ctx);\n}\n\n/** Pure mapping — exported for unit tests + non-hook call sites. */\nexport function resolve(tokens: ThemeTokens | undefined): LensTheme {\n const t = tokens ?? {};\n const c = t.colors ?? coolDark.colors ?? {};\n const fallback = coolDark.colors ?? {};\n return {\n bg: c.bgPrimary ?? fallback.bgPrimary ?? \"#0f172a\",\n bgElev: c.bgSecondary ?? fallback.bgSecondary ?? \"#1e293b\",\n bgHover: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n border: c.border ?? fallback.border ?? \"#334155\",\n borderStrong: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n text: c.textPrimary ?? fallback.textPrimary ?? \"#f8fafc\",\n textMuted: c.textSecondary ?? fallback.textSecondary ?? \"#94a3b8\",\n textSubtle: c.textMuted ?? fallback.textMuted ?? \"#64748b\",\n accent: c.primary ?? fallback.primary ?? \"#6366f1\",\n success: c.success ?? fallback.success ?? \"#22c55e\",\n warning: c.warning ?? fallback.warning ?? \"#f59e0b\",\n error: c.error ?? fallback.error ?? \"#ef4444\",\n fontSans: t.fontFamily?.sans ?? coolDark.fontFamily?.sans ?? \"system-ui, sans-serif\",\n fontMono: t.fontFamily?.mono ?? coolDark.fontFamily?.mono ?? \"ui-monospace, monospace\",\n radius: t.radius ?? coolDark.radius ?? \"8px\",\n };\n}\n","/**\n * IterationStrip — horizontal ribbon of LLM calls across the run, one\n * chip per iteration. Click to scroll/pin MessagesPanel to that iter.\n *\n * v0.1 is display-only with the selection callback; parent app owns the\n * scroll behavior.\n */\nimport type { AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface IterationStripProps {\n readonly timeline: AgentTimeline;\n readonly selectedKey?: string | null;\n readonly onSelect?: (key: string) => void;\n}\n\nexport function IterationStrip({ timeline, selectedKey, onSelect }: IterationStripProps) {\n const t = useLensTheme();\n const chips = timeline.turns.flatMap((turn) =>\n turn.iterations.map((iter) => ({\n key: `${turn.index}.${iter.index}`,\n turn: turn.index + 1,\n iter: iter.index,\n label: chipLabel(iter),\n tools: iter.toolCalls.length,\n durationMs: iter.durationMs ?? 0,\n stopReason: iter.stopReason,\n })),\n );\n\n return (\n <div\n data-fp-lens=\"iteration-strip\"\n style={{\n display: \"flex\",\n gap: 4,\n padding: \"8px 12px\",\n overflowX: \"auto\",\n borderBottom: `1px solid ${t.border}`,\n background: t.bgElev,\n }}\n >\n {chips.length === 0 && (\n <span style={{ color: t.textSubtle, fontSize: 11 }}>No iterations yet.</span>\n )}\n {chips.map((c) => {\n const active = c.key === selectedKey;\n const isFinal = c.stopReason === \"stop\" || c.stopReason === \"end_turn\";\n return (\n <button\n key={c.key}\n onClick={() => onSelect?.(c.key)}\n style={{\n background: active ? t.accent : \"transparent\",\n color: active ? \"#fff\" : t.textMuted,\n border: `1px solid ${active ? t.accent : t.border}`,\n borderRadius: 4,\n padding: \"4px 8px\",\n fontSize: 11,\n fontFamily: \"ui-monospace, monospace\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n title={`turn ${c.turn} · iter ${c.iter} · ${c.tools} tool call${\n c.tools === 1 ? \"\" : \"s\"\n }${c.stopReason ? ` · ${c.stopReason}` : \"\"}`}\n >\n t{c.turn}.i{c.iter} · {c.label} {isFinal ? \"✓\" : \"\"}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction chipLabel(iter: { toolCalls: readonly unknown[]; durationMs?: number }): string {\n const d = iter.durationMs ?? 0;\n const secs = d >= 1000 ? `${(d / 1000).toFixed(1)}s` : `${Math.round(d)}ms`;\n const toolBit = iter.toolCalls.length > 0 ? `${iter.toolCalls.length}t` : \"final\";\n return `${secs} · ${toolBit}`;\n}\n","/**\n * ToolCallInspector — flat sidebar list of every tool invocation in the\n * run. Primary workflow: skim for errors, click to focus a specific\n * call (mirrors MessagesPanel's selection).\n *\n * v0.1 minimum — name, args preview, latency, error badge. Drill-in to\n * the tool's underlying footprintjs flowchart via explainable-ui is a\n * phase-2 item (requires surfacing per-tool sub-snapshots).\n */\nimport type { AgentToolInvocation, AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface ToolCallInspectorProps {\n readonly timeline: AgentTimeline;\n readonly selectedId?: string | null;\n readonly onSelect?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function ToolCallInspector({\n timeline,\n selectedId,\n onSelect,\n}: ToolCallInspectorProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"tool-call-inspector\"\n style={{\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n display: \"flex\",\n flexDirection: \"column\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"10px 14px\",\n borderBottom: `1px solid ${t.border}`,\n fontSize: 11,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n background: t.bgElev,\n }}\n >\n Tool calls · {timeline.tools.length}\n </div>\n <div style={{ overflow: \"auto\", flex: 1 }}>\n {timeline.tools.length === 0 && (\n <div style={{ padding: 14, color: t.textSubtle, fontSize: 12 }}>\n No tool calls yet.\n </div>\n )}\n {timeline.tools.map((tc) => {\n const active = tc.id === selectedId;\n const errored = tc.error === true;\n return (\n <button\n key={tc.id}\n onClick={() => onSelect?.(tc)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n textAlign: \"left\",\n padding: \"8px 12px\",\n background: active ? t.bgHover : \"transparent\",\n border: \"none\",\n borderLeft: `3px solid ${\n active ? t.accent : errored ? t.error : \"transparent\"\n }`,\n borderBottom: `1px solid ${t.border}`,\n color: t.text,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: 8,\n alignItems: \"baseline\",\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {tc.name}\n </span>\n <span\n style={{ color: t.textSubtle, fontSize: 10, marginLeft: \"auto\" }}\n >\n t{tc.turnIndex + 1}.i{tc.iterationIndex}\n {tc.durationMs !== undefined && ` · ${Math.round(tc.durationMs)}ms`}\n </span>\n </div>\n <div\n style={{\n fontSize: 10,\n color: t.textMuted,\n marginTop: 2,\n fontFamily: t.fontMono,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {shortArgs(tc.arguments)}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"— no args —\";\n return keys\n .map((k) => {\n const v = args[k];\n if (typeof v === \"string\") return `${k}: \"${v.length > 20 ? v.slice(0, 20) + \"…\" : v}\"`;\n if (typeof v === \"number\" || typeof v === \"boolean\") return `${k}: ${v}`;\n return `${k}: …`;\n })\n .join(\", \");\n}\n","/**\n * LiveTimelineBuilder — ingests agentfootprint emit events AS THEY HAPPEN\n * and accumulates the `AgentTimeline` incrementally. Zero post-processing:\n * every field is set as the corresponding event fires during traversal.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Why this exists\n *\n * footprintjs's core principle: \"collect during traversal, never post-\n * process.\" Walking `commitLog` after the run to reconstruct the agent\n * view is valid but it re-traverses data that already flowed past. The\n * Builder is the correct shape — it's a recorder that subscribes to the\n * stream of events the agent already emits and writes each field exactly\n * once, when the source-of-truth event fires.\n *\n * Consumer wiring (from a React app):\n *\n * const builder = useMemo(() => new LiveTimelineBuilder(), []);\n * const [timeline, setTimeline] = useState(builder.getTimeline());\n * // In Neo's runTurn onEvent:\n * await agent.run(prompt, {\n * onEvent: (e) => {\n * builder.ingest(e);\n * setTimeline(builder.getTimeline());\n * },\n * });\n * <AgentLens timeline={timeline} />\n *\n * Or via the `useLiveTimeline()` React hook below — same mechanics, less\n * boilerplate.\n *\n * The events consumed are all `agentfootprint.stream.*` (llm_start,\n * llm_end, tool_start, tool_end) + `agentfootprint.agent.turn_complete`.\n * User messages are captured by calling `startTurn(userPrompt)` before\n * each `agent.run()` invocation — that's the one piece the event stream\n * doesn't carry (agent.run() is where the user message enters the\n * system, not an event emission).\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// Minimal shape we need from an agent event — structural only, no direct\n// dep on agentfootprint's event type (which may evolve).\ninterface AgentEventLike {\n readonly type: string;\n readonly toolName?: string;\n readonly toolCallId?: string;\n readonly args?: Record<string, unknown>;\n readonly result?: { content?: string; error?: boolean } | string;\n readonly iteration?: number;\n readonly content?: string;\n readonly toolCallCount?: number;\n readonly model?: string;\n readonly usage?: { inputTokens?: number; outputTokens?: number };\n readonly stopReason?: string;\n readonly durationMs?: number;\n readonly iterations?: number;\n readonly reason?: string;\n}\n\ninterface MutableTurn {\n index: number;\n userPrompt: string;\n iterations: MutableIteration[];\n finalContent: string;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalDurationMs: number;\n startMs: number;\n}\n\ninterface MutableIteration {\n index: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCalls: MutableTool[];\n decisionAtStart: Record<string, unknown>;\n matchedInstructions?: string[];\n visibleTools: string[];\n startMs: number;\n}\n\ninterface MutableTool {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result: string;\n error?: boolean;\n decisionUpdate?: Record<string, unknown>;\n iterationIndex: number;\n turnIndex: number;\n durationMs?: number;\n startMs: number;\n}\n\nexport class LiveTimelineBuilder {\n private turns: MutableTurn[] = [];\n private currentTurn: MutableTurn | null = null;\n private currentIter: MutableIteration | null = null;\n private toolByCallId = new Map<string, MutableTool>();\n private messages: AgentMessage[] = [];\n private systemPrompt: string | undefined;\n private finalDecision: Record<string, unknown> = {};\n\n /**\n * Begin a new turn. Call this BEFORE `agent.run(userPrompt)` so the\n * user's prompt appears alongside the iterations it produced. Safe to\n * call even mid-conversation — it closes the previous turn cleanly.\n */\n startTurn(userPrompt: string): void {\n if (this.currentTurn) this.commitCurrentTurn();\n this.currentTurn = {\n index: this.turns.length,\n userPrompt,\n iterations: [],\n finalContent: \"\",\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalDurationMs: 0,\n startMs: Date.now(),\n };\n this.messages.push({ role: \"user\", content: userPrompt });\n }\n\n /**\n * Optional — attach the system prompt so MessagesPanel can render it\n * in the collapsible preamble. Usually set once at agent construction.\n */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n /**\n * Feed one agent stream event. Safe to call for unknown events; we\n * ignore anything we don't recognize.\n */\n ingest(event: AgentEventLike | unknown): void {\n const e = event as AgentEventLike;\n if (!e || typeof e.type !== \"string\") return;\n switch (e.type) {\n case \"llm_start\":\n case \"agentfootprint.stream.llm_start\":\n this.onLLMStart(e);\n return;\n case \"llm_end\":\n case \"agentfootprint.stream.llm_end\":\n this.onLLMEnd(e);\n return;\n case \"tool_start\":\n case \"agentfootprint.stream.tool_start\":\n this.onToolStart(e);\n return;\n case \"tool_end\":\n case \"agentfootprint.stream.tool_end\":\n this.onToolEnd(e);\n return;\n case \"turn_end\":\n case \"agentfootprint.agent.turn_complete\":\n this.commitCurrentTurn();\n return;\n default:\n return;\n }\n }\n\n private onLLMStart(e: AgentEventLike): void {\n if (!this.currentTurn) return;\n const iterNum = e.iteration ?? this.currentTurn.iterations.length + 1;\n this.currentIter = {\n index: iterNum,\n assistantContent: \"\",\n toolCalls: [],\n decisionAtStart: {},\n visibleTools: [],\n startMs: Date.now(),\n };\n this.currentTurn.iterations.push(this.currentIter);\n }\n\n private onLLMEnd(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n this.currentIter.assistantContent = e.content ?? this.currentIter.assistantContent;\n if (e.model) this.currentIter.model = e.model;\n if (e.usage?.inputTokens !== undefined) this.currentIter.inputTokens = e.usage.inputTokens;\n if (e.usage?.outputTokens !== undefined) this.currentIter.outputTokens = e.usage.outputTokens;\n if (e.stopReason) this.currentIter.stopReason = e.stopReason;\n this.currentIter.durationMs = e.durationMs ?? Date.now() - this.currentIter.startMs;\n\n // Aggregate into turn totals.\n this.currentTurn.totalInputTokens += this.currentIter.inputTokens ?? 0;\n this.currentTurn.totalOutputTokens += this.currentIter.outputTokens ?? 0;\n this.currentTurn.totalDurationMs += this.currentIter.durationMs ?? 0;\n\n // Assistant message for the chat view.\n if (this.currentIter.assistantContent) {\n this.messages.push({ role: \"assistant\", content: this.currentIter.assistantContent });\n }\n // If no tool calls follow, this iteration's content IS the turn's final answer.\n if ((e.toolCallCount ?? 0) === 0) {\n this.currentTurn.finalContent = this.currentIter.assistantContent;\n }\n }\n\n private onToolStart(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n const tool: MutableTool = {\n id: e.toolCallId ?? `tool-${this.currentIter.toolCalls.length}`,\n name: e.toolName ?? \"unknown\",\n arguments: e.args ?? {},\n result: \"\",\n iterationIndex: this.currentIter.index,\n turnIndex: this.currentTurn.index,\n startMs: Date.now(),\n };\n this.currentIter.toolCalls.push(tool);\n this.toolByCallId.set(tool.id, tool);\n }\n\n private onToolEnd(e: AgentEventLike): void {\n const tool = this.toolByCallId.get(e.toolCallId ?? \"\");\n if (!tool) return;\n const r = e.result;\n if (typeof r === \"string\") {\n tool.result = r;\n } else if (r && typeof r === \"object\") {\n tool.result = r.content ?? \"\";\n if (r.error === true) tool.error = true;\n }\n tool.durationMs = e.durationMs ?? Date.now() - tool.startMs;\n // Record the tool-role message so MessagesPanel can render it.\n this.messages.push({ role: \"tool\", content: tool.result, toolCallId: tool.id });\n }\n\n private commitCurrentTurn(): void {\n if (!this.currentTurn) return;\n this.turns.push(this.currentTurn);\n this.currentTurn = null;\n this.currentIter = null;\n }\n\n /**\n * Snapshot the current state as an immutable `AgentTimeline`. Safe to\n * call at any point — mid-run gives you the partial state so Lens can\n * live-update.\n */\n getTimeline(): AgentTimeline {\n const allTurns = [...this.turns];\n if (this.currentTurn) allTurns.push(this.currentTurn);\n const tools: AgentToolInvocation[] = [];\n const frozenTurns: AgentTurn[] = allTurns.map((t) => {\n const iterations: AgentIteration[] = t.iterations.map((i) => {\n const tcs = i.toolCalls.map((tc) => ({ ...tc } as AgentToolInvocation));\n tools.push(...tcs);\n return { ...i, toolCalls: tcs } as AgentIteration;\n });\n return { ...t, iterations } as AgentTurn;\n });\n return {\n turns: frozenTurns,\n messages: [...this.messages],\n tools,\n finalDecision: { ...this.finalDecision },\n rawSnapshot: null,\n };\n }\n\n /**\n * Fold in a final `decision` scope after the run — useful when\n * the consumer wants the Decision Ribbon (phase-2) to reflect the\n * post-run state. Safe no-op during the run itself.\n */\n setFinalDecision(decision: Record<string, unknown>): void {\n this.finalDecision = decision;\n }\n\n /** Get the optional system prompt for the Messages preamble. */\n getSystemPrompt(): string | undefined {\n return this.systemPrompt;\n }\n\n /** Wipe state. Useful when the consumer starts a fresh conversation. */\n reset(): void {\n this.turns = [];\n this.currentTurn = null;\n this.currentIter = null;\n this.toolByCallId.clear();\n this.messages = [];\n this.finalDecision = {};\n }\n}\n","/**\n * useLiveTimeline — React hook wrapper around LiveTimelineBuilder.\n *\n * The hook owns a stable builder across renders and returns:\n * • `timeline` — current state (re-renders on every `ingest` call)\n * • `ingest` — feed an agentfootprint stream event\n * • `startTurn`, `setSystemPrompt`, `setFinalDecision`, `reset` — forward methods\n *\n * Usage:\n *\n * const lens = useLiveTimeline();\n * <AgentLens timeline={lens.timeline} />\n *\n * // Before agent.run():\n * lens.startTurn(userPrompt);\n * await agent.run(userPrompt, { onEvent: lens.ingest });\n *\n * The hook keeps the agent-shaped view in sync AS events fire — Lens\n * updates incrementally during the run, not only after it completes.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { LiveTimelineBuilder } from \"./LiveTimelineBuilder\";\nimport type { AgentTimeline } from \"./types\";\n\nexport interface UseLiveTimelineResult {\n readonly timeline: AgentTimeline;\n readonly ingest: (event: unknown) => void;\n readonly startTurn: (userPrompt: string) => void;\n readonly setSystemPrompt: (prompt: string) => void;\n readonly setFinalDecision: (decision: Record<string, unknown>) => void;\n readonly reset: () => void;\n /** Escape hatch — exposed for integrations that need builder internals. */\n readonly builder: LiveTimelineBuilder;\n}\n\nexport function useLiveTimeline(): UseLiveTimelineResult {\n const builderRef = useRef<LiveTimelineBuilder | null>(null);\n if (!builderRef.current) builderRef.current = new LiveTimelineBuilder();\n const builder = builderRef.current;\n\n const [timeline, setTimeline] = useState<AgentTimeline>(() => builder.getTimeline());\n\n const sync = useCallback(() => {\n setTimeline(builder.getTimeline());\n }, [builder]);\n\n const ingest = useCallback(\n (event: unknown) => {\n builder.ingest(event);\n sync();\n },\n [builder, sync],\n );\n\n const startTurn = useCallback(\n (userPrompt: string) => {\n builder.startTurn(userPrompt);\n sync();\n },\n [builder, sync],\n );\n\n const setSystemPrompt = useCallback(\n (prompt: string) => {\n builder.setSystemPrompt(prompt);\n sync();\n },\n [builder, sync],\n );\n\n const setFinalDecision = useCallback(\n (decision: Record<string, unknown>) => {\n builder.setFinalDecision(decision);\n sync();\n },\n [builder, sync],\n );\n\n const reset = useCallback(() => {\n builder.reset();\n sync();\n }, [builder, sync]);\n\n return useMemo(\n () => ({ timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder }),\n [timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder],\n );\n}\n"],"mappings":"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","names":["useState","jsx","jsxs","jsx","jsxs","shortArgs","jsx","jsxs","useState","useMemo","useState","useState","useMemo"]}
1
+ {"version":3,"sources":["../src/AgentLens.tsx","../src/adapters/fromAgentSnapshot.ts","../src/panels/MessagesPanel.tsx","../src/theme/useLensTheme.ts","../src/panels/IterationStrip.tsx","../src/panels/ToolCallInspector.tsx","../src/adapters/LiveTimelineBuilder.ts","../src/adapters/useLiveTimeline.ts"],"sourcesContent":["/**\n * <AgentLens> — top-level shell.\n *\n * Composes the three v0.1 surfaces: IterationStrip (top), MessagesPanel\n * (center, primary), ToolCallInspector (right sidebar). Selection state\n * is internal; parent apps can hook into `onToolCallClick` to drive\n * external drill-downs (e.g. open a footprint-explainable-ui drawer\n * scoped to the tool's flowchart execution).\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Usage (zero-boilerplate):\n *\n * import { AgentLens } from 'agentfootprint-lens';\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n *\n * <FootprintTheme tokens={dark ? coolDark : coolLight}>\n * <AgentLens runtimeSnapshot={agent.getSnapshot()} />\n * </FootprintTheme>\n *\n * No Lens-specific theme prop — tokens flow from the standard\n * FootprintTheme context. The drill-in drawer (explainable-ui) reads\n * the same context, so chat + trace stay in sync when the consumer\n * flips themes.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useMemo, useState } from \"react\";\nimport { fromAgentSnapshot } from \"./adapters/fromAgentSnapshot\";\nimport type {\n AgentToolInvocation,\n AgentTimeline,\n} from \"./adapters/types\";\nimport { MessagesPanel } from \"./panels/MessagesPanel\";\nimport { IterationStrip } from \"./panels/IterationStrip\";\nimport { ToolCallInspector } from \"./panels/ToolCallInspector\";\nimport { useLensTheme } from \"./theme/useLensTheme\";\n\nexport interface AgentLensProps {\n /**\n * Raw runtimeSnapshot from `agent.getSnapshot()`. Lens parses this\n * into an agent-shaped AgentTimeline internally. Pass `null` when a\n * run hasn't happened yet — Lens renders an empty state.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly runtimeSnapshot?: any | null;\n /**\n * Pre-parsed timeline, for callers who want to run the adapter once\n * upstream and share the result. Overrides `runtimeSnapshot` when set.\n */\n readonly timeline?: AgentTimeline;\n /**\n * Optional system prompt to render in the collapsible preamble of\n * MessagesPanel. Usually `runtimeSnapshot.sharedState.systemPrompt`\n * or the agent's configured base prompt.\n */\n readonly systemPrompt?: string;\n /**\n * Called when the user clicks a tool call in either the Inspector or\n * the inline Messages tool-call card. Parent can use this to open a\n * drawer rendering `<ExplainableShell>` from footprint-explainable-ui\n * scoped to that tool's internal flowchart execution — the\n * composition seam between Lens (agent view) and explainable-ui\n * (tool-internal view).\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function AgentLens({\n runtimeSnapshot,\n timeline: providedTimeline,\n systemPrompt,\n onToolCallClick,\n}: AgentLensProps) {\n const t = useLensTheme();\n const timeline = useMemo<AgentTimeline | null>(() => {\n if (providedTimeline) return providedTimeline;\n if (!runtimeSnapshot) return null;\n return fromAgentSnapshot(runtimeSnapshot);\n }, [providedTimeline, runtimeSnapshot]);\n\n const [selectedToolId, setSelectedToolId] = useState<string | null>(null);\n const [selectedIterKey, setSelectedIterKey] = useState<string | null>(null);\n\n function handleToolClick(inv: AgentToolInvocation) {\n setSelectedToolId(inv.id);\n setSelectedIterKey(`${inv.turnIndex}.${inv.iterationIndex}`);\n onToolCallClick?.(inv);\n }\n\n if (!timeline) {\n return (\n <div\n data-fp-lens=\"empty\"\n style={{\n padding: 32,\n color: t.textMuted,\n fontFamily: t.fontSans,\n textAlign: \"center\",\n background: t.bg,\n }}\n >\n No agent run to show yet. Pass <code>runtimeSnapshot</code> after the agent runs.\n </div>\n );\n }\n\n const derivedSystemPrompt =\n systemPrompt ??\n (typeof timeline.rawSnapshot?.sharedState?.systemPrompt === \"string\"\n ? (timeline.rawSnapshot.sharedState.systemPrompt as string)\n : undefined);\n\n return (\n <div\n data-fp-lens=\"shell\"\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 320px\",\n gridTemplateRows: \"auto 1fr\",\n gridTemplateAreas: '\"strip strip\" \"messages inspector\"',\n height: \"100%\",\n minHeight: 0,\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n }}\n >\n {/* One-off stylesheet for the selected-iter pulse. Inline-style can't\n target a data attribute, and this rule is stable (doesn't depend\n on tokens — `currentColor` picks up whatever text color the\n active theme resolves). */}\n <style>{`\n [data-iter-selected=\"true\"] {\n outline-color: currentColor !important;\n background: color-mix(in srgb, currentColor 8%, transparent);\n }\n `}</style>\n <div style={{ gridArea: \"strip\" }}>\n <IterationStrip\n timeline={timeline}\n selectedKey={selectedIterKey}\n onSelect={setSelectedIterKey}\n />\n </div>\n <div style={{ gridArea: \"messages\", minHeight: 0, overflow: \"hidden\" }}>\n <MessagesPanel\n timeline={timeline}\n onToolCallClick={handleToolClick}\n selectedIterKey={selectedIterKey}\n {...(derivedSystemPrompt && { systemPrompt: derivedSystemPrompt })}\n />\n </div>\n <div\n style={{\n gridArea: \"inspector\",\n minHeight: 0,\n overflow: \"hidden\",\n borderLeft: `1px solid ${t.border}`,\n }}\n >\n <ToolCallInspector\n timeline={timeline}\n selectedId={selectedToolId}\n onSelect={handleToolClick}\n />\n </div>\n </div>\n );\n}\n","/**\n * fromAgentSnapshot — turn an agentfootprint runtimeSnapshot into the\n * agent-shaped AgentTimeline Lens renders against.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * The raw snapshot is flowchart-shaped (stages, commitLog, subflowResults).\n * Lens needs agent-shape: turns[] → iterations[] → {messages, toolCalls,\n * decision, tokens, latency, visibleTools}. That's what this file does.\n *\n * Derivation strategy (all sources already present — no library change\n * needed):\n * • `sharedState.messages[]` — canonical conversation\n * • `commitLog` entries for `call-llm` / `streaming-call-llm` — per-iter\n * LLM request+response (model, tokens, duration, stop reason)\n * • `commitLog` entries for `execute-tool-calls` — per-iter tool outputs\n * and decision updates\n * • `sf-instructions-to-llm` snapshots — matched instruction ids +\n * injection counts per iter\n * • `sf-tools` snapshots — tool list visible to the LLM that iter\n *\n * Turn boundaries are inferred by walking `messages[]` and grouping\n * everything between user messages into one turn. Iteration boundaries\n * are the LLM call events within a turn.\n * ─────────────────────────────────────────────────────────────────────────\n */\n\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySnapshot = any;\n\nexport function fromAgentSnapshot(runtime: AnySnapshot): AgentTimeline {\n const shared = runtime?.sharedState ?? {};\n const rawMessages: RawMessage[] = shared.messages ?? [];\n const messages = rawMessages.map(normalizeMessage);\n\n const commitLog = Array.isArray(runtime?.commitLog) ? runtime.commitLog : [];\n const llmCalls = extractLLMCalls(commitLog);\n const toolExecs = extractToolExecutions(commitLog);\n const instructionEvals = extractInstructionEvals(commitLog);\n const toolResolves = extractToolResolves(commitLog);\n\n const turns = assembleTurns(messages, llmCalls, toolExecs, instructionEvals, toolResolves);\n const allTools = turns.flatMap((t) => t.iterations.flatMap((i) => i.toolCalls));\n\n return {\n turns,\n messages,\n tools: allTools,\n finalDecision: (shared.decision as Record<string, unknown>) ?? {},\n rawSnapshot: runtime,\n };\n}\n\n// ── Normalize ─────────────────────────────────────────────────────────\n\ninterface RawMessage {\n role: string;\n content: string | unknown;\n toolCalls?: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n toolCallId?: string;\n}\n\nfunction normalizeMessage(m: RawMessage): AgentMessage {\n const role = ((): AgentMessage[\"role\"] => {\n if (m.role === \"system\" || m.role === \"user\" || m.role === \"assistant\" || m.role === \"tool\")\n return m.role;\n return \"user\";\n })();\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n return {\n role,\n content,\n ...(m.toolCalls?.length ? { toolCalls: m.toolCalls } : {}),\n ...(m.toolCallId ? { toolCallId: m.toolCallId } : {}),\n };\n}\n\n// ── Extract from commitLog ────────────────────────────────────────────\n\ninterface RawCommit {\n stageId?: string;\n stage?: string;\n runtimeStageId?: string;\n updates?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trace?: any;\n}\n\ninterface LLMCall {\n iterationIndex: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCallsRequested: Array<{ id: string; name: string; arguments: Record<string, unknown> }>;\n}\n\nfunction extractLLMCalls(commitLog: RawCommit[]): LLMCall[] {\n const out: LLMCall[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"call-llm\" && id !== \"streaming-call-llm\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const rawResponse =\n (u[\"adapterRawResponse\"] as Record<string, unknown> | undefined) ??\n (u[\"llmResponse\"] as Record<string, unknown> | undefined);\n const usage = rawResponse?.usage as\n | { inputTokens?: number; outputTokens?: number }\n | undefined;\n out.push({\n iterationIndex: iter,\n model: rawResponse?.model as string | undefined,\n inputTokens: usage?.inputTokens,\n outputTokens: usage?.outputTokens,\n durationMs: (u[\"callDurationMs\"] as number | undefined) ?? undefined,\n stopReason: rawResponse?.stopReason as string | undefined,\n assistantContent: (rawResponse?.content as string | undefined) ?? \"\",\n toolCallsRequested:\n (rawResponse?.toolCalls as LLMCall[\"toolCallsRequested\"] | undefined) ?? [],\n });\n }\n return out;\n}\n\ninterface ToolExec {\n iterationIndex: number;\n toolCalls: AgentToolInvocation[];\n}\n\nfunction extractToolExecutions(commitLog: RawCommit[]): ToolExec[] {\n const out: ToolExec[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"execute-tool-calls\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n // agentfootprint stores parsed tool calls + their results via\n // tool-start / tool-end emit events + the tool-role messages appended\n // to `messages`. Simplest stable derivation: walk messages right\n // after this commit and collect the tool-result entries.\n // For v0.1 we emit the tool call stubs; full resolution happens at\n // the assembler step where we have both sides in hand.\n const rawCalls = u[\"toolCalls\"] as LLMCall[\"toolCallsRequested\"] | undefined;\n const stubs: AgentToolInvocation[] = (rawCalls ?? []).map((c) => ({\n id: c.id,\n name: c.name,\n arguments: c.arguments ?? {},\n result: \"\", // filled in during assembly\n iterationIndex: iter,\n turnIndex: 0, // reassigned during assembly\n decisionUpdate: u[\"updatedDecision\"] as Record<string, unknown> | undefined,\n }));\n out.push({ iterationIndex: iter, toolCalls: stubs });\n }\n return out;\n}\n\ninterface InstructionEval {\n iterationIndex: number;\n matchedInstructions?: string[];\n promptInjectionCount: number;\n toolInjectionCount: number;\n}\n\nfunction extractInstructionEvals(commitLog: RawCommit[]): InstructionEval[] {\n const out: InstructionEval[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"evaluate-instructions\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const matchedRaw = u[\"matchedInstructions\"];\n const matched = parseMatched(matchedRaw);\n const promptInj = Array.isArray(u[\"promptInjections\"]) ? u[\"promptInjections\"].length : 0;\n const toolInj = Array.isArray(u[\"toolInjections\"]) ? u[\"toolInjections\"].length : 0;\n out.push({\n iterationIndex: iter,\n ...(matched.length > 0 && { matchedInstructions: matched }),\n promptInjectionCount: promptInj,\n toolInjectionCount: toolInj,\n });\n }\n return out;\n}\n\nfunction parseMatched(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v.filter((x) => typeof x === \"string\");\n if (typeof v === \"string\") {\n // format: \"N matched: id1, id2, id3...\"\n const m = v.match(/:\\s*(.+)/);\n if (!m) return [];\n return m[1]\n .split(\",\")\n .map((s) => s.trim().replace(/\\.{3}$/, \"\"))\n .filter(Boolean);\n }\n return [];\n}\n\ninterface ToolResolve {\n iterationIndex: number;\n visibleTools: string[];\n}\n\nfunction extractToolResolves(commitLog: RawCommit[]): ToolResolve[] {\n const out: ToolResolve[] = [];\n let iter = 0;\n for (const entry of commitLog) {\n const id = entry.stageId ?? \"\";\n if (id !== \"resolve-tools\") continue;\n iter++;\n const u = (entry.updates ?? {}) as Record<string, unknown>;\n const descs = u[\"toolDescriptions\"] as Array<{ name: string }> | undefined;\n out.push({\n iterationIndex: iter,\n visibleTools: (descs ?? []).map((d) => d.name),\n });\n }\n return out;\n}\n\n// ── Assemble turns ────────────────────────────────────────────────────\n\nfunction assembleTurns(\n messages: AgentMessage[],\n llmCalls: LLMCall[],\n toolExecs: ToolExec[],\n instructionEvals: InstructionEval[],\n toolResolves: ToolResolve[],\n): AgentTurn[] {\n // Build a per-iteration map (flat across turns) then split by turn.\n // For a fresh agent instance, iter counts restart every turn — but\n // because commitLog is cumulative, iter numbers across commitLog are\n // monotonically increasing over the whole execution. So we group\n // iterations by the message boundary they fall in.\n //\n // Algorithm: walk messages in order. Each user message starts a new\n // turn. Each assistant message that has toolCalls (or is the final)\n // consumes the next LLM call from llmCalls. Tool-role messages that\n // follow bind to the most recent assistant message's toolCalls.\n\n const turns: AgentTurn[] = [];\n let currentTurn: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n } | null = null;\n let llmIdx = 0;\n const toolExecByIter = new Map(toolExecs.map((t) => [t.iterationIndex, t]));\n const instrByIter = new Map(instructionEvals.map((i) => [i.iterationIndex, i]));\n const visibleByIter = new Map(toolResolves.map((t) => [t.iterationIndex, t]));\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n currentTurn = {\n index: turns.length,\n userPrompt: msg.content,\n iterations: [],\n finalContent: \"\",\n };\n continue;\n }\n if (!currentTurn) continue; // skip system prompt + anything before first user\n\n if (msg.role === \"assistant\") {\n const call = llmCalls[llmIdx];\n llmIdx++;\n const iterIndex = call?.iterationIndex ?? currentTurn.iterations.length + 1;\n const exec = toolExecByIter.get(iterIndex);\n const instr = instrByIter.get(iterIndex);\n const visible = visibleByIter.get(iterIndex);\n\n const toolCalls: AgentToolInvocation[] = (exec?.toolCalls ?? []).map((tc) => ({\n ...tc,\n turnIndex: currentTurn!.index,\n }));\n\n const iteration: AgentIteration = {\n index: iterIndex,\n ...(call?.model && { model: call.model }),\n ...(call?.inputTokens !== undefined && { inputTokens: call.inputTokens }),\n ...(call?.outputTokens !== undefined && { outputTokens: call.outputTokens }),\n ...(call?.durationMs !== undefined && { durationMs: call.durationMs }),\n ...(call?.stopReason && { stopReason: call.stopReason }),\n assistantContent: call?.assistantContent ?? msg.content,\n toolCalls,\n decisionAtStart: {}, // TODO(phase-2): derive from pre-iter commit\n ...(instr?.matchedInstructions && { matchedInstructions: instr.matchedInstructions }),\n visibleTools: visible?.visibleTools ?? [],\n };\n\n currentTurn.iterations.push(iteration);\n if (!toolCalls.length) currentTurn.finalContent = iteration.assistantContent;\n continue;\n }\n\n if (msg.role === \"tool\" && msg.toolCallId) {\n // Bind the result string back to the matching tool invocation in\n // the latest iteration.\n const iter = currentTurn.iterations[currentTurn.iterations.length - 1];\n if (!iter) continue;\n const idx = iter.toolCalls.findIndex((tc) => tc.id === msg.toolCallId);\n if (idx < 0) continue;\n const updated = { ...iter.toolCalls[idx], result: msg.content };\n // Rewrite via mutation — iter is readonly at the type level but we\n // own this intermediate structure during assembly.\n (iter.toolCalls as AgentToolInvocation[])[idx] = updated;\n }\n }\n\n if (currentTurn) turns.push(finalizeTurn(currentTurn));\n return turns;\n}\n\nfunction finalizeTurn(t: {\n index: number;\n userPrompt: string;\n iterations: AgentIteration[];\n finalContent: string;\n}): AgentTurn {\n const totalInputTokens = t.iterations.reduce((s, i) => s + (i.inputTokens ?? 0), 0);\n const totalOutputTokens = t.iterations.reduce((s, i) => s + (i.outputTokens ?? 0), 0);\n const totalDurationMs = t.iterations.reduce((s, i) => s + (i.durationMs ?? 0), 0);\n return {\n index: t.index,\n userPrompt: t.userPrompt,\n iterations: t.iterations,\n finalContent: t.finalContent,\n totalInputTokens,\n totalOutputTokens,\n totalDurationMs,\n };\n}\n","/**\n * MessagesPanel — the primary Lens surface. Chat-shaped view of an agent\n * run with turn boundaries, iteration markers, and expandable tool calls.\n *\n * Data comes from `fromAgentSnapshot(runtimeSnapshot).turns`. Each turn\n * is:\n * • one user message\n * • one or more assistant iterations (each may request N tool calls)\n * • tool role bubbles bound to their assistant parent\n * • final assistant bubble\n *\n * Theme is read via `useLensTheme()` which maps FootprintTheme tokens\n * into Lens's semantic palette. Consumers get free light/dark support\n * by wrapping their app in `<FootprintTheme tokens={coolLight|coolDark}>`\n * — no Lens-specific theme API to learn.\n */\nimport { useEffect, useRef, useState } from \"react\";\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface MessagesPanelProps {\n readonly timeline: AgentTimeline;\n /**\n * Called when the user clicks a tool-call card. Host app surfaces it\n * in the Tool Call Inspector. When omitted, clicking is a no-op.\n */\n readonly onToolCallClick?: (invocation: AgentToolInvocation) => void;\n /** Optional system-prompt text to render in the collapsible preamble. */\n readonly systemPrompt?: string;\n /**\n * The currently-selected iteration key in the parent shell, format\n * `\"<turnIndex>.<iterIndex>\"` (e.g. `\"0.3\"` for turn 1, iter 3).\n * When this changes, the panel scrolls the matching iteration block\n * into view and flashes a highlight for 1.2s so the user sees the\n * jump. No-op when undefined.\n */\n readonly selectedIterKey?: string | null;\n}\n\nexport function MessagesPanel({\n timeline,\n onToolCallClick,\n systemPrompt,\n selectedIterKey,\n}: MessagesPanelProps) {\n const t = useLensTheme();\n const scrollRef = useRef<HTMLDivElement | null>(null);\n\n // Scroll + highlight when selectedIterKey changes. The highlight is a\n // CSS class toggled on the target block; we pulse it via a one-shot\n // timer rather than CSS animation so it behaves the same in both\n // themes and survives re-renders mid-pulse.\n useEffect(() => {\n if (!selectedIterKey || !scrollRef.current) return;\n const target = scrollRef.current.querySelector<HTMLDivElement>(\n `[data-iter-key=\"${CSS.escape(selectedIterKey)}\"]`,\n );\n if (!target) return;\n target.scrollIntoView({ block: \"start\", behavior: \"smooth\" });\n target.setAttribute(\"data-iter-selected\", \"true\");\n const h = window.setTimeout(() => target.removeAttribute(\"data-iter-selected\"), 1200);\n return () => window.clearTimeout(h);\n }, [selectedIterKey]);\n\n return (\n <div\n ref={scrollRef}\n data-fp-lens=\"messages-panel\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n padding: \"16px 24px\",\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n fontSize: 14,\n lineHeight: 1.55,\n minHeight: 0,\n overflow: \"auto\",\n }}\n >\n {systemPrompt && <SystemBubble text={systemPrompt} />}\n {timeline.turns.map((turn) => (\n <TurnBlock key={turn.index} turn={turn} onToolCallClick={onToolCallClick} />\n ))}\n </div>\n );\n}\n\nfunction SystemBubble({ text }: { text: string }) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = text.slice(0, 140).replace(/\\s+/g, \" \") + (text.length > 140 ? \"…\" : \"\");\n return (\n <div\n style={{\n alignSelf: \"center\",\n width: \"100%\",\n maxWidth: 880,\n border: `1px dashed ${t.border}`,\n borderRadius: t.radius,\n padding: \"8px 12px\",\n background: t.bgElev,\n fontSize: 12,\n color: t.textMuted,\n }}\n >\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: t.textMuted,\n cursor: \"pointer\",\n padding: 0,\n font: \"inherit\",\n }}\n >\n <strong>SYSTEM</strong> {open ? \"▾\" : \"▸\"} {open ? \"\" : preview}\n </button>\n {open && (\n <pre\n style={{\n marginTop: 8,\n whiteSpace: \"pre-wrap\",\n fontFamily: t.fontMono,\n fontSize: 11,\n color: t.text,\n }}\n >\n {text}\n </pre>\n )}\n </div>\n );\n}\n\nfunction TurnBlock({\n turn,\n onToolCallClick,\n}: {\n turn: AgentTurn;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <TurnHeader turn={turn} />\n <UserBubble text={turn.userPrompt} />\n {turn.iterations.map((iter) => (\n <IterationBlock\n key={iter.index}\n iter={iter}\n turnIndex={turn.index}\n onToolCallClick={onToolCallClick}\n />\n ))}\n {turn.finalContent && turn.iterations.length > 0 && (\n <div style={{ fontSize: 11, color: t.textSubtle, textAlign: \"center\" }}>\n turn {turn.index + 1} final · {turn.iterations.length} iter · {turn.totalInputTokens}→\n {turn.totalOutputTokens} tok · {(turn.totalDurationMs / 1000).toFixed(1)}s\n </div>\n )}\n </div>\n );\n}\n\nfunction TurnHeader({ turn }: { turn: AgentTurn }) {\n const t = useLensTheme();\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n color: t.textSubtle,\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n }}\n >\n <div style={{ flex: 1, height: 1, background: t.border }} />\n <span>Turn {turn.index + 1}</span>\n <div style={{ flex: 1, height: 1, background: t.border }} />\n </div>\n );\n}\n\nfunction UserBubble({ text }: { text: string }) {\n const t = useLensTheme();\n return (\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <div\n style={{\n background: `color-mix(in srgb, ${t.accent} 18%, ${t.bgElev})`,\n border: `1px solid ${t.border}`,\n color: t.text,\n maxWidth: 720,\n padding: \"10px 14px\",\n borderRadius: `${t.radius} ${t.radius} 2px ${t.radius}`,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {text}\n </div>\n </div>\n );\n}\n\nfunction IterationBlock({\n iter,\n turnIndex,\n onToolCallClick,\n}: {\n iter: AgentIteration;\n turnIndex: number;\n onToolCallClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const key = `${turnIndex}.${iter.index}`;\n return (\n <div\n data-iter-key={key}\n data-turn-index={turnIndex}\n data-iter-index={iter.index}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n // When the parent adds data-iter-selected (via IterationStrip\n // click), pulse a soft ring using the accent color. Subtle so\n // the chat itself stays readable.\n padding: 8,\n margin: -8,\n borderRadius: t.radius,\n outline: \"2px solid transparent\",\n outlineOffset: 2,\n transition: \"outline-color 180ms ease, background 180ms ease\",\n }}\n >\n <IterationBadge iter={iter} />\n {iter.assistantContent && (\n <div\n style={{\n background: t.bgElev,\n border: `1px solid ${t.border}`,\n borderRadius: `2px ${t.radius} ${t.radius} ${t.radius}`,\n padding: \"10px 14px\",\n maxWidth: 820,\n whiteSpace: \"pre-wrap\",\n }}\n >\n {iter.assistantContent}\n </div>\n )}\n {iter.toolCalls.length > 0 && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, paddingLeft: 12 }}>\n {iter.toolCalls.map((tc) => (\n <ToolCallCard key={tc.id} invocation={tc} onClick={onToolCallClick} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction IterationBadge({ iter }: { iter: AgentIteration }) {\n const t = useLensTheme();\n const bits: string[] = [`iter ${iter.index}`];\n if (iter.model) bits.push(iter.model);\n if (iter.inputTokens !== undefined)\n bits.push(`${iter.inputTokens}→${iter.outputTokens ?? \"?\"} tok`);\n if (iter.durationMs !== undefined) bits.push(`${(iter.durationMs / 1000).toFixed(2)}s`);\n if (iter.stopReason) bits.push(iter.stopReason);\n return (\n <div\n style={{\n alignSelf: \"flex-start\",\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n fontFamily: t.fontMono,\n }}\n >\n {bits.join(\" · \")}\n </div>\n );\n}\n\nfunction ToolCallCard({\n invocation,\n onClick,\n}: {\n invocation: AgentToolInvocation;\n onClick?: (inv: AgentToolInvocation) => void;\n}) {\n const t = useLensTheme();\n const [open, setOpen] = useState(false);\n const preview = shortArgs(invocation.arguments);\n const errored = invocation.error === true;\n return (\n <div\n style={{\n border: `1px solid ${errored ? t.error : t.border}`,\n borderLeft: `3px solid ${errored ? t.error : t.accent}`,\n borderRadius: 6,\n background: t.bg,\n overflow: \"hidden\",\n }}\n >\n <div\n onClick={() => {\n setOpen((v) => !v);\n onClick?.(invocation);\n }}\n style={{\n padding: \"8px 12px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {invocation.name}\n </span>\n <span style={{ color: t.textMuted }}>({preview})</span>\n <span style={{ flex: 1 }} />\n {invocation.decisionUpdate && Object.keys(invocation.decisionUpdate).length > 0 && (\n <span\n style={{\n fontSize: 10,\n padding: \"1px 6px\",\n borderRadius: 3,\n background: `color-mix(in srgb, ${t.warning} 20%, transparent)`,\n color: t.warning,\n fontFamily: t.fontSans,\n fontWeight: 600,\n textTransform: \"uppercase\",\n }}\n >\n decisionUpdate\n </span>\n )}\n <span style={{ color: t.textSubtle }}>{open ? \"▾\" : \"▸\"}</span>\n </div>\n {open && (\n <div style={{ padding: \"8px 12px\", borderTop: `1px solid ${t.border}` }}>\n <Label t={t}>args</Label>\n <JsonBlock value={invocation.arguments} />\n {invocation.result && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n result\n </Label>\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: errored ? t.error : t.text,\n maxHeight: 280,\n overflow: \"auto\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {invocation.result}\n </pre>\n </>\n )}\n {invocation.decisionUpdate &&\n Object.keys(invocation.decisionUpdate).length > 0 && (\n <>\n <Label t={t} style={{ marginTop: 10 }}>\n decisionUpdate\n </Label>\n <JsonBlock value={invocation.decisionUpdate} />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction Label({\n t,\n children,\n style,\n}: {\n t: ReturnType<typeof useLensTheme>;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) {\n return (\n <div\n style={{\n fontSize: 10,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n marginBottom: 4,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction JsonBlock({ value }: { value: unknown }) {\n const t = useLensTheme();\n return (\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n background: t.bgElev,\n borderRadius: 4,\n fontSize: 11,\n fontFamily: t.fontMono,\n color: t.text,\n maxHeight: 200,\n overflow: \"auto\",\n }}\n >\n {JSON.stringify(value, null, 2)}\n </pre>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"\";\n if (keys.length === 1) {\n const v = args[keys[0]];\n if (typeof v === \"string\" && v.length < 40) return `${keys[0]}: \"${v}\"`;\n }\n return keys.join(\", \");\n}\n\nexport { ToolCallCard };\n\nfunction _assertUnused(_: AgentMessage) {\n // Exported type is referenced from ./index.ts; keeping the import\n // for bundler tree-shaking consistency without introducing a new\n // linter warning on a \"used-elsewhere\" type import.\n void _;\n}\n_assertUnused;\n","/**\n * useLensTheme — single source of truth for Lens colors + sizing.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Theme pass-through contract (IMPORTANT for consumers):\n *\n * Lens does NOT invent its own theme system. It reads tokens from the\n * FootprintTheme context already defined in `footprint-explainable-ui`.\n * A consumer app that wraps its tree in:\n *\n * import { FootprintTheme, coolDark, coolLight } from 'footprint-explainable-ui';\n * <FootprintTheme tokens={theme === 'light' ? coolLight : coolDark}>\n * <AgentLens runtimeSnapshot={snap} />\n * </FootprintTheme>\n *\n * …gets both Lens AND the drill-down explainable-ui drawer themed from the\n * same token bag. No separate `theme` prop, no duplicate palette, no\n * drift between the two views when the user flips light/dark.\n *\n * If no FootprintTheme provider is mounted, Lens falls back to cool-dark\n * defaults — the same defaults explainable-ui uses, so it looks correct\n * out of the box without configuration.\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport { useFootprintTheme, coolDark } from \"footprint-explainable-ui\";\nimport type { ThemeTokens } from \"footprint-explainable-ui\";\n\n/**\n * The resolved color palette + sizing tokens Lens renders against.\n * Always defined — callers never need to null-check.\n */\nexport interface LensTheme {\n readonly bg: string;\n readonly bgElev: string;\n readonly bgHover: string;\n readonly border: string;\n readonly borderStrong: string;\n readonly text: string;\n readonly textMuted: string;\n readonly textSubtle: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly error: string;\n readonly fontSans: string;\n readonly fontMono: string;\n readonly radius: string;\n}\n\n/**\n * Read tokens from FootprintTheme context (if present) and map them\n * into Lens's semantic palette. Missing tokens fall back to coolDark.\n */\nexport function useLensTheme(): LensTheme {\n const ctx = useFootprintTheme();\n return resolve(ctx);\n}\n\n/** Pure mapping — exported for unit tests + non-hook call sites. */\nexport function resolve(tokens: ThemeTokens | undefined): LensTheme {\n const t = tokens ?? {};\n const c = t.colors ?? coolDark.colors ?? {};\n const fallback = coolDark.colors ?? {};\n return {\n bg: c.bgPrimary ?? fallback.bgPrimary ?? \"#0f172a\",\n bgElev: c.bgSecondary ?? fallback.bgSecondary ?? \"#1e293b\",\n bgHover: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n border: c.border ?? fallback.border ?? \"#334155\",\n borderStrong: c.bgTertiary ?? fallback.bgTertiary ?? \"#334155\",\n text: c.textPrimary ?? fallback.textPrimary ?? \"#f8fafc\",\n textMuted: c.textSecondary ?? fallback.textSecondary ?? \"#94a3b8\",\n textSubtle: c.textMuted ?? fallback.textMuted ?? \"#64748b\",\n accent: c.primary ?? fallback.primary ?? \"#6366f1\",\n success: c.success ?? fallback.success ?? \"#22c55e\",\n warning: c.warning ?? fallback.warning ?? \"#f59e0b\",\n error: c.error ?? fallback.error ?? \"#ef4444\",\n fontSans: t.fontFamily?.sans ?? coolDark.fontFamily?.sans ?? \"system-ui, sans-serif\",\n fontMono: t.fontFamily?.mono ?? coolDark.fontFamily?.mono ?? \"ui-monospace, monospace\",\n radius: t.radius ?? coolDark.radius ?? \"8px\",\n };\n}\n","/**\n * IterationStrip — horizontal ribbon of LLM calls across the run, one\n * chip per iteration. Click to scroll/pin MessagesPanel to that iter.\n *\n * v0.1 is display-only with the selection callback; parent app owns the\n * scroll behavior.\n */\nimport type { AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface IterationStripProps {\n readonly timeline: AgentTimeline;\n readonly selectedKey?: string | null;\n readonly onSelect?: (key: string) => void;\n}\n\nexport function IterationStrip({ timeline, selectedKey, onSelect }: IterationStripProps) {\n const t = useLensTheme();\n const chips = timeline.turns.flatMap((turn) =>\n turn.iterations.map((iter) => ({\n key: `${turn.index}.${iter.index}`,\n turn: turn.index + 1,\n iter: iter.index,\n label: chipLabel(iter),\n tools: iter.toolCalls.length,\n durationMs: iter.durationMs ?? 0,\n stopReason: iter.stopReason,\n })),\n );\n\n return (\n <div\n data-fp-lens=\"iteration-strip\"\n style={{\n display: \"flex\",\n gap: 4,\n padding: \"8px 12px\",\n overflowX: \"auto\",\n borderBottom: `1px solid ${t.border}`,\n background: t.bgElev,\n }}\n >\n {chips.length === 0 && (\n <span style={{ color: t.textSubtle, fontSize: 11 }}>No iterations yet.</span>\n )}\n {chips.map((c) => {\n const active = c.key === selectedKey;\n const isFinal = c.stopReason === \"stop\" || c.stopReason === \"end_turn\";\n return (\n <button\n key={c.key}\n onClick={() => onSelect?.(c.key)}\n style={{\n background: active ? t.accent : \"transparent\",\n color: active ? \"#fff\" : t.textMuted,\n border: `1px solid ${active ? t.accent : t.border}`,\n borderRadius: 4,\n padding: \"4px 8px\",\n fontSize: 11,\n fontFamily: \"ui-monospace, monospace\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n title={`turn ${c.turn} · iter ${c.iter} · ${c.tools} tool call${\n c.tools === 1 ? \"\" : \"s\"\n }${c.stopReason ? ` · ${c.stopReason}` : \"\"}`}\n >\n t{c.turn}.i{c.iter} · {c.label} {isFinal ? \"✓\" : \"\"}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction chipLabel(iter: { toolCalls: readonly unknown[]; durationMs?: number }): string {\n const d = iter.durationMs ?? 0;\n const secs = d >= 1000 ? `${(d / 1000).toFixed(1)}s` : `${Math.round(d)}ms`;\n const toolBit = iter.toolCalls.length > 0 ? `${iter.toolCalls.length}t` : \"final\";\n return `${secs} · ${toolBit}`;\n}\n","/**\n * ToolCallInspector — flat sidebar list of every tool invocation in the\n * run. Primary workflow: skim for errors, click to focus a specific\n * call (mirrors MessagesPanel's selection).\n *\n * v0.1 minimum — name, args preview, latency, error badge. Drill-in to\n * the tool's underlying footprintjs flowchart via explainable-ui is a\n * phase-2 item (requires surfacing per-tool sub-snapshots).\n */\nimport type { AgentToolInvocation, AgentTimeline } from \"../adapters/types\";\nimport { useLensTheme } from \"../theme/useLensTheme\";\n\nexport interface ToolCallInspectorProps {\n readonly timeline: AgentTimeline;\n readonly selectedId?: string | null;\n readonly onSelect?: (invocation: AgentToolInvocation) => void;\n}\n\nexport function ToolCallInspector({\n timeline,\n selectedId,\n onSelect,\n}: ToolCallInspectorProps) {\n const t = useLensTheme();\n return (\n <div\n data-fp-lens=\"tool-call-inspector\"\n style={{\n background: t.bg,\n color: t.text,\n fontFamily: t.fontSans,\n display: \"flex\",\n flexDirection: \"column\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"10px 14px\",\n borderBottom: `1px solid ${t.border}`,\n fontSize: 11,\n color: t.textSubtle,\n textTransform: \"uppercase\",\n letterSpacing: \"0.08em\",\n fontWeight: 600,\n background: t.bgElev,\n }}\n >\n Tool calls · {timeline.tools.length}\n </div>\n <div style={{ overflow: \"auto\", flex: 1 }}>\n {timeline.tools.length === 0 && (\n <div style={{ padding: 14, color: t.textSubtle, fontSize: 12 }}>\n No tool calls yet.\n </div>\n )}\n {timeline.tools.map((tc) => {\n const active = tc.id === selectedId;\n const errored = tc.error === true;\n return (\n <button\n key={tc.id}\n onClick={() => onSelect?.(tc)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n textAlign: \"left\",\n padding: \"8px 12px\",\n background: active ? t.bgHover : \"transparent\",\n border: \"none\",\n borderLeft: `3px solid ${\n active ? t.accent : errored ? t.error : \"transparent\"\n }`,\n borderBottom: `1px solid ${t.border}`,\n color: t.text,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: 8,\n alignItems: \"baseline\",\n fontSize: 12,\n fontFamily: t.fontMono,\n }}\n >\n <span style={{ color: errored ? t.error : t.accent, fontWeight: 600 }}>\n {tc.name}\n </span>\n <span\n style={{ color: t.textSubtle, fontSize: 10, marginLeft: \"auto\" }}\n >\n t{tc.turnIndex + 1}.i{tc.iterationIndex}\n {tc.durationMs !== undefined && ` · ${Math.round(tc.durationMs)}ms`}\n </span>\n </div>\n <div\n style={{\n fontSize: 10,\n color: t.textMuted,\n marginTop: 2,\n fontFamily: t.fontMono,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {shortArgs(tc.arguments)}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction shortArgs(args: Record<string, unknown>): string {\n const keys = Object.keys(args);\n if (keys.length === 0) return \"— no args —\";\n return keys\n .map((k) => {\n const v = args[k];\n if (typeof v === \"string\") return `${k}: \"${v.length > 20 ? v.slice(0, 20) + \"…\" : v}\"`;\n if (typeof v === \"number\" || typeof v === \"boolean\") return `${k}: ${v}`;\n return `${k}: …`;\n })\n .join(\", \");\n}\n","/**\n * LiveTimelineBuilder — ingests agentfootprint emit events AS THEY HAPPEN\n * and accumulates the `AgentTimeline` incrementally. Zero post-processing:\n * every field is set as the corresponding event fires during traversal.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * Why this exists\n *\n * footprintjs's core principle: \"collect during traversal, never post-\n * process.\" Walking `commitLog` after the run to reconstruct the agent\n * view is valid but it re-traverses data that already flowed past. The\n * Builder is the correct shape — it's a recorder that subscribes to the\n * stream of events the agent already emits and writes each field exactly\n * once, when the source-of-truth event fires.\n *\n * Consumer wiring (from a React app):\n *\n * const builder = useMemo(() => new LiveTimelineBuilder(), []);\n * const [timeline, setTimeline] = useState(builder.getTimeline());\n * // In Neo's runTurn onEvent:\n * await agent.run(prompt, {\n * onEvent: (e) => {\n * builder.ingest(e);\n * setTimeline(builder.getTimeline());\n * },\n * });\n * <AgentLens timeline={timeline} />\n *\n * Or via the `useLiveTimeline()` React hook below — same mechanics, less\n * boilerplate.\n *\n * The events consumed are all `agentfootprint.stream.*` (llm_start,\n * llm_end, tool_start, tool_end) + `agentfootprint.agent.turn_complete`.\n * User messages are captured by calling `startTurn(userPrompt)` before\n * each `agent.run()` invocation — that's the one piece the event stream\n * doesn't carry (agent.run() is where the user message enters the\n * system, not an event emission).\n * ─────────────────────────────────────────────────────────────────────────\n */\nimport type {\n AgentIteration,\n AgentMessage,\n AgentTimeline,\n AgentToolInvocation,\n AgentTurn,\n} from \"./types\";\n\n// Minimal shape we need from an agent event — structural only, no direct\n// dep on agentfootprint's event type (which may evolve).\ninterface AgentEventLike {\n readonly type: string;\n readonly toolName?: string;\n readonly toolCallId?: string;\n readonly args?: Record<string, unknown>;\n readonly result?: { content?: string; error?: boolean } | string;\n readonly iteration?: number;\n readonly content?: string;\n readonly toolCallCount?: number;\n readonly model?: string;\n readonly usage?: { inputTokens?: number; outputTokens?: number };\n readonly stopReason?: string;\n readonly durationMs?: number;\n readonly iterations?: number;\n readonly reason?: string;\n}\n\ninterface MutableTurn {\n index: number;\n userPrompt: string;\n iterations: MutableIteration[];\n finalContent: string;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalDurationMs: number;\n startMs: number;\n}\n\ninterface MutableIteration {\n index: number;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n durationMs?: number;\n stopReason?: string;\n assistantContent: string;\n toolCalls: MutableTool[];\n decisionAtStart: Record<string, unknown>;\n matchedInstructions?: string[];\n visibleTools: string[];\n startMs: number;\n}\n\ninterface MutableTool {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result: string;\n error?: boolean;\n decisionUpdate?: Record<string, unknown>;\n iterationIndex: number;\n turnIndex: number;\n durationMs?: number;\n startMs: number;\n}\n\nexport class LiveTimelineBuilder {\n private turns: MutableTurn[] = [];\n private currentTurn: MutableTurn | null = null;\n private currentIter: MutableIteration | null = null;\n private toolByCallId = new Map<string, MutableTool>();\n private messages: AgentMessage[] = [];\n private systemPrompt: string | undefined;\n private finalDecision: Record<string, unknown> = {};\n\n /**\n * Begin a new turn. Call this BEFORE `agent.run(userPrompt)` so the\n * user's prompt appears alongside the iterations it produced. Safe to\n * call even mid-conversation — it closes the previous turn cleanly.\n */\n startTurn(userPrompt: string): void {\n if (this.currentTurn) this.commitCurrentTurn();\n this.currentTurn = {\n index: this.turns.length,\n userPrompt,\n iterations: [],\n finalContent: \"\",\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalDurationMs: 0,\n startMs: Date.now(),\n };\n this.messages.push({ role: \"user\", content: userPrompt });\n }\n\n /**\n * Optional — attach the system prompt so MessagesPanel can render it\n * in the collapsible preamble. Usually set once at agent construction.\n */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n /**\n * Feed one agent stream event. Safe to call for unknown events; we\n * ignore anything we don't recognize.\n */\n ingest(event: AgentEventLike | unknown): void {\n const e = event as AgentEventLike;\n if (!e || typeof e.type !== \"string\") return;\n switch (e.type) {\n case \"llm_start\":\n case \"agentfootprint.stream.llm_start\":\n this.onLLMStart(e);\n return;\n case \"llm_end\":\n case \"agentfootprint.stream.llm_end\":\n this.onLLMEnd(e);\n return;\n case \"tool_start\":\n case \"agentfootprint.stream.tool_start\":\n this.onToolStart(e);\n return;\n case \"tool_end\":\n case \"agentfootprint.stream.tool_end\":\n this.onToolEnd(e);\n return;\n case \"turn_end\":\n case \"agentfootprint.agent.turn_complete\":\n this.commitCurrentTurn();\n return;\n default:\n return;\n }\n }\n\n private onLLMStart(e: AgentEventLike): void {\n if (!this.currentTurn) return;\n const iterNum = e.iteration ?? this.currentTurn.iterations.length + 1;\n this.currentIter = {\n index: iterNum,\n assistantContent: \"\",\n toolCalls: [],\n decisionAtStart: {},\n visibleTools: [],\n startMs: Date.now(),\n };\n this.currentTurn.iterations.push(this.currentIter);\n }\n\n private onLLMEnd(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n this.currentIter.assistantContent = e.content ?? this.currentIter.assistantContent;\n if (e.model) this.currentIter.model = e.model;\n if (e.usage?.inputTokens !== undefined) this.currentIter.inputTokens = e.usage.inputTokens;\n if (e.usage?.outputTokens !== undefined) this.currentIter.outputTokens = e.usage.outputTokens;\n if (e.stopReason) this.currentIter.stopReason = e.stopReason;\n this.currentIter.durationMs = e.durationMs ?? Date.now() - this.currentIter.startMs;\n\n // Aggregate into turn totals.\n this.currentTurn.totalInputTokens += this.currentIter.inputTokens ?? 0;\n this.currentTurn.totalOutputTokens += this.currentIter.outputTokens ?? 0;\n this.currentTurn.totalDurationMs += this.currentIter.durationMs ?? 0;\n\n // Assistant message for the chat view.\n if (this.currentIter.assistantContent) {\n this.messages.push({ role: \"assistant\", content: this.currentIter.assistantContent });\n }\n // If no tool calls follow, this iteration's content IS the turn's final answer.\n if ((e.toolCallCount ?? 0) === 0) {\n this.currentTurn.finalContent = this.currentIter.assistantContent;\n }\n }\n\n private onToolStart(e: AgentEventLike): void {\n if (!this.currentIter || !this.currentTurn) return;\n const tool: MutableTool = {\n id: e.toolCallId ?? `tool-${this.currentIter.toolCalls.length}`,\n name: e.toolName ?? \"unknown\",\n arguments: e.args ?? {},\n result: \"\",\n iterationIndex: this.currentIter.index,\n turnIndex: this.currentTurn.index,\n startMs: Date.now(),\n };\n this.currentIter.toolCalls.push(tool);\n this.toolByCallId.set(tool.id, tool);\n }\n\n private onToolEnd(e: AgentEventLike): void {\n const tool = this.toolByCallId.get(e.toolCallId ?? \"\");\n if (!tool) return;\n const r = e.result;\n if (typeof r === \"string\") {\n tool.result = r;\n } else if (r && typeof r === \"object\") {\n tool.result = r.content ?? \"\";\n if (r.error === true) tool.error = true;\n }\n tool.durationMs = e.durationMs ?? Date.now() - tool.startMs;\n // Record the tool-role message so MessagesPanel can render it.\n this.messages.push({ role: \"tool\", content: tool.result, toolCallId: tool.id });\n }\n\n private commitCurrentTurn(): void {\n if (!this.currentTurn) return;\n this.turns.push(this.currentTurn);\n this.currentTurn = null;\n this.currentIter = null;\n }\n\n /**\n * Snapshot the current state as an immutable `AgentTimeline`. Safe to\n * call at any point — mid-run gives you the partial state so Lens can\n * live-update.\n */\n getTimeline(): AgentTimeline {\n const allTurns = [...this.turns];\n if (this.currentTurn) allTurns.push(this.currentTurn);\n const tools: AgentToolInvocation[] = [];\n const frozenTurns: AgentTurn[] = allTurns.map((t) => {\n const iterations: AgentIteration[] = t.iterations.map((i) => {\n const tcs = i.toolCalls.map((tc) => ({ ...tc } as AgentToolInvocation));\n tools.push(...tcs);\n return { ...i, toolCalls: tcs } as AgentIteration;\n });\n return { ...t, iterations } as AgentTurn;\n });\n return {\n turns: frozenTurns,\n messages: [...this.messages],\n tools,\n finalDecision: { ...this.finalDecision },\n rawSnapshot: null,\n };\n }\n\n /**\n * Fold in a final `decision` scope after the run — useful when\n * the consumer wants the Decision Ribbon (phase-2) to reflect the\n * post-run state. Safe no-op during the run itself.\n */\n setFinalDecision(decision: Record<string, unknown>): void {\n this.finalDecision = decision;\n }\n\n /** Get the optional system prompt for the Messages preamble. */\n getSystemPrompt(): string | undefined {\n return this.systemPrompt;\n }\n\n /** Wipe state. Useful when the consumer starts a fresh conversation. */\n reset(): void {\n this.turns = [];\n this.currentTurn = null;\n this.currentIter = null;\n this.toolByCallId.clear();\n this.messages = [];\n this.finalDecision = {};\n }\n}\n","/**\n * useLiveTimeline — React hook wrapper around LiveTimelineBuilder.\n *\n * The hook owns a stable builder across renders and returns:\n * • `timeline` — current state (re-renders on every `ingest` call)\n * • `ingest` — feed an agentfootprint stream event\n * • `startTurn`, `setSystemPrompt`, `setFinalDecision`, `reset` — forward methods\n *\n * Usage:\n *\n * const lens = useLiveTimeline();\n * <AgentLens timeline={lens.timeline} />\n *\n * // Before agent.run():\n * lens.startTurn(userPrompt);\n * await agent.run(userPrompt, { onEvent: lens.ingest });\n *\n * The hook keeps the agent-shaped view in sync AS events fire — Lens\n * updates incrementally during the run, not only after it completes.\n */\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { LiveTimelineBuilder } from \"./LiveTimelineBuilder\";\nimport type { AgentTimeline } from \"./types\";\n\nexport interface UseLiveTimelineResult {\n readonly timeline: AgentTimeline;\n readonly ingest: (event: unknown) => void;\n readonly startTurn: (userPrompt: string) => void;\n readonly setSystemPrompt: (prompt: string) => void;\n readonly setFinalDecision: (decision: Record<string, unknown>) => void;\n readonly reset: () => void;\n /** Escape hatch — exposed for integrations that need builder internals. */\n readonly builder: LiveTimelineBuilder;\n}\n\nexport function useLiveTimeline(): UseLiveTimelineResult {\n const builderRef = useRef<LiveTimelineBuilder | null>(null);\n if (!builderRef.current) builderRef.current = new LiveTimelineBuilder();\n const builder = builderRef.current;\n\n const [timeline, setTimeline] = useState<AgentTimeline>(() => builder.getTimeline());\n\n const sync = useCallback(() => {\n setTimeline(builder.getTimeline());\n }, [builder]);\n\n const ingest = useCallback(\n (event: unknown) => {\n builder.ingest(event);\n sync();\n },\n [builder, sync],\n );\n\n const startTurn = useCallback(\n (userPrompt: string) => {\n builder.startTurn(userPrompt);\n sync();\n },\n [builder, sync],\n );\n\n const setSystemPrompt = useCallback(\n (prompt: string) => {\n builder.setSystemPrompt(prompt);\n sync();\n },\n [builder, sync],\n );\n\n const setFinalDecision = useCallback(\n (decision: Record<string, unknown>) => {\n builder.setFinalDecision(decision);\n sync();\n },\n [builder, sync],\n );\n\n const reset = useCallback(() => {\n builder.reset();\n sync();\n }, [builder, sync]);\n\n return useMemo(\n () => ({ timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder }),\n [timeline, ingest, startTurn, setSystemPrompt, setFinalDecision, reset, builder],\n );\n}\n"],"mappings":"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","names":["useState","jsx","jsxs","jsx","jsxs","shortArgs","jsx","jsxs","useState","useMemo","useRef","useState","useRef","useState","useMemo"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfootprint-lens",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "See through your agent's decisions. React components for debugging agentfootprint runs — messages, prompts, tool calls, decision scope, cost.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",