Skip to content

feat(gateway-cli): scope usage-cost by agent#94483

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
ly-wang19:fix/gateway-usage-cost-cli-scope
Jun 22, 2026
Merged

feat(gateway-cli): scope usage-cost by agent#94483
vincentkoc merged 2 commits into
openclaw:mainfrom
ly-wang19:fix/gateway-usage-cost-cli-scope

Conversation

@ly-wang19

Copy link
Copy Markdown
Contributor

Summary

openclaw gateway usage-cost only sent { days } to the usage.cost gateway 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.agentId narrows the summary to one agent, and params.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> → forwards agentId (cost for that one agent).
  • --all-agents → forwards agentScope: "all" (cost across every agent).

They are mutually exclusive: the gateway honors agentScope only when no agentId is 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-agents options, a mutual-exclusion guard, and forward agentId/agentScope to the RPC.
  • src/cli/gateway-cli.coverage.test.ts — 4 tests: --agent forwards agentId; blank --agent is omitted; --all-agents forwards agentScope: "all"; --agent + --all-agents errors before any RPC call.

Real behavior proof

Behavior addressed: the gateway usage-cost CLI could not scope cost by agent (the RPC supports it; the CLI never sent agentId/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 7799 against an isolated OPENCLAW_HOME/OPENCLAW_STATE_DIR; the real openclaw gateway usage-cost CLI was run against it (no model, no network egress). "BEFORE" is the same CLI rebuilt from origin/main (the flags absent).

Exact steps or command run after this patch:

# isolated dev gateway (auth=none), then the real CLI against it:
node scripts/run-node.mjs gateway run --dev --auth none --port 7799 --force   # background
node scripts/run-node.mjs gateway usage-cost --agent alpha --days 7 --json
node scripts/run-node.mjs gateway usage-cost --all-agents --days 7 --json
node scripts/run-node.mjs gateway usage-cost --agent alpha --all-agents --json
# BEFORE: same CLI rebuilt from origin/main (flags do not exist):
git stash && rm -f dist/.buildstamp
node scripts/run-node.mjs gateway usage-cost --agent alpha --days 7 --json

Evidence after fix:

BEFORE (origin/main): gateway usage-cost --agent alpha
  -> OpenClaw does not recognize option "--agent".

AFTER --agent alpha --days 7 --json
  -> { "updatedAt": ..., "days": 8, "totals": { "totalCost": 0, ... }, "cacheStatus": { "status": "fresh", ... } }   (valid summary, RPC round-trip OK)

AFTER --all-agents --days 7 --json
  -> { "updatedAt": ..., "days": 8, "totals": { "totalCost": 0, ... }, "cacheStatus": {...} }   (all-agents path, RPC round-trip OK)

AFTER --agent alpha --all-agents
  -> Gateway usage cost failed: Error: Use --agent or --all-agents, not both   (guard fires; no RPC sent)

Observed result after fix: --agent and --all-agents are accepted and complete a real usage.cost RPC round-trip returning a valid CostUsageSummary; on origin/main the 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 in gateway-cli.coverage.test.ts; the RPC's agent-scoping logic itself is pre-existing and covered by src/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-agents collide with no global gateway option).
  • Formatter (oxfmt), static analysis (oxlint), and tsgo:core typecheck pass for the changed files.
  • Sibling check: usage-cost is the only CLI command in the usage/cost RPC family — sessions.usage / sessions.usage.timeseries / sessions.usage.logs have no CLI command — so no parallel CLI surface is left unscoped.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 18, 2026
@ly-wang19 ly-wang19 force-pushed the fix/gateway-usage-cost-cli-scope branch from 6a54f0d to b517192 Compare June 18, 2026 09:35
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed June 21, 2026, 11:21 PM ET / 03:21 UTC.

Summary
The PR adds --agent <id> and --all-agents to openclaw gateway usage-cost, forwards the matching RPC params, rejects the conflicting flag combination, and adds focused CLI coverage tests.

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 --days for gateway usage-cost and sends { days }, while the gateway already accepts agentId and agentScope. The PR body also supplies before/after terminal output from a real dev gateway run.

Review metrics: 1 noteworthy metric.

  • CLI option surface: 2 added. The PR adds two public operator-facing flags, so maintainers should notice the additive CLI API before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Update docs/cli/gateway.md to document --agent <id> and --all-agents.

Risk before merge

  • [P1] The public CLI reference at docs/cli/gateway.md will remain stale if the two new operator-facing flags merge without docs.

Maintainer options:

  1. Decide the mitigation before merge
    Land the CLI flag wiring together with a matching docs/cli/gateway.md update for --agent <id> and --all-agents.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • A narrow docs-only patch can resolve the only review finding; the implementation itself is not the blocker.

Security
Cleared: The diff only changes CLI option wiring and colocated tests; it does not touch dependencies, workflows, secrets, auth, install scripts, or package metadata.

Review findings

  • [P3] Document the new usage-cost scope flags — src/cli/gateway-cli/register.ts:530-531
Review details

Best possible solution:

Land the CLI flag wiring together with a matching docs/cli/gateway.md update for --agent <id> and --all-agents.

Do we have a high-confidence way to reproduce the issue?

Yes, source inspection gives a high-confidence reproduction path: current main only registers --days for gateway usage-cost and sends { days }, while the gateway already accepts agentId and agentScope. The PR body also supplies before/after terminal output from a real dev gateway run.

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:

  • [P3] Document the new usage-cost scope flags — src/cli/gateway-cli/register.ts:530-531
    docs/cli/gateway.md still documents gateway usage-cost with only --days, but these added lines create two public CLI flags. Please add --agent <id> and --all-agents examples/ParamField entries so the public CLI reference matches the command surface.
    Confidence: 0.91

Overall correctness: patch is correct
Overall confidence: 0.91

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a1828110704f.

Label changes

Label justifications:

  • P3: This is a low-risk additive CLI ergonomics improvement for an existing Gateway RPC, with a narrow documentation gap to resolve.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix live terminal output from a dev gateway showing both new flags completing usage.cost RPC round trips and the conflict guard firing before any RPC call.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live terminal output from a dev gateway showing both new flags completing usage.cost RPC round trips and the conflict guard firing before any RPC call.
Evidence reviewed

PR surface:

Source +12, Tests +49. Total +61 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 13 1 +12
Tests 1 49 0 +49
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 62 1 +61

Acceptance criteria:

  • [P1] pnpm docs:list.
  • [P1] pnpm docs:check-mdx.
  • [P1] git diff --check.

What I checked:

  • PR implementation: The diff adds the two usage-cost flags, trims --agent, rejects --agent plus --all-agents, and forwards { agentId } or { agentScope: "all" } to usage.cost while preserving the default { days } payload. (src/cli/gateway-cli/register.ts:530, b517192d533f)
  • Current main CLI gap: Current main registers gateway usage-cost with only --days and calls usage.cost with { days }, so the CLI cannot request a specific agent or all-agent aggregation today. (src/cli/gateway-cli/register.ts:527, a1828110704f)
  • Existing RPC contract: Current main already normalizes params.agentId, honors agentScope: "all" only when no agent id is set, and passes the scope to the cached cost-summary loader. (src/gateway/server-methods/usage.ts:923, a1828110704f)
  • Sibling UI caller: The Control UI already builds the same agentId or agentScope: "all" params and sends them to both sessions.usage and usage.cost, supporting the PR's choice to reuse the existing gateway contract. (ui/src/ui/controllers/usage.ts:296, a1828110704f)
  • Adjacent gateway tests: Existing tests cover usage.cost passing agentId, aggregating explicit all-agent scope, and keeping default behavior non-aggregated unless agentScope: "all" is explicit. (src/gateway/server-methods/usage.test.ts:296, a1828110704f)
  • Docs gap: The CLI reference still shows only the default, --days, and --json examples plus a single --days ParamField for gateway usage-cost; it does not document the two new public flags. Public docs: docs/cli/gateway.md. (docs/cli/gateway.md:172, a1828110704f)

Likely related people:

  • Alix-007: Merged PR fix(ui): scope usage requests by agent filter #87222 authored the current Gateway/UI usage agent-scope behavior and related protocol documentation that this CLI change exposes. (role: introduced agent-scoped usage contract; confidence: high; commits: 99bd27535985, 6079e7f3c0a9; files: src/gateway/server-methods/usage.ts, ui/src/ui/controllers/usage.ts, docs/gateway/protocol.md)
  • Peter Steinberger: The merged usage-scope PR includes adjacent all-agent and Swift usage-scope commits by this contributor, making them relevant for cross-client behavior questions. (role: adjacent usage-scope contributor; confidence: medium; commits: 9932a64b65da, d67156a3c552; files: src/gateway/server-methods/usage.ts, apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
  • snowzlmbot: Local blame in this shallow/grafted checkout attributes the current gateway usage-cost registration and docs section to this commit, but the history boundary makes original authorship unclear. (role: current-line blame signal; confidence: low; commits: e37b0f8cd384; files: src/cli/gateway-cli/register.ts, docs/cli/gateway.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@vincentkoc vincentkoc force-pushed the fix/gateway-usage-cost-cli-scope branch from b517192 to fbf3f32 Compare June 22, 2026 21:52
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label Jun 22, 2026
ly-wang19 and others added 2 commits June 22, 2026 22:04
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>
@vincentkoc vincentkoc force-pushed the fix/gateway-usage-cost-cli-scope branch from 5c79301 to 30a07f0 Compare June 22, 2026 22:04
@vincentkoc vincentkoc merged commit 75af913 into openclaw:main Jun 22, 2026
13 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 23, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes docs Improvements or additions to documentation P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants