feat(booterm): structured pty_exited WS notifications. Plan-validated, impl-validated, code-reviewed green (contracts build clean, contracts test 29/29, booterm + web typecheck clean). wip: in-progress inference/provider refactor (agents.ts, provider.ts, new llama-providers.ts, removed llama-args-validator), plus arena, dispatcher, compaction, schema changes. openspec: pty-exit-notifications complete; x-agent-flags planned (not yet implemented).
5.0 KiB
5.0 KiB
multi-llama-swap-providers-model-favorites — tasks
P0 — config and contracts
- Add a shared local-provider config schema under
packages/contracts. - Add
LLAMA_PROVIDERS_PATHtoapps/server/src/config.tsandapps/coder/src/config.ts. - Add
data/llama-providers.example.jsonwithsam-desktopandembedding. - Implement a loader that falls back to the legacy single-provider env vars when the shared file is missing.
P1 — model identity helpers
- Add shared parsing/formatting helpers for composite model IDs:
provider/model. - Preserve indefinite support for legacy bare IDs by resolving them to the configured default provider.
- Update display-name helpers to strip only the provider prefix intended for presentation, not for routing/cache identity.
P2 — server model catalog and routing
- Refactor
apps/server/src/routes/models.tsto emit a provider-aware model catalog with composite IDs. - Refactor
apps/server/src/services/inference/provider.tsto resolve route and base URL from provider identity instead of string heuristics alone. - Make sidecar routing a per-provider attribute so
embedding/*never hitsLLAMA_SIDECAR_URL. - Replace the bare
deepseek-prefix special case with provider-aware handling for DeepSeek models.
P3 — server call sites that currently assume one endpoint
- Update
apps/server/src/services/model-context.tsto fetch upstream props from the resolved provider and key caches by the full composite ID. - Update
apps/server/src/services/compaction.tsto use the resolved provider endpoint for summaries. - Update
apps/server/src/services/task-model.tsto resolve fallback models through the same provider-aware endpoint logic. - Verify any other direct
LLAMA_SWAP_URLusage inapps/serveris either migrated or explicitly documented as legacy-only.
P4 — favorites persistence
- Add
favorite_modelshandling toapps/server/src/routes/settings.ts. - Define normalization rules for malformed, duplicate, or unavailable favorites.
- Ensure unavailable favorites are hidden from visible picker sections but never auto-deleted from settings.
- Keep favorites out of the server model-catalog payload; derive the Favorites section in the clients from settings + provider-aware inventory.
P5 — BooChat UI
- Update
apps/web/src/components/ModelPicker.tsxto render: Favorites first, then provider sections. - Add a per-model favorite toggle wired to
PATCH /api/settings. - Keep favorited models visible in their provider group as well as the Favorites section.
- Verify session model changes write composite IDs for new selections.
P6 — BooCoder snapshot, dispatch, and arena
- Update
apps/coder/src/services/provider-snapshot.tsso BooCode's localboocodeprovider models retain composite IDs in snapshot data. - Update the compact picker in
apps/web/src/components/AgentComposerBar.tsxto match the grouped/favorite behavior used by BooChat for native local models. - Update
apps/coder/src/services/arena-model-call.tsandapps/coder/src/services/arena-analyzer.tsto use provider-aware routing.
P7 — external-agent parity decision (opencode)
- Decide whether the first slice includes
opencodemulti-provider local models or explicitly limits parity to nativeboocode. - If
opencodeparity is included, add a provider-identity-preserving bridge instead of collapsing tollama-swap/<wireModelId>. - Preferred bridge: a BooCoder-hosted OpenAI-compatible local-model gateway for consumers that still assume one provider namespace.
- If the bridge is deferred, stop advertising multi-provider local models
under the
opencodeprovider until the bridge exists.
P8 — tests and verification
- Add unit tests for model-ref parsing, legacy bare-ID fallback, and provider-aware routing.
- Add tests covering the
embedding/deepseek-r1-qwen3-8bcollision case. - Add tests proving duplicate model names on two hosts do not share context cache entries.
- Add UI or route tests for favorites hide-not-delete behavior.
(
apps/server/src/routes/__tests__/settings-favorites.test.ts, DB-gated: unavailable favorite persists through PATCH/GET and unrelated writes; removal is explicit-only.) - Smoke test native BooChat/BooCoder against:
sam-desktop,embedding, and DeepSeek-enabled configs. (API layer verified 2026-06-12: both hosts healthy,/api/modelsserving grouped composite ids live. Remaining: in-browser send-a-message pass per provider group + a DeepSeek-enabled config.) - If
opencodeparity ships in-scope, add a smoke test proving duplicate local model names still route to the intended provider. (apps/coder/src/services/__tests__/local-gateway-routing.test.ts: resolver + HTTP-route level — same wire name routes to distinct baseUrls with the bare wire id upstream; unknown provider → 400, no upstream call.)