From fb88a80616eb89588a910dd68546563729d10161 Mon Sep 17 00:00:00 2001 From: Vader Yang Date: Tue, 23 Jun 2026 14:14:31 +0800 Subject: [PATCH 1/3] fix(console): read span_ids not call_ids in turn detail (fixes prod blank page) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OTel rename made the traces API serialize `span_ids` (formerly `call_ids`), and the rename updated the API-path hooks — but the `AgentTurnDetail` type and the `agent-breakdown` component were missed and still read `call_ids`. At runtime `turn.call_ids` is undefined, so `turn.call_ids.length` throws `TypeError: undefined is not an object`. With no React error boundary, that render throw blanks the entire console — which is the white screen seen after the v0.7.0 production upgrade. The soak gates exercise backend invariants, not frontend rendering, and the stale type kept tsc green, so it reached prod. Align the type + component to `span_ids` and guard with `?.` so a future missing field degrades to "0 calls" instead of a white screen. --- console/src/components/turn-detail/agent-breakdown.tsx | 4 ++-- console/src/types/api.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/console/src/components/turn-detail/agent-breakdown.tsx b/console/src/components/turn-detail/agent-breakdown.tsx index 42409158..5a24b47e 100644 --- a/console/src/components/turn-detail/agent-breakdown.tsx +++ b/console/src/components/turn-detail/agent-breakdown.tsx @@ -38,8 +38,8 @@ export function AgentBreakdown({ turn, calls }: Props) {
Tool calls
- {turn.tool_call_total} total across {turn.call_ids.length} call - {turn.call_ids.length === 1 ? "" : "s"} + {turn.tool_call_total} total across {turn.span_ids?.length ?? 0} call + {(turn.span_ids?.length ?? 0) === 1 ? "" : "s"}
{turn.suspicious_skills.length > 0 && ( diff --git a/console/src/types/api.ts b/console/src/types/api.ts index 888a673b..2aecd930 100644 --- a/console/src/types/api.ts +++ b/console/src/types/api.ts @@ -339,7 +339,7 @@ export interface AgentTurnDetail { user_input: string | null final_call_id: string | null final_answer: string | null - call_ids: string[] + span_ids: string[] metadata: unknown /** See AgentTurnListItem. */ tool_surfaces: ToolSurface[] From 2bfeccafb1422157dcd29ff1c4bf0bda4e89468b Mon Sep 17 00:00:00 2001 From: Vader Yang Date: Tue, 23 Jun 2026 14:36:10 +0800 Subject: [PATCH 2/3] =?UTF-8?q?refactor(console):=20rename=20UI=20"Agent?= =?UTF-8?q?=20Turns"=E2=86=92"Agent=20Traces",=20"HTTP=20Exchanges"?= =?UTF-8?q?=E2=86=92"HTTP=20Logs"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align user-visible labels with the OTel model: the top-level list is a trace (one agent interaction); a step within a trace is a turn/span. Renamed: sidebar nav labels, the trace-detail title ("Agent Trace Detail"), the overview gauge ("Active Agent Traces" + "Open traces"), the metadata "Trace ID" row, the agent-session-detail empty/error/load-more states, the SFT batch-export tooltip, the HTTP list error/empty states ("HTTP logs"), and the agent-distribution chart legend. Left unchanged on purpose: backend metric names (agent_turns_open), pipeline stage/metric-group names ("turn"), route paths (/agent-turns, /http-exchanges), component/hook/variable identifiers, and the SFT-domain term "multi-turn trajectory". --- console/src/components/charts/agent-distribution-chart.tsx | 2 +- console/src/components/layout/sidebar.tsx | 4 ++-- console/src/components/trajectory-actions.tsx | 4 ++-- console/src/components/turn-detail/metadata-popover.tsx | 2 +- console/src/components/turn-detail/top-bar.tsx | 2 +- console/src/pages/agent-session-detail.tsx | 6 +++--- console/src/pages/http-exchange-detail-panel.tsx | 2 +- console/src/pages/http-exchanges.tsx | 4 ++-- console/src/pages/overview.tsx | 6 +++--- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/console/src/components/charts/agent-distribution-chart.tsx b/console/src/components/charts/agent-distribution-chart.tsx index 951d7b98..e1adec0f 100644 --- a/console/src/components/charts/agent-distribution-chart.tsx +++ b/console/src/components/charts/agent-distribution-chart.tsx @@ -62,7 +62,7 @@ export function AgentDistributionChart({ rows }: Props) { /> { - if (name === "turns") return [formatNumber(Number(value)), "Turns"] + if (name === "turns") return [formatNumber(Number(value)), "Traces"] return [String(value), String(name)] }} labelFormatter={(_label, payload) => diff --git a/console/src/components/layout/sidebar.tsx b/console/src/components/layout/sidebar.tsx index 9a88429d..8a3a70fe 100644 --- a/console/src/components/layout/sidebar.tsx +++ b/console/src/components/layout/sidebar.tsx @@ -33,9 +33,9 @@ const observeItems = [ const exploreItems = [ { to: "/services", icon: Server, label: "Services" }, { to: "/agent-sessions", icon: MessageSquare, label: "Agent Sessions" }, - { to: "/agent-turns", icon: MessagesSquare, label: "Agent Turns" }, + { to: "/agent-turns", icon: MessagesSquare, label: "Agent Traces" }, { to: "/llm-calls", icon: Sparkles, label: "LLM Calls" }, - { to: "/http-exchanges", icon: Network, label: "HTTP Exchanges" }, + { to: "/http-exchanges", icon: Network, label: "HTTP Logs" }, ] const THEME_META: Record = { diff --git a/console/src/components/trajectory-actions.tsx b/console/src/components/trajectory-actions.tsx index 03029d78..92c8fc87 100644 --- a/console/src/components/trajectory-actions.tsx +++ b/console/src/components/trajectory-actions.tsx @@ -49,7 +49,7 @@ export function DownloadTrajectoryButton({ } /** Labeled batch-export button with inline written/skipped feedback - * (Agent Turns list — exports every turn matching the current filters). */ + * (Agent Traces list — exports every trace matching the current filters). */ export function BatchExportButton({ url, fallbackName = "trajectories.jsonl", @@ -82,7 +82,7 @@ export function BatchExportButton({ setBusy(false) } }} - title="Export every turn matching the current filters as SFT trajectories (.jsonl)" + title="Export every trace matching the current filters as SFT trajectories (.jsonl)" className={cn( "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1 text-xs font-medium text-foreground transition-colors hover:bg-muted disabled:opacity-50", className, diff --git a/console/src/components/turn-detail/metadata-popover.tsx b/console/src/components/turn-detail/metadata-popover.tsx index fb4821ea..18dbc5f8 100644 --- a/console/src/components/turn-detail/metadata-popover.tsx +++ b/console/src/components/turn-detail/metadata-popover.tsx @@ -9,7 +9,7 @@ interface Props { export function MetadataPopover({ turn, onClose }: Props) { const rows: [string, string][] = [ - ["Turn ID", turn.turn_id], + ["Trace ID", turn.turn_id], ["Source", turn.source_id || "—"], ["Session ID", turn.session_id], ["Agent", turn.agent_kind], diff --git a/console/src/components/turn-detail/top-bar.tsx b/console/src/components/turn-detail/top-bar.tsx index 749b1d80..5dd10098 100644 --- a/console/src/components/turn-detail/top-bar.tsx +++ b/console/src/components/turn-detail/top-bar.tsx @@ -19,7 +19,7 @@ export function TopBar({ turn, onClose }: Props) { const [metaOpen, setMetaOpen] = useState(false) return (
-

Agent Turn Detail

+

Agent Trace Detail

{turn.agent_kind} · diff --git a/console/src/pages/agent-session-detail.tsx b/console/src/pages/agent-session-detail.tsx index 93948c40..47cfd705 100644 --- a/console/src/pages/agent-session-detail.tsx +++ b/console/src/pages/agent-session-detail.tsx @@ -70,9 +70,9 @@ export function AgentSessionDetailPage() {
) : errorTurns ? ( -
Failed to load turns
+
Failed to load traces
) : turns.length === 0 ? ( -
No turns in this session
+
No traces in this session
) : ( turns.map((t) => ( - {isFetchingNextPage ? "Loading…" : "Load older turns"} + {isFetchingNextPage ? "Loading…" : "Load older traces"}
)} diff --git a/console/src/pages/http-exchange-detail-panel.tsx b/console/src/pages/http-exchange-detail-panel.tsx index 65e43340..d48669c0 100644 --- a/console/src/pages/http-exchange-detail-panel.tsx +++ b/console/src/pages/http-exchange-detail-panel.tsx @@ -108,7 +108,7 @@ export function HttpExchangeDetailPanel({ id, onClose, onNavigate, hasPrev, hasN
{/* Header */}
-

HTTP Exchange Detail

+

HTTP Log Detail

{detail && ( diff --git a/console/src/pages/http-exchanges.tsx b/console/src/pages/http-exchanges.tsx index 4109f220..9d7360d6 100644 --- a/console/src/pages/http-exchanges.tsx +++ b/console/src/pages/http-exchanges.tsx @@ -300,13 +300,13 @@ export function HttpExchangesPage() { ) : isError ? ( - Failed to load http exchanges: {error?.message} + Failed to load HTTP logs: {error?.message} ) : items.length === 0 ? ( - No HTTP exchanges in the selected time range + No HTTP logs in the selected time range ) : ( diff --git a/console/src/pages/overview.tsx b/console/src/pages/overview.tsx index 0929d07d..97cdb77e 100644 --- a/console/src/pages/overview.tsx +++ b/console/src/pages/overview.tsx @@ -156,14 +156,14 @@ export function OverviewPage() {

- Active Agent Turns + Active Agent Traces - in-progress agent turns (registry size) + in-progress agent traces (registry size)

From d20c307c98e0cdd8b1e2bd5c9ac799fd0af40763 Mon Sep 17 00:00:00 2001 From: Vader Yang Date: Tue, 23 Jun 2026 14:41:59 +0800 Subject: [PATCH 3/3] chore(release): v0.7.1 Patch release: console blank-page hotfix (span_ids alignment) + UI vocabulary rename (Agent Traces / HTTP Logs). See CHANGELOG [0.7.1]. --- CHANGELOG.md | 21 +++++++++++++++++++++ VERSION | 2 +- console/package.json | 2 +- server/Cargo.lock | 28 ++++++++++++++-------------- server/Cargo.toml | 2 +- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd8d5e96..a89f40b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,27 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.7.1] — 2026-06-24 + +### Fixed + +- **Console blank-page regression from the v0.7.0 OTel rename.** The traces API + serializes `span_ids` (renamed from `call_ids`), but the `AgentTurnDetail` + type and the `agent-breakdown` component still read `call_ids`, so opening an + agent trace detail threw `TypeError: undefined is not an object (evaluating + '…call_ids.length')` and — with no React error boundary — blanked the entire + console. Aligned the type + component to `span_ids` and guarded the access so + a missing field degrades to "0 calls" instead of a white screen. + +### Changed + +- **UI vocabulary aligned with the OTel model.** Renamed user-visible labels: + "Agent Turns" → "Agent Traces" and "HTTP Exchanges" → "HTTP Logs" (nav, detail + titles, the overview gauge, the "Trace ID" metadata row, empty/error states, + the SFT export tooltip, and the distribution chart). A trace is one agent + interaction; a step within it remains a turn/span. Backend metric names, route + paths, and code identifiers are unchanged. + ## [0.7.0] — 2026-06-24 ### Added diff --git a/VERSION b/VERSION index faef31a4..39e898a4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.0 +0.7.1 diff --git a/console/package.json b/console/package.json index 04d38fae..b964e26b 100644 --- a/console/package.json +++ b/console/package.json @@ -1,7 +1,7 @@ { "name": "console", "private": true, - "version": "0.7.0", + "version": "0.7.1", "type": "module", "scripts": { "dev": "vite", diff --git a/server/Cargo.lock b/server/Cargo.lock index fa7fe22f..9fb036b1 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -1326,7 +1326,7 @@ dependencies = [ [[package]] name = "h-api" -version = "0.7.0" +version = "0.7.1" dependencies = [ "axum", "chrono", @@ -1350,7 +1350,7 @@ dependencies = [ [[package]] name = "h-capture" -version = "0.7.0" +version = "0.7.1" dependencies = [ "async-trait", "aya", @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "h-common" -version = "0.7.0" +version = "0.7.1" dependencies = [ "config", "serde", @@ -1385,11 +1385,11 @@ dependencies = [ [[package]] name = "h-ebpf-common" -version = "0.7.0" +version = "0.7.1" [[package]] name = "h-export" -version = "0.7.0" +version = "0.7.1" dependencies = [ "h-llm", "serde", @@ -1399,7 +1399,7 @@ dependencies = [ [[package]] name = "h-llm" -version = "0.7.0" +version = "0.7.1" dependencies = [ "bitflags 2.11.0", "bytes", @@ -1419,7 +1419,7 @@ dependencies = [ [[package]] name = "h-metrics" -version = "0.7.0" +version = "0.7.1" dependencies = [ "h-common", "h-llm", @@ -1430,7 +1430,7 @@ dependencies = [ [[package]] name = "h-pcap-extract" -version = "0.7.0" +version = "0.7.1" dependencies = [ "bytes", "futures", @@ -1447,7 +1447,7 @@ dependencies = [ [[package]] name = "h-protocol" -version = "0.7.0" +version = "0.7.1" dependencies = [ "bytemuck", "bytes", @@ -1465,7 +1465,7 @@ dependencies = [ [[package]] name = "h-storage" -version = "0.7.0" +version = "0.7.1" dependencies = [ "async-trait", "bytes", @@ -1484,7 +1484,7 @@ dependencies = [ [[package]] name = "h-storage-clickhouse" -version = "0.7.0" +version = "0.7.1" dependencies = [ "async-trait", "bytes", @@ -1504,7 +1504,7 @@ dependencies = [ [[package]] name = "h-storage-duckdb" -version = "0.7.0" +version = "0.7.1" dependencies = [ "async-trait", "bytes", @@ -1524,7 +1524,7 @@ dependencies = [ [[package]] name = "h-turn" -version = "0.7.0" +version = "0.7.1" dependencies = [ "h-capture", "h-common", @@ -1614,7 +1614,7 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "heron" -version = "0.7.0" +version = "0.7.1" dependencies = [ "axum", "clap", diff --git a/server/Cargo.toml b/server/Cargo.toml index 8b8903c7..179bb0c4 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -8,7 +8,7 @@ exclude = ["h-ebpf-prog"] resolver = "2" [workspace.package] -version = "0.7.0" +version = "0.7.1" edition = "2021" license = "Apache-2.0"