The built-in deepseek cast dialed a model DeepSeek retired - #194
Merged
Conversation
Setting the DeepSeek backend up on Amy's box surfaced this: the provider's catalog serves `deepseek-flash` and `deepseek-v4-pro`. There is no `deepseek-v4-flash`, and that is what `default_models` has seeded the built-in `deepseek` cast with. Anyone who installs kaibo, declares a DeepSeek key, and asks for `cast="deepseek"` gets a request-time failure from a default we ship. Both roles now name `deepseek-flash`: the undated id is the rot-resistant one, tracking each new flash generation, and DeepSeek is folding v4-pro into flash. The same dead id was in four documents — `docs/config.md` (twice, including the built-in registry table), `docs/config.example.toml` (three sites, one of them the annotated slot example), `docs/casts.md`, and `README.md` (the table and a sample provenance footer). Two of those are embedded in the binary and served as `kaibo://config/guide` and `kaibo://config/example`, so an operator or a model reading them was being taught a config that cannot work. The registry and the documents drifted because nothing tied them together, so `the_guide_names_the_models_every_built_in_cast_dials` now does: for every built-in cast, the embedded guide must name both models it dials. Run against the old pair, it fails and names the id. A second thing this turned up, corrected rather than removed: `credentials.rs` opened by saying a per-provider dotfile in `$HOME` is the source of truth with the env var winning over it. That describes seeding kaibo deleted; the same doc says so correctly four paragraphs later, and `docs/config.md` has documented the removal all along. The module doc now leads with what is true — kaibo resolves only declared sources — and scopes `load()` as what it is, the fallback the `#[ignore]`d live probes use. It is not dead: `live_key` in tests/consult.rs calls it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The three example casts that name `deepseek-flash` labelled it "cheap fast
surveys", and the chimera rationale sold itself as "a cheap DeepSeek explorer +
a strong Claude synth". Amy: "deepseek flash shouldn't be described as cheap and
small. it's outperforming opus these days." A line that mis-sizes the model
teaches the same wrong thing the retired id did — an operator picks a slot by
what the comment claims about it.
The comments now say what the slot does — "reads the tree and cites" — rather
than what tier the model is presumed to be, so they stay true as the model
moves. The chimera argument keeps the part that is actually its point: two
lineages make mistakes that don't line up.
Left alone deliberately: the role-level language ("a cheap explorer sub-agent")
in tool descriptions and the guide. Whether explorer/synth is still the right
split for the flash families is a real question and Amy's call is to let the
`deepseek` cast run flash on both roles and revisit in a later release, not to
redesign the roles inside a fix PR.
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.
Setting the DeepSeek backend up on this box surfaced a shipped default that cannot work. The provider's catalog serves
deepseek-flashanddeepseek-v4-pro. There is nodeepseek-v4-flash— and that is whatdefault_modelsseeds the built-indeepseekcast with. Install kaibo, declare a DeepSeek key, ask forcast="deepseek", and the call fails at request time on a default we ship.Both roles now name
deepseek-flash. The undated id is the rot-resistant one — it tracks each new flash generation rather than pinning a version the provider will retire under us — and DeepSeek is folding v4-pro into flash, so the two-tier split has nothing left to split.The same dead id was in four documents:
docs/config.mdtwice (including the built-in registry table),docs/config.example.tomlthree times (one of them the annotated slot example an operator copies),docs/casts.md, andREADME.md(the built-in table and a sample provenance footer). Two of those areinclude_str!'d and served askaibo://config/guideandkaibo://config/example, so an operator or a model reading them was being taught a config that cannot work.Why it drifted: nothing tied the registry to the documents.
the_guide_names_the_models_every_built_in_cast_dialsnow does — for every built-in cast, the embedded guide must name both models it dials. Run against the old pair it fails and names the id, which is the check that would have caught this the day DeepSeek changed the catalog.A correction inside this PR
I first reported
credentials::load()as dead code and was going to delete it withkey_file()andkey_file_name(). It is not dead —live_keyintests/consult.rs:1791calls it as the fallback an#[ignore]d live probe uses when the operator's config declares no backend of that kind. My grep coveredsrc/only and the caller is a bareload(kind)intests/.What is wrong there is prose, and it is what misled me:
credentials.rsopened by saying a per-provider dotfile in$HOMEis the source of truth with the env var winning over it. That describes seeding kaibo removed. The same module doc says so correctly four paragraphs down, anddocs/config.mdhas documented the removal all along — the docs were right, the module doc contradicted itself. It now leads with what is true (kaibo resolves declared sources only, and these names are what an operator pointsapi_key_file/api_key_envat) and scopesload()as live-probe infrastructure.Suite 1363/0, clippy clean.
🤖 Generated with Claude Code