Skip to content

Proposal: expose full per-run diagnostics to local users & external agents (od run inspect + diagnostics API) #5489

Description

@tomsen02

Why

When a chat run fails or runs slow/expensive, the daemon already computes a rich diagnostic picture on the run-terminal path — full failure classification (failure_category, failure_detail, failure_stage, retryable, user_action in run-failure-classification.ts), timing segments (queue / pre-spawn / spawn / first-token / generation / tool / finalize in run-analytics-observability.ts:591-807), and token/cache breakdown (input / output / cache-read / cache-creation / hit-ratio). But almost none of it reaches a local user or an external agent: it is emitted to PostHog/Langfuse telemetry and otherwise dropped.

What's already exposed vs not:

  • feat(chat): surface daemon failure_detail to sharpen run-error guidance #5321 (feat(chat): surface daemon failure_detail) persisted failureCategory / failureDetail onto ChatRunStatusResponse (packages/contracts/src/api/chat.ts:469-473) and renders them as chat-UI guidance. Good — this proposal builds on it, it does not duplicate it.
  • Still unreachable anywhere outside telemetry: failureStage, retryable, user_action, all timing segments, and all token/cache fields.
  • od run has start / watch / cancel / list / info / result-package (cli.ts:5983-5992) but no diagnostics command — the CLI, which AGENTS.md calls the embeddability contract for external agents, exposes none of this.

The pain: a self-hoster who hits a failed run can only see a coarse status: failed / exitCode: 1 unless they happen to be in the chat UI on an AMR-guided path; they cannot ask where it failed, whether it's retryable, or where the time/tokens went. Worse, an external agent driving Open Design through od (the exact integration surface AGENTS.md's dual-track rule protects) has no way to read retryable / user_action to make its own retry or routing decision. The daemon computes the answer and throws it away for everyone not looking at telemetry.

What users will see

  • od run inspect <runId> [--json] — prints the run's full diagnostics: failure classification (category, detail, stage, retryable, user_action), timing segments, and token/cache breakdown. --json for scripts/agents.
  • A run diagnostics panel in the web run detail (expand from the existing error card) showing the same, so the UI reaches parity with the CLI.
  • The /api/* response that backs both.

Surface area

  • CLI / env var — new od run inspect subcommand
  • API / contract — new/extended run-diagnostics endpoint + packages/contracts DTO
  • UI — run diagnostics panel
  • i18n keys — for the new UI panel labels

(This is a dual-track capability per AGENTS.md — landing API + CLI + UI in one PR.)

Scope boundaries (what this does NOT do)

Open questions for maintainers (decide the shape)

  1. Persistence. Timing/token analytics are currently fire-and-forget into the telemetry event, not persisted. To make them queryable after a run finishes, do we (A) persist them on the run object / SQLite — which must follow the RUNTIME_DATA_DIR data-directory contract in AGENTS.md — or (B) expose them only for runs still resident in memory (recent runs), accepting that older runs return classification-only? I lean B for a first slice (smallest, no data-dir surface), with A as a follow-up if there's demand.
  2. Endpoint shape. Extend GET /api/runs/:id (wider response) or add a dedicated GET /api/runs/:id/diagnostics sub-resource (opt-in fetch)? I lean the sub-resource.
  3. Phasing. Land failure-classification completion (stage / retryable / user_action) + od run inspect first, and timing/token as a second PR? That keeps the first PR small and reviewable.

Product relevance

Sits in the #3408 reliability lane, but from the exposure angle rather than the failure-rate-optimization angle (#3547). It directly serves two AGENTS.md invariants: the UI+CLI dual-track rule, and the CLI-as-embeddability-contract principle for external agents. No existing issue proposes local run-diagnostics exposure; #5321 is the nearest and is complementary (chat-guidance for category/detail), not overlapping.

I'm happy to implement this once the scope (esp. Q1/Q3) is blessed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or enhancementneeds-product-directionAwaiting product direction review (see OpenDesign roadmap)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions