Skip to content

fix(usage): return all agent sessions when no agentId specified#87335

Closed
Jefsky wants to merge 3 commits into
openclaw:mainfrom
Jefsky:fix/usage-agent-filter
Closed

fix(usage): return all agent sessions when no agentId specified#87335
Jefsky wants to merge 3 commits into
openclaw:mainfrom
Jefsky:fix/usage-agent-filter

Conversation

@Jefsky
Copy link
Copy Markdown
Contributor

@Jefsky Jefsky commented May 27, 2026

Summary

Fixes #87132.

When no is specified in the request, the backend previously defaulted to returning only the default agent's sessions (usually "main"). This caused the Web UI's agent filter to only show main agent sessions, making it impossible to filter by other agents.

Changes

  • When is omitted and no specific session key is provided, is now instead of defaulting to the configured default agent
  • When is undefined, skip the step so all agents' sessions are returned
  • Updated test to verify that sessions from all configured agents are returned when no agentId is specified

Test Plan

  • Updated existing test to expect all agent sessions returned when no agentId is specified
  • Verified existing tests for specific agentId filtering still pass

Issue: #87132

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. size: XS 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.

Close: the linked usage bug is already solved on current main by the merged explicit-scope implementation in #87222, while this branch changes the omitted-agent default in a way that conflicts with the gateway scoping contract.

Canonical path: Keep current main's explicit agentScope: "all" contract from #87222 and close this branch instead of changing the omitted-agent default.

So I’m closing this here and keeping the remaining discussion on #87222.

Review details

Best possible solution:

Keep current main's explicit agentScope: "all" contract from #87222 and close this branch instead of changing the omitted-agent default.

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

Yes, by source inspection: this branch sets effectiveAgentId to undefined for omitted agentId and no key, which loads and returns the unfiltered combined session store. Current main and tests show the intended default is scoped unless agentScope: "all" is explicit.

Is this the best way to solve the issue?

No. The maintainable fix is the merged explicit-scope path: the UI asks for all agents intentionally, while existing gateway callers that omit agentId keep the scoped default.

Security review:

Security review needs attention: The diff broadens a session-usage boundary by making omitted agentId return all agents; current main uses explicit all-agent intent instead.

  • [high] Do not broaden omitted-agent session scope — src/gateway/server-methods/usage.ts:883
    Changing the default to an unfiltered combined session store can expose cross-agent session usage metadata to callers that currently rely on default-agent scoping.
    Confidence: 0.92

AGENTS.md: found and applied where relevant.

What I checked:

  • Current main keeps omitted agentId scoped: On current main, sessions.usage only treats the request as all-agent when agentScope === "all"; otherwise it normalizes requestedAgentId ?? specificKeyAgentId ?? resolveDefaultAgentId(config), preserving the default-agent scoped behavior for omitted agentId. (src/gateway/server-methods/usage.ts:963, 98611e62728e)
  • Current UI uses explicit all-agent scope: When no usage agent is selected, the Control UI sends agentScope: "all" to both sessions.usage and usage.cost, so the UI gets cross-agent usage without relying on an unscoped default. (ui/src/ui/controllers/usage.ts:295, 98611e62728e)
  • Current tests cover both default and explicit all-agent behavior: The current gateway tests assert omitted agentId defaults to main, and a separate agentScope: "all" case returns sessions from both configured agents. (src/gateway/server-methods/usage.sessions-usage.test.ts:179, 98611e62728e)
  • Merged replacement provenance: Commit 99bd2753598534581f6da585a0562cef6962c7be from the merged replacement changed gateway usage, UI usage, protocol schema, docs, and tests to add explicit all-agent usage scope and fix the linked bug. (99bd27535985)
  • Original scoped-default provenance: Commit 6a12c6f7991547c0bf82323392ca327f4de016a3 introduced gateway session data scoping by agent, making a silent return to all-agent defaults compatibility- and security-sensitive. (src/gateway/server-methods/usage.ts, 6a12c6f79915)
  • This PR changes the risky default: The PR diff sets effectiveAgentId to undefined when agentId and key are omitted, which makes the handler load an unfiltered combined store for existing callers that do not pass an agent. (src/gateway/server-methods/usage.ts:883, 6a8c94fc5a0b)

