Skip to content

fix(ui): pass agentId in sessions.usage request for usage page#87190

Closed
Linux2010 wants to merge 4 commits into
openclaw:mainfrom
Linux2010:fix/87132-usage-agent-filter
Closed

fix(ui): pass agentId in sessions.usage request for usage page#87190
Linux2010 wants to merge 4 commits into
openclaw:mainfrom
Linux2010:fix/87132-usage-agent-filter

Conversation

@Linux2010
Copy link
Copy Markdown
Contributor

Fixes #87132

Summary

  • Added usageAgentId to UsageState and AppViewState to track selected agent for usage page
  • Pass agentId in sessions.usage API request when an agent is selected
  • Created renderAgentFilter that uses onAgentChange callback instead of client-side query tokens
  • Use agents from agentsList instead of loaded sessions for agent filter options

Root cause

After commit 6a12c6f (v2026.5.17), the sessions.usage backend scopes session discovery by agentId, defaulting to "main" when no agentId is provided. The Web UI frontend never sent agentId in the API request, so non-main agent sessions were never returned. The agent filter UI was client-side only (using query tokens), which didn't affect the API parameters.

Real behavior proof

Behavior addressed: Usage page agent filter now sends agentId to sessions.usage backend API, allowing non-main agent sessions to be returned when selected.

Real environment tested: Local macOS source checkout of PR branch fix/87132-usage-agent-filter, Vitest unit tests.

Exact steps or command run after this patch:

node scripts/run-vitest.mjs ui/src/ui/controllers/usage.node.test.ts ui/src/ui/views/usage.test.ts --reporter=dot
pnpm build

Evidence after fix:

 RUN  v4.1.7

 Test Files  2 passed (2)
      Tests  12 passed (12)

test: sends agentId when usageAgentId is set
  ✓ sessions.usage params include agentId: "testclaw"

test: omits agentId when usageAgentId is null
  ✓ sessions.usage params do not have agentId property

build: ✓ built in 662ms

Observed result after fix:

  • Server-side: sessions.usage request includes agentId parameter when usageAgentId is set
  • Client-side: Agent filter dropdown shows all configured agents from agentsList, uses onAgentChange callback
  • Tests: 12 tests pass including new agent filtering tests

What was not tested: Live Control UI browser test with multi-agent configuration; behavior verified via unit tests.

Verification

  • node scripts/run-vitest.mjs ui/src/ui/controllers/usage.node.test.ts ui/src/ui/views/usage.test.ts — 12 tests pass
  • pnpm build — successful

- Add usageAgentId to UsageState and AppViewState
- Pass agentId in sessions.usage API request when selected
- Add renderAgentFilter that uses onAgentChange callback instead of query tokens
- Use agents from agentsList instead of loaded sessions for agent options
- Add tests for agentId parameter in sessions.usage request

Fixes openclaw#87132
@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: S proof: supplied External PR includes structured after-fix real behavior proof. labels May 27, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

The merged replacement path now implements the useful part of this PR on current main and covers a broader, safer contract: selected agents send agentId, default usage sends explicit all-agent scope, costs are scoped the same way, and gateway/protocol compatibility is updated. This PR's remaining branch conflicts with the merged implementation and would reintroduce the narrower default-agent semantics, so keeping it open is no longer useful.

Canonical path: Close this PR in favor of the merged replacement implementation and keep validating the broader all-agent usage behavior from current main until it ships.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this PR in favor of the merged replacement implementation and keep validating the broader all-agent usage behavior from current main until it ships.

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

Yes, source inspection gives a high-confidence reproduction for the original bug: v2026.5.27 lacks usageAgentId/agentScope, while current main sends selected-agent and all-agent scope parameters. I did not run a live browser in this read-only cleanup review.

Is this the best way to solve the issue?

No, this PR is no longer the best way to solve it. The merged replacement is broader and cleaner because it updates the UI, gateway, protocol/docs, Swift model, all-agent default behavior, selected-agent cost usage, and compatibility fallbacks together.

Security review:

Security review cleared: The branch only changes Control UI usage state/view/controller tests and English i18n; no concrete security or supply-chain issue was found in the proposed diff.

AGENTS.md: found and applied where relevant.

What I checked:

  • Current main source implements selected-agent and all-agent request scoping: At current main, loadUsage derives usageAgentId, sends agentId when selected, sends agentScope: "all" when no agent is selected, and applies the same scope to both sessions.usage and usage.cost. (ui/src/ui/controllers/usage.ts:279, 8a60f39221db)
  • Current main backend supports explicit all-agent usage: Current main accepts agentScope: "all", rejects invalid combinations with agentId or key, and skips agent filtering only for explicit all-agent requests. (src/gateway/server-methods/usage.ts:963, 8a60f39221db)
  • Current main tests cover the central behavior: The current usage controller tests assert default all-agent requests, selected-agent agentId requests for both session and cost usage, and legacy fallback behavior for unsupported agentId and agentScope. (ui/src/ui/controllers/usage.node.test.ts:109, 8a60f39221db)
  • Merged superseding PR provenance: Commit 99bd275 is the merged replacement for fix(ui): scope usage requests by agent filter #87222 and its commit message states it fixes the linked bug by adding all-agent default scope, selected-agent agentId, gateway aggregation, protocol/docs updates, compatibility fallbacks, and focused verification. (99bd27535985)
  • This PR is narrower than the merged replacement: This PR branch only changes the UI-side files and does not include the merged gateway/protocol/docs/Swift surface from the replacement, so it no longer owns the best remaining fix path. (684004a2d331)
  • Merge simulation shows direct overlap with current main: A read-only merge-tree against the PR base and current main shows both sides changed the same usage controller, view, state, and locale files, with conflict markers in usage controller tests and controller code around the agent-scope changes. (ui/src/ui/controllers/usage.ts:19, 684004a2d331)

Likely related people:

  • Alix-007: Authored merged commit 99bd275 for the superseding usage-agent fix in fix(ui): scope usage requests by agent filter #87222. (role: replacement implementation author; confidence: high; commits: 99bd27535985; files: ui/src/ui/controllers/usage.ts, ui/src/ui/views/usage.ts, ui/src/ui/app-render-usage-tab.ts)
  • pgondhi987: Commit 6a12c6f added agent-scoped usage lookups and the default-agent fallback that made the Web UI gap visible. (role: related backend behavior author; confidence: high; commits: 6a12c6f79915; files: src/gateway/server-methods/usage.ts, apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
  • joshavant: Local history shows several prior usage controller refactors and simplifications, making this a useful routing candidate for Control UI usage behavior. (role: adjacent UI usage contributor; confidence: medium; commits: 594de84d04f1, b658e5d35ccc; files: ui/src/ui/controllers/usage.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8a60f39221db; fix evidence: commit 99bd27535985, main fix timestamp 2026-05-29T02:03:33+01:00.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 27, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

ClawSweeper PR egg

🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress.

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.
What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@Linux2010
Copy link
Copy Markdown
Contributor Author

Linux2010 commented May 27, 2026

Verification Proof

Unit Tests

Test file: ui/src/ui/controllers/usage.node.test.ts

Test Results:

Test Files  1 passed (1)
Tests       11 passed (11)

Live Proof (Playwright)

Script: scripts/verify-usage-agent-filter.mjs

Test Flow:

  1. Open Control UI Usage page
  2. Initial sessions.usage request has no agentId
  3. Click Agent filter dropdown
  4. Select "testclaw" agent
  5. New sessions.usage request includes agentId: "testclaw"

Captured WebSocket Request:

{
  "startDate": "2026-05-27",
  "endDate": "2026-05-27",
  "mode": "specific",
  "utcOffset": "UTC+8",
  "groupBy": "family",
  "includeHistorical": true,
  "agentId": "testclaw",
  "limit": 1000,
  "includeContextWeight": true
}

Screenshots: /Users/hope/ai-project/openclaw/.artifacts/usage-agent-filter-proof/

Summary

  • ✅ Unit tests pass (11 tests)
  • ✅ Live proof confirms agentId passed to sessions.usage when agent selected
  • ✅ Initial request correctly omits agentId when no agent selected

Fix Implementation

  • ui/src/ui/controllers/usage.ts: Passes agentId in sessions.usage request when state.usageAgentId is set
  • ui/src/ui/app.ts: Added usageAgentId state property
  • ui/src/ui/views/usage.ts: Added renderAgentFilter with onAgentChange callback

@Linux2010
Copy link
Copy Markdown
Contributor Author

Linux2010 commented May 27, 2026

Verification: Usage Page Agent Filter

Verdict: PASS

Claim: When selecting an agent in Control UI Usage page, the sessions.usage WebSocket request should include the agentId parameter to filter sessions by that agent.

Method: Playwright browser automation with WebSocket frame capture. Gateway running with --auth none on port 18789.

Steps

  1. ✅ Open Usage page at http://127.0.0.1:18789/usage → WebSocket request sent without agentId
  2. ✅ Click Agent filter dropdown (显示"代理") → Shows agent options: 全部, main, testclaw, telegram, bailian, qwen3.6-plus, exec, session_status
  3. ✅ Select "testclaw" agent → WebSocket request sent with agentId: "testclaw"
  4. 🔍 Initial request had no agentId field → Confirmed baseline
  5. 🔍 After selecting agent → agentId present in request payload

WebSocket Request Evidence

Before selecting agent (无 agentId):

{
  "startDate": "2026-05-27",
  "endDate": "2026-05-27",
  "mode": "specific",
  "utcOffset": "UTC+8",
  "groupBy": "family",
  "includeHistorical": true,
  "limit": 1000,
  "includeContextWeight": true
}

After selecting testclaw (包含 agentId):

{
  "startDate": "2026-05-27",
  "endDate": "2026-05-27",
  "mode": "specific",
  "utcOffset": "UTC+8",
  "groupBy": "family",
  "includeHistorical": true,
  "agentId": "testclaw",
  "limit": 1000,
  "includeContextWeight": true
}

Screenshots

Local path: .artifacts/usage-agent-filter-proof/

  • 01-usage-initial.png - Usage page initial state
  • 02-agent-filter-open.png - Agent filter dropdown with options
  • 03-agent-selected.png - Page after selecting testclaw
  • 04-final.png - Final state with filter applied

Findings

  • Fix correctly passes agentId to sessions.usage request when agent is selected
  • WebSocket frame capture confirms the API contract is honored
  • UI shows Chinese translation "代理" for Agent filter
01-usage-initial 02-agent-filter-open 03-agent-selected 04-final

@Linux2010
Copy link
Copy Markdown
Contributor Author

@clawsweeper please review - verification proof added with screenshots

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 27, 2026
- Add retry/cache pattern for unsupported agentId param in sessions.usage
- Similar to existing date/scope legacy fallback patterns
- Change 'All' filter label to 'Default' to accurately reflect backend behavior
- Add focused controller test for agentId fallback

Addresses ClawSweeper review findings:
- [P2] Preserve older-gateway usage compatibility
- [P2] Do not label default-scoped usage as All
@openclaw-barnacle openclaw-barnacle Bot added size: M and removed size: S proof: sufficient ClawSweeper judged the real behavior proof convincing. labels May 27, 2026
@Linux2010
Copy link
Copy Markdown
Contributor Author

Fix Applied

Addressed both ClawSweeper findings:

1. Older-gateway compatibility (P2)

Added retry/cache pattern for unsupported agentId param in sessions.usage:

  • New storage key: openclaw.control.usage.agent-id-params.v1
  • Error detection regex: unexpected property 'agentId'
  • Same retry pattern as existing date/scope fallbacks
  • Falls back gracefully on older gateways (pre-6a12c6f79915)

2. Default agent label (P2)

Changed "All" filter label to "Default" to accurately reflect backend behavior:

  • When agentId is null, backend returns default agent data, not all agents
  • New i18n key: usage.filters.defaultAgent
  • Avoids misleading users about what data they're viewing

Test Coverage

Added focused controller test for agentId fallback:

  • Tests error detection and retry behavior
  • Tests cache persistence across reloads
  • All 12 tests pass

Files Changed

  • ui/src/ui/controllers/usage.ts - Added agentId compatibility retry
  • ui/src/ui/controllers/usage.node.test.ts - Added fallback test
  • ui/src/ui/views/usage.ts - Changed label to "Default"
  • ui/src/i18n/locales/en.ts - Added defaultAgent key

Commit: 0e60e40

@Linux2010
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 27, 2026
@Linux2010
Copy link
Copy Markdown
Contributor Author

@clawsweeper review

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Re-review progress:

…label in closed badge

- Add client-side session filtering when agentId fallback is triggered
- Change closed agent badge to show 'Default' instead of 'All'
- Addresses ClawSweeper review findings:
  - [P2] Preserve selected-agent filtering after legacy retry
  - [P2] Show Default in the closed agent badge
@Linux2010
Copy link
Copy Markdown
Contributor Author

Additional Fixes Applied

Addressed 2 of 3 ClawSweeper findings:

1. ✅ Client-side agent filtering after legacy retry (P2)

Added agentIdFallback flag to track when server-side filtering is disabled.
When fallback is triggered, filter sessions client-side:

if (agentIdFallback && state.usageAgentId) {
  filteredRes.sessions = filteredRes.sessions.filter(
    (s) => s.agentId === state.usageAgentId,
  );
}

2. ✅ Default label in closed badge (P2)

Changed line 425 from t("usage.filters.all") to t("usage.filters.defaultAgent").

3. ⚠️ i18n locale bundles - Blocked

pnpm ui:i18n:sync failed due to OpenAI API key error:

OpenAI API error (401): 401 Incorrect API key provided

This is an environment configuration issue. The generated locale bundles cannot be updated until the API key is configured correctly.

Commit: 684004a

@Linux2010
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 27, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 27, 2026
@BingqingLyu

This comment was marked as spam.

@clawsweeper clawsweeper Bot added 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. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. labels May 29, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 29, 2026

ClawSweeper applied the proposed close for this PR.

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

Labels

app: web-ui App: web-ui merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. 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: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: M 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.

[Bug]: Usage page agent filter broken since v2026.5.17 – sessions.usage API always scoped to "main" agent

3 participants