feat(gateway-cli): scope usage-cost by agent#94483
Conversation
6a54f0d to
b517192
Compare
|
Codex review: needs changes before merge. Reviewed June 21, 2026, 11:21 PM ET / 03:21 UTC. Summary PR surface: Source +12, Tests +49. Total +61 across 2 files. Reproducibility: yes. source inspection gives a high-confidence reproduction path: current main only registers Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land the CLI flag wiring together with a matching Do we have a high-confidence way to reproduce the issue? Yes, source inspection gives a high-confidence reproduction path: current main only registers Is this the best way to solve the issue? Mostly yes. The CLI is the right layer because the RPC and Control UI already share this scope contract; the remaining best-fix work is keeping the public CLI reference aligned with the new flags. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against a1828110704f. Label changesLabel justifications:
Evidence reviewedPR surface: Source +12, Tests +49. Total +61 across 2 files. View PR surface stats
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
b517192 to
fbf3f32
Compare
The `gateway usage-cost` CLI only sent `{ days }` to the `usage.cost` RPC, so
callers could not break cost down per agent or aggregate across all agents the
way the Control UI can. Add `--agent <id>` (forwards `agentId`, scoping to one
agent) and `--all-agents` (forwards `agentScope: "all"`, aggregating every
agent). The two are mutually exclusive because the gateway honors `agentScope`
only when no `agentId` is set; passing both now errors instead of silently
dropping `--all-agents`. No flag keeps the existing default-agent behavior.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5c79301 to
30a07f0
Compare
* feat(gateway-cli): scope usage-cost by agent
The `gateway usage-cost` CLI only sent `{ days }` to the `usage.cost` RPC, so
callers could not break cost down per agent or aggregate across all agents the
way the Control UI can. Add `--agent <id>` (forwards `agentId`, scoping to one
agent) and `--all-agents` (forwards `agentScope: "all"`, aggregating every
agent). The two are mutually exclusive because the gateway honors `agentScope`
only when no `agentId` is set; passing both now errors instead of silently
dropping `--all-agents`. No flag keeps the existing default-agent behavior.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(gateway-cli): scope usage-cost by agent
---------
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Summary
openclaw gateway usage-costonly sent{ days }to theusage.costgateway RPC (src/cli/gateway-cli/register.ts:535), even though the handler already accepts agent scoping (src/gateway/server-methods/usage.ts:982-990):params.agentIdnarrows the summary to one agent, andparams.agentScope: "all"aggregates every agent. The Control UI uses both, but the CLI could only ever report the default agent, so operators running multiple agents had no way to see per-agent or all-agent cost from the terminal.This adds the two missing agent-scoping flags to the CLI command:
--agent <id>→ forwardsagentId(cost for that one agent).--all-agents→ forwardsagentScope: "all"(cost across every agent).They are mutually exclusive: the gateway honors
agentScopeonly when noagentIdis set (usage.ts:983), so passing both now errors instead of silently dropping--all-agents. With no flag the wire payload stays exactly{ days }, so existing default-agent behavior is unchanged.--days(the existing date-range flag) is intentionally left as-is; only the agent dimension is added.Changes
src/cli/gateway-cli/register.ts— add--agent/--all-agentsoptions, a mutual-exclusion guard, and forwardagentId/agentScopeto the RPC.src/cli/gateway-cli.coverage.test.ts— 4 tests:--agentforwardsagentId; blank--agentis omitted;--all-agentsforwardsagentScope: "all";--agent+--all-agentserrors before any RPC call.Real behavior proof
Behavior addressed: the
gateway usage-costCLI could not scope cost by agent (the RPC supports it; the CLI never sentagentId/agentScope). It now exposes--agent <id>and--all-agents, mutually exclusive.Real environment tested: Node 22.22.1, macOS. A dev gateway built from source and run with
gateway run --dev --auth none --port 7799against an isolatedOPENCLAW_HOME/OPENCLAW_STATE_DIR; the realopenclaw gateway usage-costCLI was run against it (no model, no network egress). "BEFORE" is the same CLI rebuilt fromorigin/main(the flags absent).Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix:
--agentand--all-agentsare accepted and complete a realusage.costRPC round-trip returning a validCostUsageSummary; onorigin/mainthe same flags are rejected as unknown options. The mutually-exclusive combination is rejected before any RPC call.What was not tested: per-agent cost differentiation with seeded session-log cost data — the isolated env has no usage history, so every summary is zero. The exact wire payload the CLI sends for each flag (
{ days, agentId },{ days, agentScope: "all" }, blank-omitted{ days }, and the conflict rejection) is asserted by the colocated tests ingateway-cli.coverage.test.ts; the RPC's agent-scoping logic itself is pre-existing and covered bysrc/infra/session-cost-usage.test.ts.Additional checks
pnpm test src/cli/gateway-cli.coverage.test.ts— 27 pass (incl. the 4 new cases).register.option-collisions.test.ts— green (--agent/--all-agentscollide with no global gateway option).oxfmt), static analysis (oxlint), andtsgo:coretypecheck pass for the changed files.usage-costis the only CLI command in the usage/cost RPC family —sessions.usage/sessions.usage.timeseries/sessions.usage.logshave no CLI command — so no parallel CLI surface is left unscoped.