Skip to content

OTel spans for subagent calls omit billing attributes (github.copilot.nano_aiu, github.copilot.cost), so external cost accounting undercounts actual billing #4224

Description

@stefanpinson

Describe the bug

When a session delegates work to subagents (the task tool / custom agents), the OTel spans for those subagent model calls omit all billing attributes. The subagent calls consume real AI credits (per the cumulative session display — see #4207, which notes session usage "including usage by the main agent, subagents, and background operations"), but that consumption is invisible to OpenTelemetry, so any external cost accounting built on the documented OTel telemetry (copilot help monitoring) systematically undercounts actual billing.

Main-agent chat spans carry the full billing envelope:

  • github.copilot.nano_aiu
  • github.copilot.cost
  • github.copilot.initiator (user / agent)
  • github.copilot.interaction_id / github.copilot.turn_id

Subagent model calls emit spans with correct gen_ai.* semconv attributes (gen_ai.operation.name, gen_ai.request.model, gen_ai.usage.input_tokens / output_tokens / cache_read.input_tokens / cache_creation.input_tokens) but carry none of the github.copilot.* billing attributes — no nano_aiu, no cost, not even initiator or an interaction id. This holds at every level:

  1. The subagent's child chat spans: no billing attributes.
  2. The subagent's own nested invoke_agent span (which does carry gen_ai.agent.name and rolled-up token counts): no billing attributes.
  3. The session root invoke_agent span's github.copilot.nano_aiu rollup equals the sum of the main-agent chat spans' nano_aiu exactly — i.e. the subagent spend is not folded in anywhere.

Observed within a single trace from one session (models are our configured custom-agent models; the same holds for built-in task delegation):

Span Model gen_ai.usage.input_tokens nano_aiu cost
root invoke_agent claude-fable-5 1,963,612 506,956,900,000 13
main-agent chat × 13 claude-fable-5 present on every one; sums to exactly 506,956,900,000 1 each
nested invoke_agent (custom agent A) claude-haiku-4.5 296,978 absent absent
nested invoke_agent (custom agent B) gpt-5.6-terra 155,061 absent absent
subagent chat spans claude-haiku-4.5 / gpt-5.6-terra 124K–321K each absent absent

In our sessions the unreported subagent calls account for roughly 10–15% of estimated session cost (rate-card priced from the token counts, which are reported).

Affected version

GitHub Copilot CLI 1.0.73

Steps to reproduce the behavior

  1. Enable OTel export (COPILOT_OTEL_ENABLED with an OTLP endpoint, or COPILOT_OTEL_FILE_EXPORTER_PATH).
  2. Run an interactive session and issue a prompt that delegates to a subagent — e.g. a custom agent configured with a different model, or anything that triggers the task tool.
  3. Inspect the exported spans for the session trace.
  4. Main-agent chat spans carry github.copilot.nano_aiu / github.copilot.cost; the subagent invoke_agent and chat spans carry token usage but no billing attributes, and the root rollup excludes them.

Expected behavior

Subagent model calls should carry the same billing attributes as main-agent calls (github.copilot.nano_aiu, github.copilot.cost), so that OTel-based cost accounting matches what is actually billed. Alternatively, if this is intentional (subagent calls genuinely bill zero credits), it would be great to have that documented in copilot help billing / the monitoring docs — though the cumulative session credit display suggests they are billed.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:agentsSub-agents, fleet, autopilot, plan mode, background agents, and custom agents

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions