Skip to content

--output-format json omits token/cost usage that OTel exposes #4107

Description

@gmpt-jiangning

Describe the feature or problem you'd like to solve

No response

Proposed solution

--output-format json's terminal result event only carries legacy fields (premiumRequests, totalApiDurationMs, sessionDurationMs, codeChanges) under usage. It does not include token counts (input/output/cached) or AI-credit cost, even though this exact data is computed internally during the very same run and is fully available via OpenTelemetry (COPILOT_OTEL_ENABLED / COPILOT_OTEL_FILE_EXPORTER_PATH, documented in copilot help monitoring).

I verified with raw, unmodified CLI output (happy to attach the files):

  • A full, unfiltered JSONL dump of -p ... --output-format json shows the only usage-bearing event is the terminal result, and its usage object has no token/cost fields at all.
  • Enabling the OTel file exporter simultaneously with --output-format json (same invocation) proves the CLI does compute gen_ai.usage.input_tokens / output_tokens / cache_read.input_tokens / cache_creation.input_tokens and github.copilot.nano_aiu (exact AI-credit cost) during the run - it's just never written into the result JSON event.
  • Cross-checked nano_aiu-derived AI Credits against the interactive footer ("AI Credits X.X") in the same session - they match exactly, confirming this is real billing data, not an estimate.

Proposed solution: add inputTokens, outputTokens, cacheReadInputTokens, cacheCreationInputTokens, and aiCredits/costUSD (broken down per model if more than one model was used in the run) to the terminal result event's usage object in --output-format json, mirroring what OTel's chat spans already export. This would make --output-format json self-sufficient for accurate cost accounting without requiring a full OTel pipeline for simple scripting/automation use cases.

Example prompts or workflows

  1. CI pipeline running copilot -p "<task>" --output-format json per job step, parsing result.usage directly to log real per-task USD cost - no OTel collector needed.
  2. Agent-orchestration frameworks (e.g. workflow engines that shell out to copilot as one of several interchangeable LLM-CLI backends) recording accurate per-node cost alongside output/session data from a single JSON parse.
  3. Budget-alerting scripts that tail result events and sum costUSD/aiCredits across many non-interactive invocations without standing up OTel infrastructure just to get numbers already in memory.
  4. Local dev tooling that shows "this command cost $X" right after a scripted -p call, matching what the interactive footer already shows for interactive sessions.

Additional context

Environment: GitHub Copilot CLI 1.0.70, Windows.

Raw evidence available on request (unfiltered JSONL dumps + OTel raw export files from side-by-side runs of the same prompt with/without OTel enabled, plus the interactive footer output used for cross-validation). Happy to attach as files once this issue is reviewed.

Root-cause hypothesis: result.usage looks like a schema left over from the pre-"AI Credits" (legacy premium-request) billing era that was never updated when AI Credits + full token/cost telemetry was added via OTel - i.e. a schema sync gap rather than an intentional interactive-only restriction (copilot help billing documents credit/token visibility only through interactive surfaces - footer, /statusline, /model, /context, /usage, /exit - but OTel proves the same data is available non-interactively too).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:modelsModel selection, availability, switching, rate limits, and model-specific behaviorarea:non-interactiveNon-interactive mode (-p), CI/CD, ACP protocol, and headless automation

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions