telegram: /model picker resolves against the CLI model catalogue, add fable (DIVE-1883)#15
Merged
Conversation
… fable (DIVE-1883) MODEL_ALIASES was a hand-maintained copy of the CLI's agent-create alias map and the two drifted apart: the plugin pinned opus to claude-opus-4-7 while the CLI pinned claude-opus-4-8, so /model opus and 5dive compose handed you different models. Both were stale. The CLI now owns the catalogue (src/lib/models.sh, exposed as '5dive models --json'). refreshModelAliases() fetches it at boot and hands it to a new pure applyModelAliases() in commands.ts that replaces MODEL_ALIASES in place -- every read happens inside a handler, so no call site changed. The merge lives in commands.ts so it is testable without importing server.ts, which long-polls on import. Tries the bare binary before sudo: 'models' reads no state, and a standard agent's sudoers grant is scoped to _deliver/_capture/_audit_append, so the sudo path alone would strand those agents on the baked defaults. Fail-closed: a missing/older CLI or a malformed payload leaves the defaults standing rather than emptying the picker; non-string rows are dropped individually. An alias the CLI knows and the plugin does not is added. Baked defaults are now current and gain fable + haiku. telegram-pi's /model help line stopped advertising claude-sonnet-4-5 as its example. Test: test/model-aliases.test.ts (7 cases). Suite 330 pass / 0 fail. Co-Authored-By: Claude Opus 5 <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.
What
MODEL_ALIASESwas a hand-maintained copy of the same alias -> id map the 5dive CLI keeps for agent-create, and the two had drifted apart: the plugin pinnedopustoclaude-opus-4-7while the CLI pinnedclaude-opus-4-8. So/model opusover Telegram and5dive composehanded you different models. Both were stale —claude-opus-5was in neither.Pairs with 5dive#149, which adds the CLI-side source of truth (
src/lib/models.sh, exposed as5dive models --json). Merge that first — this PR degrades to its baked defaults without it, which are also updated here, so order is a preference not a hard dependency.How
refreshModelAliases()(server.ts) fetches5dive models --jsonat boot and hands it toapplyModelAliases()(commands.ts) — a pure function that replacesMODEL_ALIASESin place.Every read of
MODEL_ALIASEShappens inside a handler, well after boot, so mutating the imported object is enough — no call site changed. The merge lives incommands.tsrather thanserver.tsso it's unit-testable: importingserver.tsstarts long-polling Telegram, which is whyparity.test.tsstatic-parses instead.Tries the bare binary before sudo.
modelsreads no state and needs no root, and a standard (non-admin) agent's sudoers grant is scoped to_deliver/_capture/_audit_append— the sudo path alone would silently strand every standard agent on the baked defaults.Fail-closed throughout. A missing CLI (upstream host), an older CLI without
models, or a malformed payload leaves the defaults standing rather than emptying the picker. Non-string rows are dropped individually so one bad entry can't poison the map. An alias the CLI knows and the plugin doesn't is added, so a newly mapped family appears in the picker without a plugin release.Also
fable+haiku: opusclaude-opus-5, sonnetclaude-sonnet-5, fableclaude-fable-5, haikuclaude-haiku-4-5-20251001.telegram-pi's/modelhelp line stopped advertisinganthropic/claude-sonnet-4-5as its example.Test
test/model-aliases.test.ts— 7 cases: the baked map holds only full ids and never a bare alias (Claude Code's startup migration strips those on a fresh config dir, DIVE-506), replace-not-merge semantics, unknown-family adoption, fail-closed onnull/undefined/{}/[]/ string / number, and per-row rejection of non-string ids.Full suite: 330 pass / 0 fail (19 files).
🤖 Generated with Claude Code