Skip to content

fix: deprecate the dead --async-mode/--sync-mode and --agui no-ops (#88) - #89

Merged
dkedar7 merged 1 commit into
mainfrom
fix/88-remove-dead-flags
Jul 19, 2026
Merged

dkedar7 merged 1 commit into
mainfrom
fix/88-remove-dead-flags

Conversation

@dkedar7

@dkedar7 dkedar7 commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Closes #88.

The problem

--async-mode/--sync-mode and --agui were accepted-and-ignored no-ops advertised as working controls.

CHANGELOG 0.6.0 (ADR 0003) said --agui/--async/--stream-mode were accepted-and-ignored "for one release." --stream-mode was duly retired in #62. The other two shipped 20 patch releases longer — still inert, still presented as functional in the README (the CLI Options row and the langstage.toml [ui] async_mode example), --help, --show-config (async_mode = True [override]), /status (Mode: async), and /config.

Root cause: ADR 0003 collapsed every turn onto the single async AG-UI path (run_single_turn_aguiagui_stream.agui_stream_updatescore.agui.iter_chunk_frames), leaving no second behavior for either flag to select.

  • use_async was resolved, stored in the session context, and read in exactly three display-only places/status, /config, --show-config. There was no if use_async: branch anywhere in run(), so --sync-mode and --async-mode produced byte-identical output.
  • use_agui was passed into run() and never read at all. Its help text also described a mechanism that no longer exists ("instead of the built-in event parser" — since langstage-core 1.0 the AG-UI adapter is the only path, and the [agui] extra has been a redundant alias since 0.6.1).

Since ADR 0003 there is no "async mode" left to implement, so removal is the honest fix — not wiring a dead knob up to something invented.

The fix — mirrors #62 exactly

--stream-mode was retired in #62 as a soft deprecation, not a hard removal. This matches that posture flag-for-flag:

#62 did this PR does
hidden=True + "(deprecated: …)" help same, for --async-mode/--sync-mode and --agui
accepted-and-ignored (scripts don't break) same
one-line _status deprecation notice when passed same, one per flag
added to _INERT_KEYS → omitted from --show-config//config async_mode added
deleted the /status "Stream:" line deleted the /status "Mode:" line
dropped env/TOML resolution, kept the field inert dropped ui.async_mode, kept async_mode inert
removed the README rows removed the CLI Options row + the [ui] async_mode example

Hard-remove vs soft-deprecate: soft, because #62 did. A hard removal would exit 2 with "no such option" on any existing --async-mode script — a strictly worse break than #62 accepted for the same class of flag, and the instruction was to match the precedent over personal preference. (Argument for hard removal: these flags already had a 20-release grace, so a further silent one is indefensible. That's addressed — the grace is no longer silent. Each use now prints a notice, which is what makes the next release's hard removal defensible.)

An existing langstage.toml with [ui] async_mode: it keeps loading, and the key is simply ignored — never an error, and no warning. Two reasons: (1) it's what #62 did for [ui] stream_mode; (2) a config file that suddenly failed to resolve would be a nastier regression than the dead knob being retired, and unlike a CLI flag a TOML file is committed and shared, so a per-run warning would be recurring noise the user may not own the file to fix. The rest of the file ([ui] verbose, [configurable], …) resolves normally. Locked by a test.

Before / after

The issue's repro is no longer reachable — the flags aren't discoverable from --help, the README, or --show-config, and passing one says so:

$ langstage-cli --demo --no-interactive --async-mode "hello"
Note: --async-mode/--sync-mode is deprecated and has no effect (every turn streams through the one async path).
(demo agent) You said: hello

$ langstage-cli --demo --no-interactive --agui "hello"
Note: --agui is deprecated and has no effect (the AG-UI adapter is the only streaming path).
(demo agent) You said: hello

--show-config and /status no longer report a mode that doesn't exist:

$ langstage-cli --show-config          # async_mode row: gone
$ /status
  Agent:       Demo Agent
  Thread ID:   b6b371ff...
  Verbose:     off                     # the "Mode: async" line is gone
$ /config async_mode
Unknown config key: async_mode

A langstage.toml carrying the retired key still loads cleanly, exit 0, with [ui] verbose and [configurable] unaffected.

Tests

139 passed (baseline 128, +11). New tests/test_async_mode.py (10) plus one in test_codeconfig.py, with test_cli_help.py / test_show_config.py extended.

Verified they actually catch the bug: with langstage_cli/ reverted and the tests kept, 11 fail; restored, all pass. They cover each surface the issue named — --help, --show-config (with and without the flag passed), /status, /config, TOML resolution — plus accepted-with-a-notice for all three spellings, and a guard that a normal run emits no notice.

ruff check and ruff format --check clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_011HWCfJii6gXd3XL3Gq3W8B

--async-mode/--sync-mode, [ui] async_mode, and --agui were advertised as working
controls, but ADR 0003 collapsed every turn onto the single async AG-UI path, so
neither flag has a branch left to take: use_async was read in exactly three
display-only places (/status, /config, --show-config) and use_agui was never read
at all. CHANGELOG 0.6.0 said they were accepted-and-ignored "for one release";
--stream-mode was retired in #62 and these two shipped 20 patch releases longer.
Same posture as #62: hide both from --help; drop the README option row and the
[ui] async_mode example; omit async_mode from --show-config; delete the /status
"Mode:" line and the /config async_mode entry; stop resolving ui.async_mode;
accept-and-ignore both flags (so scripts don't break) with a one-line deprecation
notice each. A langstage.toml still setting [ui] async_mode keeps loading — the
key is ignored, never an error. Also corrects --agui's help and the agui_stream
docstring, which described a built-in event parser that no longer exists. No
streaming behavior changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HWCfJii6gXd3XL3Gq3W8B
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant