Skip to content

fix: specifying the model on ACP - #215

Merged
pedronauck merged 7 commits into
compozy:mainfrom
renanfferreira:feature/fix-model-acp
Jun 30, 2026
Merged

pedronauck merged 7 commits into
compozy:mainfrom
renanfferreira:feature/fix-model-acp

Conversation

@renanfferreira

@renanfferreira renanfferreira commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes
    • Ensured ACP sessions created and resumed consistently apply the selected model.
    • Added model trimming/validation and now set the model before the first prompt turn for both new and resumed runs.
    • Improved resilience when switching models fails, with best-effort session cleanup to reduce retry/cancellation/timeout issues.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The ACP client now sets session models during create and resume when provided, reuses the computed model name in ACP session requests, and updates test doubles and executor assertions for the new call path.

Changes

ACP session model configuration

Layer / File(s) Summary
Client contract and setter implementation
internal/core/agent/client.go
Client declares SetSessionModel; clientImpl trims inputs, CreateSession and ResumeSession call it before prompting, and cleanup helpers handle failures.
Session request preparation
internal/core/run/internal/acpshared/command_io.go
createACPSession computes modelName once and reuses it for fresh and resumed ACP session requests.
Test doubles and assertions
internal/cli/root_command_execution_test.go, internal/core/kernel/recovery_prepared_run_test.go, internal/core/run/exec/exec_integration_test.go, internal/core/run/exec/run_agent_engine_integration_test.go, internal/core/run/internal/acpshared/command_io_test.go, internal/core/run/internal/acpshared/session_exec_test.go, internal/core/run/recovery/agentic_test.go
ACP test fakes add no-op SetSessionModel methods so the updated interface is satisfied in tests.
Executor state and expectations
internal/core/run/executor/execution_acp_test.go
fakeACPClient records SetSessionModel calls and executor tests assert the new call counts and model IDs across success, retry, timeout, cancellation, and failure paths.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • compozy/compozy#78: Also modifies internal/core/agent/client.go session setup flow.
  • compozy/compozy#181: Also touches SetSessionModel and session model normalization in the ACP session flow.
  • compozy/compozy#198: Modifies session model handling in internal/core/agent/client.go, overlapping the same ACP session configuration path.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: setting/specifying the model on ACP.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR updates ACP session setup so model selection is passed through more consistently. The main changes are:

  • Adds SetSessionModel to the ACP client interface.
  • Pins the model after creating a fresh ACP session.
  • Refactors resume request preparation.
  • Updates ACP test fakes and session setup tests.

Confidence Score: 4/5

This should be fixed before merging.

  • A failed model-pin call after session creation can leave remote ACP work behind.
  • Resumed sessions can still run with the saved session model instead of the selected model.
  • The interface expansion appears covered by the in-repo implementations.

internal/core/run/internal/acpshared/command_io.go

Important Files Changed

Filename Overview
internal/core/agent/client.go Adds SetSessionModel and wires it to ACP session/set_config_option.
internal/core/run/internal/acpshared/command_io.go Adds fresh-session model pinning, but the failed pin path and resume path can still behave incorrectly.
internal/core/run/executor/execution_acp_test.go Updates executor tests and fakes to track fresh-session model pinning.
internal/core/run/internal/acpshared/command_io_test.go Updates ACP shared test fakes for the expanded client interface.

Comments Outside Diff (1)

  1. internal/core/run/internal/acpshared/command_io.go, line 395-406 (link)

    P1 Resume Skips Model This resume branch still only passes modelName inside ResumeSessionRequest. It does not call SetSessionModel before the prompt turn, and the resume implementation loads the existing session without a model field. When a resumed job selects a different model from the saved session, the prompt can still run on the old ACP session model.

    Context Used: CLAUDE.md (source)

Reviews (7): Last reviewed commit: "fix: fixing tests" | Re-trigger Greptile

Comment thread internal/core/run/internal/acpshared/command_io.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/core/run/internal/acpshared/command_io.go (1)

395-406: 🎯 Functional Correctness | 🟡 Minor

Resume should also apply the active model. The create branch calls SetSessionModel, but the resume branch only passes Model in ResumeSessionRequest. If that field doesn’t update the loaded session’s active model, resumed runs will keep the prior/default model. Mirror the create flow here. internal/core/run/internal/acpshared/command_io.go:395-406

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/core/run/internal/acpshared/command_io.go` around lines 395 - 406,
The resume path in ResumeSession currently only passes Model through
agent.ResumeSessionRequest, so the loaded session may keep its previous active
model. Update the resume flow in command_io.go to mirror the create path by
explicitly applying the active model to the session using the same model-setting
logic used for new sessions (for example, the SetSessionModel behavior around
the create branch), ensuring resumed runs use modelName instead of the
prior/default model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/core/run/exec/exec_integration_test.go`:
- Around line 702-704: The fake capturingExecACPClient currently implements
SetSessionModel but discards the session/model arguments and always returns
success, so the tests cannot verify the ACP model-setting flow. Update
SetSessionModel to record the passed context/session/model values on
capturingExecACPClient, and add a way to inject a return error so exec
integration tests can assert both the expected values and failure propagation.
Use the existing capturingExecACPClient helper and the new SetSessionModel call
path in the exec integration test suite to validate the behavior outcome.

In `@internal/core/run/executor/execution_acp_test.go`:
- Around line 1539-1541: `fakeACPClient.SetSessionModel` is currently a silent
no-op, unlike the other tracked ACP session methods. Update `fakeACPClient` to
record invocations and capture the passed arguments for `SetSessionModel`,
following the pattern used by the other fake ACP call counters in this test
file. Then adjust the relevant assertions in the `execution_acp_test.go` suite
so tests can verify the model-setting path was exercised correctly and validate
the observed behavior, not just that the call exists.

In `@internal/core/run/internal/acpshared/command_io.go`:
- Around line 386-393: The session model is being applied too late in the
create/resume flow, so the first prompt can start with the wrong model and
resumed sessions ignore the requested model. Update the session setup in the
create/resume path around client.CreateSession and client.SetSessionModel so the
model is set before runPrompt begins, and make sure the resume path applies the
provided Model value as part of session initialization rather than after the
session is already running.

---

Outside diff comments:
In `@internal/core/run/internal/acpshared/command_io.go`:
- Around line 395-406: The resume path in ResumeSession currently only passes
Model through agent.ResumeSessionRequest, so the loaded session may keep its
previous active model. Update the resume flow in command_io.go to mirror the
create path by explicitly applying the active model to the session using the
same model-setting logic used for new sessions (for example, the SetSessionModel
behavior around the create branch), ensuring resumed runs use modelName instead
of the prior/default model.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6693fe1c-1da2-4e83-8fd2-fedbf9316c2f

📥 Commits

Reviewing files that changed from the base of the PR and between e43aa56 and bc113bb.

📒 Files selected for processing (10)
  • internal/cli/root_command_execution_test.go
  • internal/core/agent/client.go
  • internal/core/kernel/recovery_prepared_run_test.go
  • internal/core/run/exec/exec_integration_test.go
  • internal/core/run/exec/run_agent_engine_integration_test.go
  • internal/core/run/executor/execution_acp_test.go
  • internal/core/run/internal/acpshared/command_io.go
  • internal/core/run/internal/acpshared/command_io_test.go
  • internal/core/run/internal/acpshared/session_exec_test.go
  • internal/core/run/recovery/agentic_test.go

Comment thread internal/core/run/exec/exec_integration_test.go
Comment thread internal/core/run/executor/execution_acp_test.go Outdated
Comment thread internal/core/run/internal/acpshared/command_io.go
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 25, 2026
Comment thread internal/core/agent/client.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/core/agent/client.go`:
- Around line 405-408: The session lifecycle hook is firing too early in the
session creation flow, before SetSessionModel can fail and trigger
c.removeSession(session.id). Move the agent.post_session_create hook in the
session creation path of client.go so it runs only after model setup succeeds,
and keep the hook placement aligned with the existing session creation logic
around SetSessionModel and session.id.
- Around line 405-406: The model-setting RPC in the session setup path is using
the wrong context; update the `SetSessionModel` call inside the `AgentClient`
session initialization flow to use `setupCtx` rather than `ctx`, and apply the
same fix in the other matching call site around the later session setup branch.
Use the `SetSessionModel` invocation in the `NewSession`/`LoadSession` handling
path to locate the change and keep the RPC scoped to setup cancellation and
timeout.

In `@internal/core/run/executor/execution_acp_test.go`:
- Around line 214-218: The assertion around secondClient.lastSetModelID in
execution_acp_test.go is performed while setModelMu is still locked, so a
failure can leave the mutex locked and affect later tests. In the test that uses
secondClient and setModelMu, read the field into a local variable while holding
the lock, release the lock immediately, then perform the t.Fatalf check on the
copied value outside the critical section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 05fbbc6d-2a12-4060-aa51-21db1dc129f9

📥 Commits

Reviewing files that changed from the base of the PR and between bc113bb and 19ec6a8.

📒 Files selected for processing (3)
  • internal/core/agent/client.go
  • internal/core/run/executor/execution_acp_test.go
  • internal/core/run/internal/acpshared/command_io.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/core/run/internal/acpshared/command_io.go

Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/run/executor/execution_acp_test.go
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 26, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 27, 2026
Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/agent/client.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/core/agent/client.go (1)

533-536: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the loaded session when model setup fails.

Line 513 stores the resumed session before this call, but this error path returns without c.removeSession(session.id), leaving a locally tracked session after setup failed.

Proposed fix
 if modelID := strings.TrimSpace(req.Model); modelID != "" {
 	if err := c.SetSessionModel(setupCtx, session.id, modelID); err != nil {
+		c.removeSession(session.id)
 		return nil, fmt.Errorf("set session model before prompt: %w", err)
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/core/agent/client.go` around lines 533 - 536, The session setup path
in client.go leaves a resumed session tracked locally when SetSessionModel
fails. In the model setup block in c.handlePrompt (the code that calls
c.SetSessionModel), remove the stored session with c.removeSession(session.id)
before returning the error so the failed resume does not stay in the client’s
session map.
🧹 Nitpick comments (1)
internal/core/agent/client.go (1)

878-880: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid context.Background() in these helpers. detachedContext and cleanupContext should require a non-nil caller context, or use a non-production placeholder at the call site, so this stays aligned with the context policy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/core/agent/client.go` around lines 878 - 880, The helpers that
currently fall back to context.Background() should not create a production root
context; update detachedContext and cleanupContext to require a non-nil
caller-provided context instead, or move any placeholder context creation to the
call site. Use the existing helper names in internal/core/agent/client.go to
locate the fallback and remove the nil-guard so these helpers stay aligned with
the context policy.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/core/agent/client.go`:
- Around line 533-536: The session setup path in client.go leaves a resumed
session tracked locally when SetSessionModel fails. In the model setup block in
c.handlePrompt (the code that calls c.SetSessionModel), remove the stored
session with c.removeSession(session.id) before returning the error so the
failed resume does not stay in the client’s session map.

---

Nitpick comments:
In `@internal/core/agent/client.go`:
- Around line 878-880: The helpers that currently fall back to
context.Background() should not create a production root context; update
detachedContext and cleanupContext to require a non-nil caller-provided context
instead, or move any placeholder context creation to the call site. Use the
existing helper names in internal/core/agent/client.go to locate the fallback
and remove the nil-guard so these helpers stay aligned with the context policy.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a8d9469-0262-4103-a742-9772c962c2cc

📥 Commits

Reviewing files that changed from the base of the PR and between bda4ad5 and 07c8b20.

📒 Files selected for processing (1)
  • internal/core/agent/client.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 27, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 27, 2026
Comment thread internal/core/agent/client.go Outdated
Comment thread internal/core/run/internal/acpshared/command_io.go
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 27, 2026
Comment thread internal/core/run/internal/acpshared/command_io.go
@pedronauck
pedronauck merged commit 64eae7b into compozy:main Jun 30, 2026
1 check passed
pedronauck added a commit that referenced this pull request Jul 3, 2026
Add human-written release notes for the next release covering the work
merged since v0.2.10:

- feat: dependency-aware parallel task execution (--parallel-tasks) (#212)
- feat: agentic recovery for failed runs (--recovery) (#212)
- feat: COMPOZY_HOME for isolated per-project daemons (#216)
- feat: repo-level default overrides in compozy setup (#90)
- fix: safer worktree management for parallel runs (#217, #223)
- fix: ACP runs consistently apply the selected model (#215)
- fix: run TUI elapsed timer restored across all terminal outcomes (#221)

Co-Authored-By: Claude Fable 5 <[email protected]>
@renanfferreira
renanfferreira deleted the feature/fix-model-acp branch September 11, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants