feat(hub/acp): translate ACP configOptions into mode/model state events (#334)#336
Merged
Conversation
…ts (#334) Newer ACP daemons (kimi-code-ts, ADR-054 D6) report per-session model/mode state via a `configOptions` select array in the session/new reply instead of the legacy `modes`/`models` blocks. ACPDriver only parsed the legacy shape, so the mode/model picker never hydrated for these engines even though switching works on the wire. Add `translateConfigOptions` — maps the `configOptions` array into the same mode/model lists the legacy path produces (mode entries keyed by `id`, model entries by `modelId`, both carrying `name`), so a single downstream (id-set caching + the synthetic initial-state system event) handles either shape. - Shape-driven + engine-neutral: any future ACP adopter benefits. - Filled PER CATEGORY, only when the legacy field is absent → legacy-shaped replies (gemini-cli, Python kimi-code) produce byte-identical output. - `thought_level` has no mobile picker yet: its current value rides the initial-state event under `thoughtLevel` for forensics only. - `config_option_update` notifications fold into the same system-event path as current_mode_update / current_model_update. Tests: TestTranslateConfigOptions (unit — kimi 0.27.0 capture, malformed, empty-value, no-configOptions); TestACPDriver_ConfigOptionsHydratesModeModelState (integration — initial-state event + current ids + thoughtLevel + a set_model round-trip validating against the cached list). Legacy mode/model tests stay green. go vet + full hostrunner suite pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The lint-legacy-markers ratchet flagged the descriptive word "legacy" in the new configOptions comments as an untargeted compat-debt marker. The older modes/models ACP shape isn't being removed (gemini-cli / Python kimi-code keep using it), so "legacy" was inaccurate anyway — reworded to "older" / "modes/models-shaped". No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #334.
Summary
Newer ACP daemons —
kimi-code-ts(ADR-054 D6), added in #335 — report per-session model/mode state via aconfigOptionsselect array in thesession/newreply instead of the legacymodes/modelsblocks.ACPDriveronly parsed the legacy shape, so the mode/model picker never hydrated for these engines even thoughsession/set_modelworks on the wire (the gap #334 documents).Change
New
translateConfigOptions(raw)maps theconfigOptionsarray into the same mode/model list shape the legacy path already produces — mode entries keyed byid, model entries bymodelId(both carryingname) — so the existing id-set caching + synthetic initial-state system event downstream inStartconsumes either shape unchanged.TestACPDriver_EmitsInitialModeModelSystemEvent/SetModelDispatch/SetModelDispatch_KimiShapetests stay green.thought_level(acceptance deps(hub): bump modernc.org/sqlite from 1.34.4 to 1.50.0 in /hub #4, out of scope): no mobile picker yet, so its current value rides the initial-state event under a distinctthoughtLevelkey for forensics only — never folded into the mode/model reducer.config_option_updatemid-session notifications fold into the samesystem-event path ascurrent_mode_update/current_model_update.Acceptance criteria
currentModeId/currentModelIdset fromcurrentValue).set_modelvalidates against the cached list populated from configOptions (integration test round-trips it).session/loadempty/{}carryover unaffected (W7/W7c path untouched; feat(hub/hostrunner): add kimi-code-ts engine family (TypeScript Kimi Code), M1-only via ACP #335'sTestSessions_ResumeThreadsACPCursor_KimiCodeTScovers the kimi-code-ts resume case).Tests
TestTranslateConfigOptions— unit; the live kimi-code 0.27.0 capture from feat(hub/acp): translate ACP configOptions into mode/model state events #334 plus malformed JSON, no-configOptions, and empty-value drop.TestACPDriver_ConfigOptionsHydratesModeModelState— integration; asserts the synthesized system event's current ids +thoughtLevelforensics field + aset_modelround-trip against the configOptions-advertised model.go vetclean; fullinternal/hostrunnersuite passes locally (Go at /usr/local/go).🤖 Generated with Claude Code