Repository navigation
feat: let Claude Code and Codex bots use Fast mode - #101
Conversation
Claude Code's and Codex's ACP adapters offer Fast mode (faster replies for more usage) as a session config option, but Codync only ever set the model, so bots always ran at normal speed. - Bots get a `fastMode` setting. The host applies it after every session/new, session/load and session/fork, since the adapters start each session or process at their own default, and only sends session/set_config_option when the value differs. - Changing it resumes the bot's sessions in a restarted agent, so the conversation context is kept. - `agentModels` reports whether the agent offers Fast mode. The iPhone and desktop editors show a Fast mode switch under Model when it does (or while it's on); the terminal UI form gets the field too. - Session config option parsing moves from auth.rs to agent/config.rs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Live switch: the host keeps each live session's Fast mode option (from every agent answer and config_option_update) and switches the session before its next turn, so changing the setting no longer restarts the agent. - Refusals: when the agent turns Fast mode off right after the bot asked (Claude does this for an account without extra usage), the host reports it as `fastModeSupport: refused` with the agent's reason in `fastModeIssue`, and stops asking until the setting changes or the host restarts. Bots carry `fastModeSupport` (unknown, offered, unsupported, refused); offered/unsupported survive host restarts. - Chat toggle: a ⚡ button by the composer's + on the desktop, a Fast mode item and ⚡ badge on the + menu on iPhone, and `F` plus a header badge in the terminal UI. Settings show the refusal reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hi @icework, thanks for this PR! We just opened a Discord server for Codync: https://discord.gg/JzMXd7gHAJ It should make it much easier to talk through PRs and plans going forward, so it'd be great to have you there. This link gives you the Contributor role automatically when you join. |
Brings the branch up to dev, whose code wins wherever the two overlap: Cursor's per-model options (`modelOptions`) stay as dev has them, and Fast mode is added on top. - Fast mode only takes an on/off (or boolean) option, as Claude Code and Codex offer it. Cursor's `fast` (true/false) is one of a model's options, so it stays with the bot's model options; before this, Cursor bots showed the bolt and every turn tried to set `fast=off`, which Cursor rejects. - The model list stays in `agent/auth.rs` as on dev; `agent/config.rs` holds only Fast mode. - The model's options and Fast mode both show under Model in the desktop, iPhone and terminal editors. - The Fast mode tests read bot state from the event stream (`sync` is gone on dev). - Version 2.17.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdZYFgoEZxruQEn7gcYMN2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdZYFgoEZxruQEn7gcYMN2
|
Thanks @icework, this is a great feature, and the validation write-up made it easy to check.
Checked on the real apps (Codync Dev desktop + iPhone simulator + terminal UI against a 2.17.0 dev host): live on/off switching on one session from each client, the refused state and its reason, a real Codex bot with Fast mode on, and a Cursor-shaped agent that no longer gets the toggle or the |
|
Thanks for your first merged contribution, @icework! Join the Codync Discord with the Contributor role in one step: https://discord.codync.dev |
Summary
Claude Code's and Codex's ACP adapters both offer Fast mode (faster replies for more usage) as a session config option, but Codync only ever set the model, so bots always ran at normal speed. This adds Fast mode per bot, switched live, with refusals reported and a toggle in the chat.
Host
BotConfiggetsfastMode(wirefastMode, default off, additive).session/new(after the model switch, whose answer can change the options),session/load,session/fork,set_config_optionanswers andconfig_option_update. Before every turn it callssession/set_config_optionwhen the value differs from the bot's setting. Both adapters start each session or process at their own default (a resumed session reportsoff), so resumed sessions are switched again.fastand Codex'sfast-mode, each aselectofon/off(booleans handled too).fastModeSupport: refused, with the agent's reason infastModeIssue. Claude does this for an account without extra usage, and appends the reason to the option's description. The host then stops asking until the user changes the setting or the host restarts, instead of re-asking (and Claude re-announcing "turned off") on every session.fastModeSupport(unknown/offered/unsupported/refused).offered/unsupportedsurvive host restarts (kv), so clients can show the toggle before a bot's first turn. Groups always reportunknown.agentModelsreturnsfastMode: bool(the probe session offered it).auth.rs(near the 500-line limit) intoagent/config.rs; the actor side isagent/bot/fast_mode.rs.Clients (shown for an agent bot whose runtime says
offered/refused, or while it's on; never groups)useAgentModelshook so the switch can be its own card row.Ftoggles it for the selected bot (listed in help), the chat header shows⚡ fast/⚡ refused, and the form has a Fast mode field whose hint shows the refusal.Docs:
docs/features/marketplace.md(Fast mode section, including thefastModeSupporttable),ui-conventions.md,file-structure.md. Version 2.15.0 (minor: feature plus additive protocol fields), with What's New.Validation
Host:
cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo testpass. Unit tests cover option matching, value changes, refusal-reason parsing and support persistence. The wire shape was re-recorded (addedfastMode,fastModeSupport,fastModeIssue).e2e::wire_shape_matches_the_snapshotfailed once with an unrelatedevent:usageaddition (this machine's real usage data landing in catch-up) and passed 3/3 on rerun.e2e with a scripted ACP agent (
turns_e2e):fast_mode_switches_live_sessions_without_a_restart: on, then off, then on, all within one agent process; nosession/load; exactly oneon/off/onsequence.a_refused_fast_mode_is_reported_and_not_asked_for_again: the agent turns it off mid-prompt the way Claude does. The bot reportsrefusedwith the reason and isn't asked again on the next turn; toggling the setting asks again.Real agents, on an isolated host (own
CODYNC_HOMEand port) on macOS, with an ACP traffic logger in front of the adapters:fast-mode=onaccepted and kept through the turn. Turning it off and then on switched the same live session (set_config_option off, thenon) with no newinitialize/session/load, and the bot still remembered the first message.config_option_update.set_config_optionon the same session (no restart or reload), there was no refusal, and context was kept ("Your first message asked me to reply with "ok 1""). A directclaude -p --settings '{"fastMode":true}'on the same account reportsfast_mode_state: "on".Desktop:
npm run typecheckandnpm testpass. In the renderer's web demo with stubbed bots: the composer ⚡ toggles between on and off, the refused state shows the warning tint with the reason in its tooltip, and the settings row shows the reason without a model list.iPhone:
xcodebuild test -scheme CodyncKit-Packageon an iOS simulator passes (CodyncKit and CodyncUI, with new tests for decoding, the update payload and composer visibility).All three clients against a real host (a
codync-hostbuilt from this branch, with its ownCODYNC_HOMEand port). Its bots ran the scripted fast-mode agent, so no provider usage: one with Fast mode on, one off, and one the agent refuses.codync-host tui --url …, in tmux):⚡ fast/⚡ refusedand nothing when off.Ftoggles the selected bot, and the host followed each press. On the refused bot,Fclears the refusal.CODYNC_PORT/CODYNC_HOME, driven overCODYNC_REMOTE_DEBUG):iOS Devsimulator build inbuild/dd, paired with acodync-dev://pairlink):Not tested: Linux and Windows desktop. The renderer code is platform-neutral; the only platform-specific piece is the
boltsymbol, which has a Lucide fallback.What's New
zh-Hant
en-US