Skip to content

telegram: /model picker resolves against the CLI model catalogue, add fable (DIVE-1883)#15

Merged
lodar merged 1 commit into
mainfrom
dive-1883-model-sot
Jul 25, 2026
Merged

telegram: /model picker resolves against the CLI model catalogue, add fable (DIVE-1883)#15
lodar merged 1 commit into
mainfrom
dive-1883-model-sot

Conversation

@lodar

@lodar lodar commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

What

MODEL_ALIASES was 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 pinned opus to claude-opus-4-7 while the CLI pinned claude-opus-4-8. So /model opus over Telegram and 5dive compose handed you different models. Both were stale — claude-opus-5 was in neither.

Pairs with 5dive#149, which adds the CLI-side source of truth (src/lib/models.sh, exposed as 5dive 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) fetches 5dive models --json at boot and hands it to
  • applyModelAliases() (commands.ts) — a pure function that replaces MODEL_ALIASES in place.

Every read of MODEL_ALIASES happens inside a handler, well after boot, so mutating the imported object is enough — no call site changed. The merge lives in commands.ts rather than server.ts so it's unit-testable: importing server.ts starts long-polling Telegram, which is why parity.test.ts static-parses instead.

Tries the bare binary before sudo. models reads 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

  • Baked defaults are now current and gain fable + haiku: opus claude-opus-5, sonnet claude-sonnet-5, fable claude-fable-5, haiku claude-haiku-4-5-20251001.
  • telegram-pi's /model help line stopped advertising anthropic/claude-sonnet-4-5 as its example.
  • Plugin manifest 0.5.35 -> 0.5.36 (versioned plugin cache).

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 on null / undefined / {} / [] / string / number, and per-row rejection of non-string ids.

Full suite: 330 pass / 0 fail (19 files).

🤖 Generated with Claude Code

… 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>
@lodar
lodar merged commit 912ab7c into main Jul 25, 2026
2 checks passed
@lodar
lodar deleted the dive-1883-model-sot branch July 25, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant