Remote chats: model, mode and option picks reach the owning machine
Leo's bug (his DEV build, a chat on a Cloud machine): picking a model in the chat's model picker shows
Couldn't switch to claude-opus-5-5: session/set_model is not available for a chat on another machine
and the Mode picker would not open on a Cloud chat.
What
A chat whose acpmux runs on another machine (a Cloud VM, an SSH host) goes through RemoteAcpmuxWire. That wire served only start, prompt, cancel, permission answers, trust and presence, so every model, mode and option pick fell through to its remote.unsupported refusal.
- cmux-tui (the daemon on the machine that runs the chat). New verbs
agent-session-set-model {surface, model_id},agent-session-set-mode {surface, mode_id}andagent-session-set-config {surface, config_id, value}, advertised asagent-session-settings-v1alongsideagent-session-attach-v1. Each sends the matching ACP call (session/set_model,session/set_mode,session/set_config_option) to acpmux on the tab's own pinned session. The verbs take no session id param (deny_unknown_fields). Each returns acpmux's result unchanged, including set_config_option'sconfigOptions, which the page reads. Ids and values must be 1-256 characters of the model-id charset, the same rule as the app'sAcpmuxPaneMethods.isModelID. An observer attachment getsagent_session.read_only. A teammate or link guest getsagent_session.not_trusted; the proxy scope allowlists don't list these verbs either. Spec:cmux-tui/spec/commands.md. - App.
AgentSessionRemoteClientgainssetModel,setModeandsetConfig. By default they throwagent_session.settings_unsupported("update cmux on that machine...").AgentSessionAttachClientcalls the new verbs only when the daemon advertises the capability.RemoteAcpmuxWireforwards the three methods only for its own session (names(sessionId)), refuses them on an observer as read-only, and returns acpmux's answer. The logic lives in Rust; the Swift side only forwards.agentSessionSettingsis added as an optionalDaemonCapability, andplans/cmux-next/daemon-capabilities.jsonis regenerated. - The host's existing rules still run before the wire: the gesture rule for set_mode and set_config_option, the full-access rule, and removal of the
_meta.cmuxGestureticket. The wire never sends_meta.
Mode picker
The access chip's AccessMenu (ComposerPickers.tsx) marks a mode as refused when picking it fails. Once every other mode is refused, the chip shows a fixed label instead of a menu. On a remote chat every session/set_mode failed with the same refusal, so after one pick the chip stopped opening. Now that set_mode is forwarded, picks succeed and the chip stays a menu. No webview change is needed.
Risk
Only remote chats are affected. If the remote machine runs an older daemon, the person sees a clear "update cmux on that machine" error instead of the old refusal. Local chats don't change.
Tests
- Rust (fleet Linux): 158
agent_sessiontests pass and clippy-D warningsis clean. New:model_mode_and_option_picks_go_to_the_pinned_sessioncovers the capability, the not-attached refusal, pinned params, acpmux's answer passed back unchanged, and bad ids and params (including_metaand a leading-). Also added: read-only refusals on an observer for the three verbs, and refusals for the remote relay and untrusted connections throughevery_verb. - Swift (fleet Mac):
RemoteAcpmuxSettingsTests(new) covers forwarding for this chat only, configOptions passed back, the older-daemon error and the observer read-only refusal. It passes, as doRemoteAcpmuxPresenceTests,RemoteAcpmuxWireAnswerTests,RemoteAcpmuxObserverTestsandAgentSessionAttachClientPresenceTests.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes model, mode, and option picks in chats that run on another machine (a Cloud VM, an SSH host) so they reach that machine's acpmux instead of failing with "session/set_model is not available for a chat on another machine".
- The daemon on the owning machine now serves
agent-session-set-model,agent-session-set-mode, andagent-session-set-config(agent-session-settings-v1), mapping them to acpmux'ssession/set_model,session/set_mode, andsession/set_config_optionon the chat's own session. Observers getagent_session.read_only; teammates and link guests getagent_session.not_trusted. - The app advertises the capability and forwards the three calls through
RemoteAcpmuxWireonly for the chat's own session, returning acpmux's answer unchanged (includingconfigOptions). An older daemon answers with a clear "update cmux on that machine" error. - Fixes the mode picker closing after one failed pick: previously every
session/set_modeon a remote chat failed, so the chip showed a fixed label instead of a menu.
Migration
- Remote machines running an older daemon show the settings-unsupported error until their cmux-tui is updated; local chats are unaffected.