feat: carry gateway client capabilities through the CLI loopback backend#102835
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 9:46 AM ET / 13:46 UTC. Summary PR surface: Source +24, Tests +89, Docs 0. Total +113 across 16 files. Reproducibility: yes. from source for the linked feature gap: current main preserves client caps on queued runs and filters tools by caps, but the CLI loopback request/scope/prepare path omits caps. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Merge after maintainer accepts the CLI loopback capability contract and the author adds redacted live Control UI or CLI-backed proof; keep grant-authenticated MCP and direct HTTP callers capless. Do we have a high-confidence way to reproduce the issue? Yes from source for the linked feature gap: current main preserves client caps on queued runs and filters tools by caps, but the CLI loopback request/scope/prepare path omits caps. Is this the best way to solve the issue? Yes, conditionally: threading caps through the existing loopback env/header/request/cache seam is the clean owner-boundary fix, but maintainer signoff and live proof are still required. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against f6b990124353. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +24, Tests +89, Docs 0. Total +113 across 16 files. View PR surface stats
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
|
CLI-backed model runs now transport the originating client's declared capabilities along the existing per-field loopback contract: RunCliAgentParams gains clientCaps, prepare emits OPENCLAW_MCP_CLIENT_CAPS, the loopback header template forwards x-openclaw-client-caps, the request context parses and normalizes it (grant-authenticated callers keep ignoring spoofable headers), and the loopback tool cache keys on a stable caps serialization so capless and capped requests never share tool lists. Capability-gated tools such as show_widget now work on CLI backends; the CLI session binding hash includes caps, consistent with messageProvider. Cron and command-attempt runs stay capless (fail closed). Fixes #102577
3b993cb to
1bdeb15
Compare
|
Merged via squash.
|
…end (openclaw#102835) * test: shorten loopback token fixtures below secret-scanner thresholds * feat: carry gateway client capabilities through the CLI loopback backend CLI-backed model runs now transport the originating client's declared capabilities along the existing per-field loopback contract: RunCliAgentParams gains clientCaps, prepare emits OPENCLAW_MCP_CLIENT_CAPS, the loopback header template forwards x-openclaw-client-caps, the request context parses and normalizes it (grant-authenticated callers keep ignoring spoofable headers), and the loopback tool cache keys on a stable caps serialization so capless and capped requests never share tool lists. Capability-gated tools such as show_widget now work on CLI backends; the CLI session binding hash includes caps, consistent with messageProvider. Cron and command-attempt runs stay capless (fail closed). Fixes openclaw#102577
Closes #102577
What Problem This Solves
Capability-gated agent tools (such as
show_widget, gated on theinline-widgetsgateway client capability) were unavailable on CLI-backed model backends: the CLI/bundle-MCP loopback never transported the originating client's declared capabilities, so tool assembly ran capless and dropped gated tools even for Control UI conversations whose client had advertised support. This was the documented fail-closed limitation left open by the inline-widgets work.Why This Change Was Made
Threads
clientCapsalong the loopback's existing per-field string transport, mirroring howmessageProvidertravels:RunCliAgentParamsgains the field (forwarded from the queued run at both dispatch sites),prepareemitsOPENCLAW_MCP_CLIENT_CAPS, the loopback header template addsx-openclaw-client-caps, the request context parses it (trim, dedupe, empty → undefined) in the gateway-launched loopback branch only — grant-authenticated callers keep nulling spoofable context headers — and the loopback tool cache includes a stable sorted serialization of the caps in its key so capless and capped requests never share cached tool lists.resolveGatewayScopedToolsalready acceptedclientCaps, so the resolver end needed no changes. The CLI session binding hash includes caps, consistent withmessageProvider(surface-dependent tool lists already participate in reuse decisions). Cron and command-attempt runs have no gateway client and stay capless (fail closed). ACP dispatch is out of scope — it cannot enforce OpenClaw tool policy at all — and direct HTTP tools-invoke callers remain fail closed because they declare no capabilities.User Impact
Control UI conversations running on CLI-backed model backends (Claude CLI, Gemini CLI, and other bundle-MCP harnesses) can now use capability-gated tools like
show_widget, matching the embedded and Codex app-server backends. No configuration changes; no behavior change for channels, cron, or grant-authenticated MCP callers.Evidence
src/gateway/mcp-http.test.ts(280 tests): header reaches the resolver as a parsed array; whitespace/duplicate/empty header normalization; grant-authenticated branch ignores the header; capless and capped requests resolve separately (no cache cross-serving).src/agents/cli-runner/prepare.test.ts(64) andbundle-mcp.gemini.test.ts: env var emitted fromRunCliAgentParams.clientCaps; header template substitutes it into the generated MCP server config.src/auto-reply/reply/followup-runner.test.ts(130) andagent-runner-execution.test.ts(242): both CLI dispatch sites forwardrun.clientCaps.src/gateway/tool-resolution.exclude.test.ts: caps passthrough at the resolver seam.git diff --checkclean; structured autoreview clean (no actionable findings).docs/tools/show-widget.mdis updated to reflect the covered backends.