Skip to content

fix(agent-platform): gateway-only generation events; never use pi cost estimates - #65457

Merged
benjackwhite merged 3 commits into
masterfrom
ben/agent-observability-gateway-cost
Jun 24, 2026
Merged

benjackwhite merged 3 commits into
masterfrom
ben/agent-observability-gateway-cost

Conversation

@benjackwhite

Copy link
Copy Markdown
Contributor

Problem

The agent observability board showed $0 spend / 7d (and a broken "Cost by model" panel) for agents even though sessions clearly had cost.

On the ai-gateway path there are two $ai_generation events per turn in the owning team's project:

$ai_origin $agent_application_id $ai_total_cost_usd
Runner's event agent_platform_runner ✅ ❌ (suppressed)
Gateway's event ❌ ❌ ✅ settled cost

The board scoped on $ai_origin = 'agent_platform_runner' and summed $ai_total_cost_usd, so it only ever matched the runner's cost-less event → $0. The gateway's cost-bearing event was unattributed to the agent. Pure double-reporting.

Fix (runner side)

Make the gateway the single source of generation events on the gateway path:

  • Forward attribution to the gateway — the runner sends $agent_application_id + $agent_session_id via X-PostHog-Properties, so the gateway's $ai_generation is sliceable per agent. (The gateway keeps $agent_* keys and strips $ai_*.)
  • Suppress the runner's duplicate $ai_generation on the gateway path (it still emits $ai_span + $ai_trace, which the gateway has no concept of). Off the gateway path the runner emits the generation without cost and lets PostHog ingestion price it from the catalog.
  • Never use pi-ai's client-side cost estimates anywhere — accumulateUsage no longer trusts usage.cost.*; the session row's cost_total comes only from the gateway's settled /v1/usage figure.
  • Renamed useGatewayCost → gatewayEmitsGenerations to match the new role.

Paired change

The observability board re-scopes every panel from $ai_origin to $agent_application_id (present on generations, tool spans, and traces, on both gateway and direct paths) — PostHog/code#2837. Both are needed for the fix to land; each is independently safe (current runner events already carry $agent_application_id).

Notes

  • Off the gateway path, the session-row cost is now 0 (no authoritative source; pi estimates are intentionally dropped). Event-level cost still appears in LLM Analytics via ingestion's catalog pricing. In practice agent traffic runs through the gateway.
  • A separate data bug surfaced while debugging: the ingestion cost catalog prices gpt-5.5 (via OpenRouter) negative on ~half its generations. This PR's passthrough cost sidesteps it for agent traffic; the catalog itself is out of scope here.

Verification

  • agent-shared / agent-runner / agent-janitor typecheck clean; oxfmt + oxlint clean on touched files.
  • summarize-conversation unit tests updated + green (pi cost never accumulated).
  • New driver tests assert the emission split (gateway suppresses generation + still traces; direct emits one without cost).
  • The driver emission tests need PG/Redis/Kafka — they exercise on the agent-tests CI gate.

🤖 Generated with Claude Code

…t estimates

On the ai-gateway path the gateway already emits a cost-bearing $ai_generation,
but the runner emitted a second, cost-suppressed one too. The agent
observability board reads the runner's events, so agent spend showed $0 while
the gateway's cost-bearing events sat unattributed. Fix the split:

- Runner forwards $agent_application_id + $agent_session_id to the gateway via
  X-PostHog-Properties, so the gateway's $ai_generation is attributable per
  agent (the gateway keeps $agent_* keys, strips $ai_*).
- On the gateway path the runner suppresses its own $ai_generation (gateway
  emits it) but still emits $ai_span + $ai_trace. Off the gateway path it emits
  the generation without cost and lets PostHog ingestion price it.
- accumulateUsage never uses pi-ai's client-side cost estimates anywhere; the
  session row's cost comes only from the gateway's settled /v1/usage figure.
- Rename useGatewayCost -> gatewayEmitsGenerations to match the new role.

Pairs with the code-repo board change that re-scopes the observability queries
to $agent_application_id (PostHog/code#2837).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(agent-platform): gateway-only genera..." | Re-trigger Greptile

accumulateUsage no longer folds pi-ai's conversation cost estimates, so
the backfill walk rewrites tokens but leaves cost_total at zero. Update
the stale assertion to match.

Generated-By: PostHog Code
Task-Id: 689bbb54-fe12-40cf-8ff1-2c2feda1ad23
Resolve conflict in agent-runner driver.ts: keep the gateway-only
generation emit (guarded by deps.gatewayEmitsGenerations, no pi-ai
cost) from this branch, drop master's removed deps.useGatewayCost
reference, and adopt master's is_preview field on the event.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@benjackwhite
benjackwhite merged commit d96f9b4 into master Jun 24, 2026
182 checks passed
@benjackwhite
benjackwhite deleted the ben/agent-observability-gateway-cost branch June 24, 2026 09:47
@deployment-status-posthog

deployment-status-posthog Bot commented Jun 24, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-06-24 10:09 UTC Run
prod-us ✅ Deployed 2026-06-24 10:27 UTC Run
prod-eu ✅ Deployed 2026-06-24 10:31 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants