pi: seed settings.json instead of clobbering the user's model choice#206
Draft
MarkAngler wants to merge 2 commits into
Draft
pi: seed settings.json instead of clobbering the user's model choice#206MarkAngler wants to merge 2 commits into
MarkAngler wants to merge 2 commits into
Conversation
Model discovery bucketed `system.ai.*` ids into claude/codex/gemini/oss by
matching substrings in the model name. Names don't say which API dialect a
model speaks, so the guess misfired three ways:
- `gpt-oss-120b`/`gpt-oss-20b` matched `"gpt-" in id` and were bucketed as
OpenAI Responses models. They only speak `mlflow/v1/chat/completions`, so pi
registered them under `databricks-openai` pointing at /ai-gateway/codex/v1 —
a route that rejects them. Claude's web_search MCP aimed at the same route.
- `claude-fable-5` matched none of `claude-{opus,sonnet,haiku}-` and vanished.
- `claude_models` is a `{family: id}` map, so only the newest model per family
reached agents that render a full model list. A workspace serving 11 Claude
models showed pi 3.
Every model-service entry already carries `supported_api_types`; the listing
fetched it and threw it away. Bucket by that instead, with precedence — a
Claude model also advertises mlflow chat-completions and would otherwise land
in two buckets. Workspaces whose payload predates the field fall back to the
name rules, with the codex rule tightened to require a version digit after
`gpt-` so gpt-oss is excluded there too.
Also:
- Sort every bucket with `model_version_sort_key`, replacing a lexicographic
reverse sort that ranked `opus-4-8` above `opus-4-10`, and leaving
`codex_models[0]` as the newest rather than the alphabetically first.
- Return `claude_ids` (every Anthropic-dialect id) alongside the family map;
persist it as `claude_model_ids` and register it in pi's models.json.
opencode deliberately keeps reading the family map — it takes `anthropic[0]`
as its default, which widening would silently move onto claude-fable-5.
- `check_gateway_endpoint("codex")` now delegates to `codex.default_model`.
A non-empty list wasn't enough: codex drops ids that don't parse as
`gpt-<version>`, so a gpt-oss-only workspace reported codex available and
then failed at launch with "No models available for codex".
State keys are additive; no STATE_VERSION bump (a mismatch discards every
workspace's state, including managed_configs and provider_services).
Refs databricks#204
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pi persists the model picked in its own selector to settings.json (via `setDefaultModelAndProvider`). ucode overwrote `defaultProvider`/`defaultModel` on every launch *and* every 30 minutes from the token-refresh thread, so the choice could never survive a relaunch — the "ucode just overwrites them" half of databricks#204. `_write_settings` now only writes when there is nothing to preserve or when what is there is ucode-authored residue that no longer resolves: - nothing pinned yet — seed it, so Pi's `findInitialModel` can't fall through to an env-key-backed provider (e.g. HF_TOKEN exposing huggingface). This is the behavior the pin existed for, and it is unchanged. - pinned to a ucode provider we no longer register (`databricks-openai` on a workspace with no Responses models, or a legacy provider name) — repair. - pinned to a ucode provider we do register, but to a model it no longer offers — repair. A pin naming a provider ucode does not manage is left alone: Pi writes defaultProvider only on an explicit user selection, so it is a deliberate choice, not fall-through. The refresh thread now passes `update_settings=False`. It still rewrites models.json every 30 minutes — that rotates the bearer token baked into the file, which is load-bearing — but no longer resets the model. Refs databricks#204 Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Part of #204.
Problem
Pi persists the model picked in its own selector to
settings.json(viasetDefaultModelAndProvider). ucode overwrotedefaultProvider/defaultModelon every launch and every 30 minutes from the token-refresh thread, so the user's choice could never survive to the nextucode pi— the "if you try to modify the providers manually, ucode just overwrites them on next launch" part of #204.Fix
_write_settingsnow only writes when there is nothing to preserve or when what is there is ucode-authored residue that no longer resolves:findInitialModelcan't fall through to an env-key-backed provider (e.g.HF_TOKENexposing huggingface). Unchanged behavior.databricks-openaion a workspace with no Responses models, or a legacy provider name) — repair.A pin naming a provider ucode does not manage is left alone (Pi writes
defaultProvideronly on an explicit user selection).The refresh thread now passes
update_settings=False: it still rewritesmodels.jsonevery 30 minutes to rotate the baked-in bearer token, but no longer resets the model.🤖 Generated with Claude Code