Likely related people:

  • Alix-007: Authored the merged replacement commit that added explicit agentScope: "all" handling across gateway, UI, protocol, docs, and tests. (role: merged replacement author; confidence: high; commits: 99bd27535985; files: src/gateway/server-methods/usage.ts, ui/src/ui/controllers/usage.ts, src/gateway/server-methods/usage.sessions-usage.test.ts)
  • pgondhi987: The related issue identifies this author as the PR author for the gateway hardening commit that scoped session data lookups by agent; local commit metadata shows the same scoped-default change. (role: introduced scoped behavior; confidence: high; commits: 6a12c6f79915; files: src/gateway/server-methods/usage.ts, src/gateway/server-methods/usage.sessions-usage.test.ts)
  • Peter Steinberger: Recent local history and blame show follow-up work on the current usage surface, including the Swift protocol compatibility commit and current checkout integration. (role: recent adjacent contributor; confidence: medium; commits: d67156a3c552, d8f2437cf4a9; files: apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift, scripts/protocol-gen-swift.ts, src/gateway/server-methods/usage.ts)
  • Tak Hoffman: Historical usage-path log includes earlier multi-agent sessions.usage discovery and Web UI usage dashboard work, making this a plausible routing candidate for the area. (role: earlier feature contributor; confidence: medium; commits: 9271fcb3d49f, 8a352c8f9dfd; files: src/gateway/server-methods/usage.ts, ui/src/ui/controllers/usage.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 98611e62728e; 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. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 27, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 27, 2026

ClawSweeper PR egg: 🎁 locked until real behavior proof passes.

Details
  • No creature or rarity is rolled until proof passes.
  • Eggs are collectible flavor only; they do not affect labels, ratings, merge decisions, or automation.

@Jefsky
Copy link
Copy Markdown
Contributor Author

Jefsky commented May 27, 2026

Behavior Proof: sessions.usage default scope change

Code Analysis

Before (main branch):

const effectiveAgentId = normalizeAgentId(
  requestedAgentId ?? specificKeyAgentId ?? resolveDefaultAgentId(config),
);

When agentId is omitted in a list-style query (no key), effectiveAgentId defaults to "main"loadCombinedSessionStoreForGateway only loads main agent sessions → filterSessionStoreByAgent further scopes to main only.

After (this PR):

const effectiveAgentId: string | undefined = requestedAgentId
  ? normalizeAgentId(requestedAgentId)
  : specificKeyAgentId
    ? normalizeAgentId(specificKeyAgentId)
    : specificKey
      ? normalizeAgentId(resolveDefaultAgentId(config))
      : undefined;

When agentId is omitted AND no key is provided: effectiveAgentId = undefinedloadCombinedSessionStoreForGateway(config, {}) loads all agents' stores → scopedStore = store (no filter applied).

Why This Is Safe

  1. loadCombinedSessionStoreForGateway with undefined agentId: Calls resolveAllAgentSessionStoreTargetsSync(cfg) which iterates all configured agents' session directories — same behavior the Web UI already uses when listing agents.

  2. No filtering on scopedStore: When effectiveAgentId is undefined, the full combined store passes through. This is the correct behavior for a "list all" query.

  3. Existing agentId/specificKey queries unaffected: When agentId IS provided, the code still normalizes and filters as before. When a key is provided without agentId, it defaults to the key's agent.

Test Coverage

The updated test (usage.sessions-usage.test.ts:179) verifies:

  • loadCombinedSessionStoreForGateway called with {} (no agentId)
  • discoverAllSessions called for each configured agent (main, opus)
  • Returns sessions from all agents
  • Existing tests for agentId="opus" (line 197), specific key lookups (line 334), and out-of-scope filtering (line 307) all remain valid

Live Server Note

This server has 2 configured agents (main, main-flash) but only main has active sessions, so a live multi-agent demo isn't possible here. The unit test with mocked multi-agent stores is the appropriate proof for this change.

Fixes openclaw#87132.

When no agentId is specified in the sessions.usage request, the backend
previously defaulted to returning only the default agent's sessions.
This caused the Web UI's agent filter to only show main agent sessions.

- When agentId is omitted and no specific session key is provided,
  effectiveAgentId is now undefined instead of defaulting to the
  configured default agent
- When effectiveAgentId is undefined, skip the filterSessionStoreByAgent
  step so all agents' sessions are returned
- Updated test to verify that sessions from all configured agents are
  returned when no agentId is specified
@Jefsky Jefsky force-pushed the fix/usage-agent-filter branch from 87f63e5 to 6e6c48e Compare May 28, 2026 02:37
The test mocked discoverAllSessions with mockResolvedValueOnce for main
agent only. With the all-agent discovery change, opus agent sessions are
also returned. Updated test to mock both agent calls and assert all 4
sessions are returned.
@BingqingLyu

This comment was marked as spam.

@Jefsky
Copy link
Copy Markdown
Contributor Author

Jefsky commented May 29, 2026

Superseded by #87823 — preserves the shipped gateway scoping contract by adding agentId: "all" as an explicit opt-in, instead of changing the default behavior. Addresses ClawSweeper's security/compatibility concerns.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 29, 2026

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

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