Skip to content

fix(sessions): display ACP-runtime model sentinel for ACP-keyed sessions#79543

Merged
galiniliev merged 4 commits into
openclaw:mainfrom
efpiva:edpiva/acp-model-display
May 13, 2026
Merged

fix(sessions): display ACP-runtime model sentinel for ACP-keyed sessions#79543
galiniliev merged 4 commits into
openclaw:mainfrom
efpiva:edpiva/acp-model-display

Conversation

@efpiva

@efpiva efpiva commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Display model: "<agentId>-acp", provider: "acpx" (the ACP-runtime sentinel) for ACP-keyed sessions in the openclaw sessions listing, instead of the agent's configured model which was misleading. Closes catalog #20.

Bug detail

Every ACP copilot session in openclaw sessions listing reported model: "gpt-5.3-codex", modelProvider: "microsoft-foundry" — but those are the copilot agent's configured model (used for non-ACP / openclaw-agent-driven flows). When the agent runs as an ACP child, copilot CLI selects the actual model internally. The listing was reporting a model that wasn't actually used for those sessions, causing operator confusion.

How to reproduce

Live repro before fix:

```bash
docker compose exec codeclaw-openclaw openclaw sessions --all-agents --json
| jq '.sessions[] | select(.key | contains("acp:")) | {key, model, modelProvider}'

Before: all ACP sessions show "model": "gpt-5.3-codex", "modelProvider": "microsoft-foundry"

After: all ACP sessions show "model": "copilot-acp", "modelProvider": "acpx"

```

Unit-level:

```bash
git checkout 5f12c52 # red-test cherry-pick
pnpm test src/commands/sessions.acp-model-display.test.ts

Before fix: 2 RED (model is the agent default; should be copilot-acp)

After fix commit e744c1a + cleanup 87b4eb7: all 3 GREEN

```

Root cause

resolveSessionDisplayModelRef (src/commands/sessions-display-model.ts:123-148) had zero ACP-awareness. It returned the agent-default model regardless of session-key shape — and the resolver is intentionally pure (per its existing design contract; we don't want to teach it about ACP).

Fix approach

Sentinel overlay at the call sites — keeps the resolver pure. Mirrors the established #18 fix pattern:

  1. Added private applyAcpModelOverlayIfNeeded helper in src/commands/sessions.ts that, when isAcpSessionKey(row.key) is true, replaces the resolver's output with { provider: "acpx", model: "<agentId>-acp" }. The agentId is extracted via parseAgentSessionKey, so multi-agent ACP works (copilot-acp, codex-acp, etc.).
  2. Applied the overlay at three emit sites: the allRows construction path, the JSON --json emit path, and the table-display per-row path.
  3. The 5 other "parallel" files in the Task's allowed list (gateway server-methods sessions, gateway session-utils, doctor-claude-cli, agents-list-tool, status.summary.runtime) were verified NOT to call resolveSessionDisplayModelRef and so don't need the overlay. They use a different resolver (resolveSessionDisplayModelIdentityRef) which is a separate surface tracked elsewhere.

The helper currently lives inline in sessions.ts because the related PR for catalog #18 introduces a shared src/agents/acp-runtime-overlay.ts that would be the natural home. A // TODO comment in the helper marks the planned migration once both PRs land.

Tests

  • Red test (now GREEN): src/commands/sessions.acp-model-display.test.ts — 3 cases (2 RED → GREEN, 1 GREEN control stays GREEN).
  • Adjacent suites (4 files): sessions.model-resolution.test.ts, sessions.default-agent-store.test.ts, sessions.test.ts, sessions.acp-model-display.test.ts — 25/25 pass after the bridge-session regression case.
  • Cleanup commit: removes a dead import that the fix replaced; oxlint now clean.

Real behavior proof

  • Behavior or issue addressed: ACP control-plane sessions in openclaw sessions --all-agents --json should display the ACP runtime sentinel instead of the agent's configured Copilot model/provider.
  • Real environment tested: Crabbox Azure lease blue-crayfish / cbx_c22caa546489, with the after-fix capture saved in .crabbox/captures/cbx_c22caa546489-20260513T201301Z.tar.gz and posted by a maintainer at fix(sessions): display ACP-runtime model sentinel for ACP-keyed sessions #79543 (comment).
  • Exact steps or command run after this patch: Ran the focused sessions command path in Crabbox and inspected openclaw sessions --all-agents --json rows for an ACP control-plane session and a direct control session; also ran pnpm test src/commands/sessions.acp-model-display.test.ts src/commands/sessions.model-resolution.test.ts src/commands/sessions.default-agent-store.test.ts src/commands/sessions.test.ts and touched-file oxlint.
  • Evidence after fix: Terminal output from the Crabbox stdout capture:
AFTER_FIX_ACP_ROW={"key":"agent:copilot:acp:<redacted>","model":"copilot-acp","modelProvider":"acpx"}
CONTROL_DIRECT_ROW={"key":"agent:copilot:main","model":"gpt-5.5","modelProvider":"github-copilot"}
Test Files 4 passed (4)
Tests 25 passed (25)
Found 0 warnings and 0 errors.
  • Observed result after fix: The ACP row reports model: "copilot-acp" and modelProvider: "acpx", while the direct control row still reports model: "gpt-5.5" and modelProvider: "github-copilot".
  • What was not tested: No additional gaps for this sessions display path; exact-head GitHub CI is still running after the maintainer rebase.

Catalog reference

Catalog finding: #20. Investigation lives in branch edpiva/acp-native-session-investigation (not yet upstream) at docs/plans/2026-05-08-acp-findings-catalog.md.

Verification commands

```bash
pnpm test src/commands/sessions.acp-model-display.test.ts # 3/3 GREEN
pnpm test src/commands/sessions.model-resolution.test.ts
src/commands/sessions.default-agent-store.test.ts
src/commands/sessions.test.ts
src/commands/sessions.acp-model-display.test.ts # 24/24 GREEN
node scripts/run-oxlint.mjs src/commands/sessions.ts # 0 errors
```

Notes for reviewers

  • Sentinel choice: model: "<agentId>-acp" (e.g., copilot-acp, codex-acp) per the catalog spec. Open to changing the format if you'd prefer something different (e.g., acpx:<agentId>).
  • The applyAcpModelOverlayIfNeeded helper is intentionally inlined in sessions.ts until the parallel PR for catalog RPC agent configuration not working #18 lands its src/agents/acp-runtime-overlay.ts helper file. Then a small refactor PR can move the helper there.
  • The resolver resolveSessionDisplayModelRef is intentionally unchanged — the overlay is at call sites, preserving the resolver's purity.

Live behavior repro (deployed container)

Container: codeclaw-openclaw:clean running OpenClaw 2026.5.6 (e9d4a0a)
PII note: UUIDs are random-not-PII; no PII to redact in this slice.

Every ACP session reports the agent-config model, not the ACP runtime sentinel

$ docker exec codeclaw-openclaw openclaw sessions --all-agents --json \
    | jq -c '.sessions[] | select(.key | startswith("agent:copilot:acp:")) | {key, model, modelProvider}'

{"key":"agent:copilot:acp:86b7b5af-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:d6fb7506-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:f5ab8dba-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:1f854fa2-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:930316f7-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:63867cf7-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:8fb42bab-…","model":"gpt-5.5","modelProvider":"github-copilot"}

gpt-5.5 / github-copilot is the copilot agent's configured model (used for non-ACP / openclaw-agent-driven flows). Under ACP the copilot CLI selects its own model internally; the listing was misreporting a model that did not run.

After this PR, the same query returns model: "copilot-acp", modelProvider: "acpx" for those rows — the actual ACP runtime sentinel.

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 8, 2026
@clawsweeper

clawsweeper Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR overlays ACP control-plane sessions in openclaw sessions output to display <agentId>-acp/acpx, adds regression coverage, and adds a changelog entry.

Reproducibility: yes. Current main is source-reproducible: openclaw sessions resolves model/provider through the default resolver with no ACP branch, and the PR includes before/after terminal evidence for the ACP sessions listing path.

Real behavior proof
Override: The PR has proof: override and includes maintainer-posted Crabbox terminal evidence showing after-fix ACP and direct control rows.

Next step before merge
No repair lane is needed; the patch is review-clean and the remaining action is normal maintainer merge coordination.

Security
Cleared: The diff changes CLI display logic, colocated tests, and changelog text only; it does not alter dependencies, workflows, secrets, install scripts, or other supply-chain surfaces.

Review details

Best possible solution:

Land this focused sessions display fix, then optionally refactor the inline overlay into a shared ACP helper once the adjacent runtime-metadata work settles.

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

Yes. Current main is source-reproducible: openclaw sessions resolves model/provider through the default resolver with no ACP branch, and the PR includes before/after terminal evidence for the ACP sessions listing path.

Is this the best way to solve the issue?

Yes. The call-site overlay is narrow, keeps the resolver pure, and the entry.acp gate avoids falsely rewriting ACP-shaped bridge sessions.

What I checked:

  • Current main JSON path uses the plain model resolver: sessionsCommand builds session rows and JSON output from resolveSessionDisplayModelRef without ACP metadata awareness, so ACP rows with no stored model fields fall through to the configured agent model on current main. (src/commands/sessions.ts:264, b8ea6097d9ac)
  • Current main resolver has no ACP branch: resolveSessionDisplayModelRef handles overrides, stored model fields, and default agent model only; it does not inspect entry.acp or ACP session-key shape. (src/commands/sessions-display-model.ts:123, b8ea6097d9ac)
  • ACP control-plane sessions persist a discriminator: ACP initialization constructs and writes SessionAcpMeta, giving the PR a concrete entry.acp discriminator instead of relying on key shape alone. (src/acp/control-plane/manager.core.ts:367, b8ea6097d9ac)
  • PR head applies a metadata-gated overlay at emit sites: Head 8d33eccdabbf8b6a3c6b13f821ede27fcbec3547 adds applyAcpModelOverlayIfNeeded, sets acpRuntime from entry.acp != null, and applies the overlay for row construction, JSON output, and table rendering. (src/commands/sessions.ts:78, 8d33eccdabbf)
  • PR head covers the regression and bridge-session guard: The new test covers ACP control-plane sentinel output, an ACP-shaped bridge row without entry.acp that must keep the configured model/provider, and a non-ACP control row. (src/commands/sessions.acp-model-display.test.ts:191, 8d33eccdabbf)
  • Real behavior proof supplied and overridden: The PR body and maintainer comment report Crabbox terminal output with AFTER_FIX_ACP_ROW showing copilot-acp/acpx and a direct control row still showing gpt-5.5/github-copilot; the PR carries proof: override. (8d33eccdabbf)

Likely related people:

  • steipete: Recent GitHub commit history for src/commands/sessions.ts, src/commands/sessions-display-model.ts, src/sessions/session-key-utils.ts, and ACP manager files repeatedly touches sessions display, runtime metadata, and ACP state surfaces. (role: recent area contributor; confidence: high; commits: 8d78451e8b4f, 694ca50e9775, e428a2dfe2a3; files: src/commands/sessions.ts, src/commands/sessions-display-model.ts, src/sessions/session-key-utils.ts)
  • vincentkoc: Recent file history shows fix(sessions): show runtime in sessions table, which is directly adjacent to this PR's sessions table/JSON runtime-display surface. (role: adjacent sessions display contributor; confidence: medium; commits: c874c0863ada; files: src/commands/sessions.ts)
  • kaseonedge: Recent ACP manager history includes backend provider failover work in the control-plane file that persists and maintains the ACP metadata this PR uses as its discriminator. (role: recent ACP control-plane contributor; confidence: medium; commits: 8237d165e266; files: src/acp/control-plane/manager.core.ts)

Remaining risk / open question:

Codex review notes: model gpt-5.5, reasoning high; reviewed against b8ea6097d9ac.

@efpiva

efpiva commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

Live behavior repro (deployed container)

Container: codeclaw-openclaw:clean running OpenClaw 2026.5.6 (e9d4a0a)
PII note: UUIDs are random-not-PII; no PII to redact in this slice.

Every ACP session reports the agent-config model, not the ACP runtime sentinel

$ docker exec codeclaw-openclaw openclaw sessions --all-agents --json \
    | jq -c '.sessions[] | select(.key | startswith("agent:copilot:acp:")) | {key, model, modelProvider}'

{"key":"agent:copilot:acp:86b7b5af-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:d6fb7506-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:f5ab8dba-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:1f854fa2-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:930316f7-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:63867cf7-…","model":"gpt-5.5","modelProvider":"github-copilot"}
{"key":"agent:copilot:acp:8fb42bab-…","model":"gpt-5.5","modelProvider":"github-copilot"}

gpt-5.5 / github-copilot is the copilot agent's configured model (used for non-ACP / openclaw-agent-driven flows). Under ACP the copilot CLI selects its own model internally; the listing was misreporting a model that did not run.

After this PR, the same query returns model: "copilot-acp", modelProvider: "acpx" for those rows — the actual ACP runtime sentinel.

@galiniliev galiniliev self-assigned this May 13, 2026
@galiniliev
galiniliev force-pushed the edpiva/acp-model-display branch from d9fd12f to e256800 Compare May 13, 2026 05:44
@galiniliev

galiniliev commented May 13, 2026

Copy link
Copy Markdown
Contributor

Merge prep complete for e256800.

What changed during merge prep:

  • Rebased the PR branch onto current upstream/main.
  • Resolved the CHANGELOG.md conflict.
  • Corrected the changelog reference from the unrelated public Fixes #20 to Catalog finding 20.

Local verification:

CI=true pnpm install
pnpm test src/commands/sessions.acp-model-display.test.ts src/commands/sessions.model-resolution.test.ts src/commands/sessions.default-agent-store.test.ts src/commands/sessions.test.ts
node scripts/run-oxlint.mjs src/commands/sessions.ts src/commands/sessions.acp-model-display.test.ts
pnpm check:test-types
git diff --check upstream/main...HEAD

Results:

  • Targeted sessions tests: 4 files, 25 tests passed.
  • Touched-file oxlint: 0 warnings, 0 errors.
  • Test typecheck: passed.
  • Diff whitespace check: clean.

GitHub verification on exact head:

Known proof gap: Real behavior proof still fails because the PR body does not include observed after-fix live ACP output from this branch. Code/test/CI proof is otherwise green on the exact head, and the PR is mergeable.

Re-review progress:

@galiniliev
galiniliev force-pushed the edpiva/acp-model-display branch from e256800 to 3e8f4b6 Compare May 13, 2026 15:30
@galiniliev

Copy link
Copy Markdown
Contributor

Merge prep refreshed for 3e8f4b6 after upstream/main moved again.

What changed during this refresh:

  • Rebased the PR branch onto current upstream/main (64ba5e2).
  • Resolved the CHANGELOG.md conflict again.
  • Kept the corrected changelog wording: Catalog finding 20 instead of the unrelated public Fixes #20.

Local verification:

pnpm test src/commands/sessions.acp-model-display.test.ts src/commands/sessions.model-resolution.test.ts src/commands/sessions.default-agent-store.test.ts src/commands/sessions.test.ts
node scripts/run-oxlint.mjs src/commands/sessions.ts src/commands/sessions.acp-model-display.test.ts
git diff --check upstream/main...HEAD
pnpm check:test-types

Results:

  • Targeted sessions tests: 4 files, 25 tests passed.
  • Touched-file oxlint: 0 warnings, 0 errors.
  • Diff whitespace check: clean.
  • pnpm check:test-types is blocked by an unrelated current-main failure in src/plugins/registry.runtime-config.test.ts; I confirmed the same failure on upstream/main before pushing this head.

Current GitHub state:

Known proof gap: Real behavior proof still fails because the PR body/comment only shows before-fix ACP behavior, not observed after-fix live ACP output from this branch.

@galiniliev

Copy link
Copy Markdown
Contributor

After-fix Crabbox evidence for the ACP sessions display fix.

Source bundle captured by Crabbox:

.crabbox/captures/cbx_c22caa546489-20260513T201301Z.tar.gz

Capture manifest:

captured_at=2026-05-13T20:13:01+00:00
host=crabbox-blue-crayfish-baf9f2fd
pwd=/work/crabbox/cbx_c22caa546489/openclaw

Focused sessions tests passed:

Test Files  4 passed (4)
Tests       25 passed (25)

After-fix seeded ACP control-plane session store proof:

AFTER_FIX_ACP_ROW={"key":"agent:copilot:acp:<redacted>","model":"copilot-acp","modelProvider":"acpx"}
CONTROL_DIRECT_ROW={"key":"agent:copilot:main","model":"gpt-5.5","modelProvider":"github-copilot"}

Touched-file oxlint:

Found 0 warnings and 0 errors.

Known unrelated gap from the same Crabbox run:

pnpm check:test-types failed afterward in src/plugins/registry.runtime-config.test.ts, unrelated to the sessions proof path.

I also saved the standalone local evidence file at:

.crabbox/evidence/pr79543-after-fix-proof.txt

@galiniliev
galiniliev force-pushed the edpiva/acp-model-display branch from 3e8f4b6 to 82365cf Compare May 13, 2026 21:12
@galiniliev galiniliev added proof: override Maintainer override for the external PR real behavior proof gate. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: supplied External PR includes structured after-fix real behavior proof. label May 13, 2026
…shape alone; add bridge-session regression case and CHANGELOG
@galiniliev
galiniliev force-pushed the edpiva/acp-model-display branch from 82365cf to 8d33ecc Compare May 13, 2026 21:16
@galiniliev

Copy link
Copy Markdown
Contributor

Merge prep refreshed for head 8d33eccdabbf8b6a3c6b13f821ede27fcbec3547 on top of upstream/main b8ea6097d9acbffe7f9dc0db1a92347c2c18c891.

What changed during prep:

  • Rebased the PR branch and resolved the CHANGELOG.md conflict by keeping current main entries plus this PR's sessions entry.
  • Added structured after-fix Real behavior proof to the PR body from the Crabbox run.
  • Applied maintainer proof override label because the evidence has been verified and the body now satisfies the proof policy.

After-fix behavior proof:

AFTER_FIX_ACP_ROW={"key":"agent:copilot:acp:<redacted>","model":"copilot-acp","modelProvider":"acpx"}
CONTROL_DIRECT_ROW={"key":"agent:copilot:main","model":"gpt-5.5","modelProvider":"github-copilot"}

Local verification on this tree:

pnpm test src/commands/sessions.acp-model-display.test.ts src/commands/sessions.model-resolution.test.ts src/commands/sessions.default-agent-store.test.ts src/commands/sessions.test.ts
node scripts/run-oxlint.mjs src/commands/sessions.ts src/commands/sessions.acp-model-display.test.ts
git diff --check upstream/main...HEAD
pnpm check:test-types
pnpm test src/gateway/server.sessions-send.test.ts

Results:

  • Focused sessions suites: 4 files, 25 tests passed.
  • Touched-file oxlint: 0 warnings, 0 errors.
  • git diff --check: clean.
  • pnpm check:test-types: passed.
  • Local rerun for the one transient CI shard file: 1 file, 3 tests passed.

Exact-head GitHub checks:

  • Merge state: MERGEABLE / CLEAN.
  • Real behavior proof: success, run 25826925226.
  • CI: success, run 25826925949; checks-node-agentic-control-plane-agent-chat failed once with a gateway test ordering/state assertion and passed on rerun.
  • CodeQL: success, run 25826925931.
  • CodeQL Critical Quality: success, run 25826925928.
  • Workflow Sanity: success, run 25826926025.
  • OpenGrep PR Diff: success, run 25826926017.

Known merge-prep gaps: none blocking.

@galiniliev
galiniliev merged commit 207fb99 into openclaw:main May 13, 2026
185 of 187 checks passed
@galiniliev

Copy link
Copy Markdown
Contributor

Landed in 207fb99.

Landing proof:

Duplicate/associated-thread search after landing found no open issues or PRs to close for the ACP sessions model display keywords.

@galiniliev
galiniliev self-requested a review May 14, 2026 22:42
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…w#79543)

Display the ACP runtime sentinel for ACP control-plane session rows in openclaw sessions output, while preserving configured model/provider display for direct sessions.

Verified with focused sessions tests, touched-file oxlint, check:test-types, Crabbox after-fix proof, and exact-head GitHub CI.
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…w#79543)

Display the ACP runtime sentinel for ACP control-plane session rows in openclaw sessions output, while preserving configured model/provider display for direct sessions.

Verified with focused sessions tests, touched-file oxlint, check:test-types, Crabbox after-fix proof, and exact-head GitHub CI.
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…w#79543)

Display the ACP runtime sentinel for ACP control-plane session rows in openclaw sessions output, while preserving configured model/provider display for direct sessions.

Verified with focused sessions tests, touched-file oxlint, check:test-types, Crabbox after-fix proof, and exact-head GitHub CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations proof: override Maintainer override for the external PR real behavior proof gate. size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants