Summary
Owners can change an existing conversation's thinking level from the agent activity pane. Choosing High during a Low response queues the change until that response finishes; the next response uses High in the same ACP session, with its history intact. Saved agent defaults remain unchanged.
- Read choices and the applied value from the session's native
thought_level options. When several conversations are visible, require an explicit conversation choice.
- Send an encrypted owner control with the exact channel, session, session token, request ID, and effort. Queue at the response boundary, fence the owning worker before its next claim, and confirm
applied only from the native adapter response. Rejection and missing confirmation stay visible.
- Bound pending edits, replay receipts, cached configurations, and RPC duration. Stale or ambiguous sessions are not selected; transport failure retires the affected worker. Small configuration snapshots survive activity transcript eviction.
The design and manual/provider checks are documented in docs/conversation-effort.md.
Related issue
Focused follow-up to the live-effort control deferred in #4557. Coordinated with #5016 in this comment; this PR leaves saved-effort and portable-export work there. The unavailable saved-value presentation in #7374 also stays separate. Searches for open live-effort and switch_effort implementations found no duplicate before submission.
This starts directly from upstream 3c7f288c60d67df78577b237e27c3dfc8831aaa1. It contains no account-switching or other private-fork history. It leaves Codex catalog deduplication (#2926) separate and does not change model selection: the live picker requires a reported native option snapshot, so a legacy model-switch response with no native options cannot enable it.
Testing
just ci was run against 80c2529d0f48a8f230d126b693cf4b3b1d33273e. Formatting, lint/static checks, workspace Rust tests, all 6,460 desktop JS tests, desktop native checks/tests, and desktop/web builds passed. The overall command is not green: mobile finished 2,071 passed / 1 failed because voice_note_recording_test.dart:529 raised PathNotFoundException during temporary-directory teardown. An earlier full run hit the same cleanup error class in a different test at line 730.
There are no mobile changes. On exact upstream base 3c7f288c6, the complete voice-note test file passed all 20 tests (the first failing case also passed six isolated runs); the full base mobile suite failed in a separate animated-avatar readiness test. This does not establish reproduction of the exact voice-note failure on base. Keeping this PR draft pending a clean required CI result; no unrelated mobile fix is bundled here.
- ACP:
cargo test -p buzz-acp --lib — 929 passed, one opt-in provider test ignored by the regular suite. Coverage includes owner/freshness/signature gates, busy response handling, exact-session/sibling isolation, duplicate IDs including busy siblings and restarted sessions, replay/capacity/expiration, native config IDs and grouped options, rejection, and timeout retirement. The reused-session regression was also run with its production token guard removed in a disposable worktree; it failed with applied instead of stale_session, as expected.
- Browser:
BUZZ_E2E_PORT=4317 pnpm exec playwright test --project=smoke conversation-effort.spec.ts agent-control-regressions.spec.ts — 12 passed (five new workflow cases plus seven existing Stop/model-control regressions).
- Real Codex: the ignored two-turn provider test passed with
@agentclientprotocol/codex-acp 1.9.0. It waits until the first prompt is written and still running, queues Low → High, checks the adapter's returned value, and recalls a random word on the second turn in the same session. The startup default remains Low. The provider's own turn records were checked for the actual model and effort, separately from the mocked browser tests.
Manual check: open activity for an owned running agent with native thinking-level options, choose the conversation if prompted, then choose a different level during a response. The old level remains selected while queued; the reported level changes after confirmation. Send another message and confirm the conversation continues. Reopening saved agent settings should show the original default.
Before/after screenshots use the same synthetic colleague and conversation text. Before is captured from the exact upstream base; queued/applied are from this branch.
Summary
Owners can change an existing conversation's thinking level from the agent activity pane. Choosing High during a Low response queues the change until that response finishes; the next response uses High in the same ACP session, with its history intact. Saved agent defaults remain unchanged.
thought_leveloptions. When several conversations are visible, require an explicit conversation choice.appliedonly from the native adapter response. Rejection and missing confirmation stay visible.The design and manual/provider checks are documented in docs/conversation-effort.md.
Related issue
Focused follow-up to the live-effort control deferred in #4557. Coordinated with #5016 in this comment; this PR leaves saved-effort and portable-export work there. The unavailable saved-value presentation in #7374 also stays separate. Searches for open live-effort and
switch_effortimplementations found no duplicate before submission.This starts directly from upstream
3c7f288c60d67df78577b237e27c3dfc8831aaa1. It contains no account-switching or other private-fork history. It leaves Codex catalog deduplication (#2926) separate and does not change model selection: the live picker requires a reported native option snapshot, so a legacy model-switch response with no native options cannot enable it.Testing
just ciwas run against80c2529d0f48a8f230d126b693cf4b3b1d33273e. Formatting, lint/static checks, workspace Rust tests, all 6,460 desktop JS tests, desktop native checks/tests, and desktop/web builds passed. The overall command is not green: mobile finished 2,071 passed / 1 failed becausevoice_note_recording_test.dart:529raisedPathNotFoundExceptionduring temporary-directory teardown. An earlier full run hit the same cleanup error class in a different test at line 730.There are no mobile changes. On exact upstream base
3c7f288c6, the complete voice-note test file passed all 20 tests (the first failing case also passed six isolated runs); the full base mobile suite failed in a separate animated-avatar readiness test. This does not establish reproduction of the exact voice-note failure on base. Keeping this PR draft pending a clean required CI result; no unrelated mobile fix is bundled here.cargo test -p buzz-acp --lib— 929 passed, one opt-in provider test ignored by the regular suite. Coverage includes owner/freshness/signature gates, busy response handling, exact-session/sibling isolation, duplicate IDs including busy siblings and restarted sessions, replay/capacity/expiration, native config IDs and grouped options, rejection, and timeout retirement. The reused-session regression was also run with its production token guard removed in a disposable worktree; it failed withappliedinstead ofstale_session, as expected.BUZZ_E2E_PORT=4317 pnpm exec playwright test --project=smoke conversation-effort.spec.ts agent-control-regressions.spec.ts— 12 passed (five new workflow cases plus seven existing Stop/model-control regressions).@agentclientprotocol/codex-acp1.9.0. It waits until the first prompt is written and still running, queues Low → High, checks the adapter's returned value, and recalls a random word on the second turn in the same session. The startup default remains Low. The provider's own turn records were checked for the actual model and effort, separately from the mocked browser tests.Manual check: open activity for an owned running agent with native thinking-level options, choose the conversation if prompted, then choose a different level during a response. The old level remains selected while queued; the reported level changes after confirmation. Send another message and confirm the conversation continues. Reopening saved agent settings should show the original default.
Before/after screenshots use the same synthetic colleague and conversation text. Before is captured from the exact upstream base; queued/applied are from this branch.