HOMELAB-1135: feat(pi-otel-telemetry): span-per-subagent telemetry to Tempo #2

Merged
aaron merged 1 commit from feat/pi-subagent-telemetry into main 2026-06-18 04:01:30 +00:00
Owner

HOMELAB-1135 — Pi subagent telemetry (extension)

Makes every Pi subagent (including isolated:true ones) a first-class, self-identifying span in Tempo, parented under the session's root pi-agent span.

What's in here

  • subagents.ts — SubagentSpanTracker: opens a subagent:<type> span on subagents:started, closes it on terminal, idempotent open-spans map, shutdown sweep for abandoned spans.
  • index.ts — subscribes to subagents:started/completed/failed/compacted on the pi.events bus; carries down session.id + plane.ticket_id; enriches llm.model from the parent model. Closes foreground (awaited) subagents from the parent Agent tool_result, since @tintinweb/pi-subagents only emits terminal bus events for background agents.
  • query_telemetry — prompt guidelines so agents can self-serve subagent analysis via TraceQL/PromQL.

Schema (Tempo spans)

subagent:<type> · agent.role=subagent · subagent.id|type|outcome|tool_uses|compaction_count · llm.model · gen_ai.usage.{input,output,total}_tokens · session.id · plane.ticket_id · resource host.name.
subagent.outcome ∈ {completed, failed, aborted, stopped, steered, abandoned, unknown}.

Verification

Live-verified in Tempo: both a foreground and an isolated subagent export with correct outcome, tool_uses, total_tokens, session.id, and parent nesting (isolated-coverage proven — the events fire in the parent process).

Final review fixes (this branch)

  • Hardened subagent.outcome fallback to unknown (no raw internal-status leak).
  • Subagent subscriptions now register unconditionally and resolve the tracer lazily via a getter, so spans aren't dropped when tracing is enabled mid-session or after an OTLP re-init.

Spec: internal-docs/plans/2026-06-17-pi-subagent-telemetry.md · paired infra-core PR adds Tempo span-metrics dimensions + the "AI Agents" Grafana folder.

Note: one pre-existing tsc error remains in the query_telemetry registration (details typing) — present before this branch, out of scope.

🤖 Generated with Claude Code

## HOMELAB-1135 — Pi subagent telemetry (extension) Makes every Pi subagent (including `isolated:true` ones) a first-class, self-identifying span in Tempo, parented under the session's root `pi-agent` span. ### What's in here - **`subagents.ts`** — `SubagentSpanTracker`: opens a `subagent:<type>` span on `subagents:started`, closes it on terminal, idempotent open-spans map, shutdown sweep for abandoned spans. - **`index.ts`** — subscribes to `subagents:started/completed/failed/compacted` on the `pi.events` bus; carries down `session.id` + `plane.ticket_id`; enriches `llm.model` from the parent model. Closes foreground (awaited) subagents from the parent `Agent` tool_result, since `@tintinweb/pi-subagents` only emits terminal bus events for background agents. - **`query_telemetry`** — prompt guidelines so agents can self-serve subagent analysis via TraceQL/PromQL. ### Schema (Tempo spans) `subagent:<type>` · `agent.role=subagent` · `subagent.id|type|outcome|tool_uses|compaction_count` · `llm.model` · `gen_ai.usage.{input,output,total}_tokens` · `session.id` · `plane.ticket_id` · resource `host.name`. `subagent.outcome ∈ {completed, failed, aborted, stopped, steered, abandoned, unknown}`. ### Verification Live-verified in Tempo: both a foreground and an **isolated** subagent export with correct `outcome`, `tool_uses`, `total_tokens`, `session.id`, and parent nesting (isolated-coverage proven — the events fire in the parent process). ### Final review fixes (this branch) - Hardened `subagent.outcome` fallback to `unknown` (no raw internal-status leak). - Subagent subscriptions now register unconditionally and resolve the tracer lazily via a getter, so spans aren't dropped when tracing is enabled mid-session or after an OTLP re-init. Spec: `internal-docs/plans/2026-06-17-pi-subagent-telemetry.md` · paired infra-core PR adds Tempo span-metrics dimensions + the "AI Agents" Grafana folder. > Note: one pre-existing `tsc` error remains in the `query_telemetry` registration (`details` typing) — present before this branch, out of scope. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Repo was ~2wk stale (pre-HOMELAB-1102, no query tool). Imports the running
~/.pi HEAD as the baseline for subagent telemetry. Metrics instruments present
but no MeterProvider registered (no-ops today); left untouched.

Also adds tsconfig.json + devDependencies (typescript, @mariozechner/pi-coding-agent,
typebox) to enable tsc type checking (build gate). Fixes plane/api.ts to export
PROJECT_MAP (matching deployed copy), resolving a cross-extension type reference.

Pre-existing type issue: AgentToolResult requires `details` but error-path returns
in index.ts/query.ts omit it — latent in deployed code, not introduced here.

HOMELAB-1135
HOMELAB-1135
Subscribes via pi.events.on(subagents:started/completed/failed/compacted),
carries session.id + plane.ticket_id down, enriches llm.model from parent.

HOMELAB-1135
Teaches pi-agents the subagent:<type> span shape + TraceQL/PromQL patterns
for reviewing subagent actions. (Dropped the unused formatSubagentResult
formatter from the plan — subagent trace queries render via the existing
formatTraceResult; YAGNI.)

HOMELAB-1135
HOMELAB-1135
Foreground (awaited) subagents never emit subagents:completed/failed (that
event fires only for background agents), so spans were swept as 'abandoned'
with no tokens/tool_uses. Now also close from the parent 'Agent' tool result
(details.agentId/status/toolUses/tokens). onTerminal accepts partial tokens
(foreground exposes total only) and no longer marks 'steered' as an error.

Found via live Tempo verification at the Tasks 1-4 checkpoint.
HOMELAB-1135
C2/I1: register subagent subscriptions unconditionally and resolve the
tracer lazily via getter so spans aren't dropped when tracing is enabled
mid-session or after an OTLP re-init (no more stale/never-bound tracer).
C1: map unknown terminal statuses to 'unknown' instead of leaking raw
internal status into subagent.outcome. HOMELAB-1135.
aaron force-pushed feat/pi-subagent-telemetry from 4ee1d60d3a to 46908fc34a 2026-06-18 04:01:16 +00:00 Compare
aaron merged commit 15a68ff49e into main 2026-06-18 04:01:30 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Homelab/pi-extensions!2
No description provided.