feat(lobe-chat): add the sec seats to the picker, drop two retired ones

Two independent gates kept the new `sec` family out of Lobe, and only one of
them was visible from the symptom.

The picker never auto-discovers. `OPENAI_MODEL_LIST=-all,+<names>` clears
Lobe's built-in OpenAI catalogue and re-adds one model per `+name`, so anything
added to LiteLLM stays invisible until this list is edited and the container
bounced. That pin is deliberate — an unpinned picker offers models that fail on
click — but it means the list rots in both directions, and it had:

- `sec` / `sec-reasoning` missing (hosted_vllm/mog-sec-27b{,-thinking} on
  ana-ml2:8019, added to config.yaml earlier today), and
- `char-rp-reasoning` / `char-rp-fable` still listed after being retired
  upstream, i.e. two picker entries that 400 on click. Verified: a call to
  char-rp-fable now returns 400 Bad Request.

The list is now curated to live, chat-capable, free-local seats — eleven, each
round-tripped through the container after the bounce. The paid family stays out
deliberately; that is now a picker decision rather than a key one.

Which is the other half of this commit: the `lobe-chat-esh` key is no longer
scoped to free local models. On the operator's instruction infra-ops swapped its
explicit array for the `all-proxy-models` access group, so it now reaches the
paid passthroughs with `max_budget: None`. The README documented the old posture
as current, which made it a security claim that was no longer true; it now
carries the change, what it costs, and the fact that the picker is the only
remaining gate.
This commit is contained in:
2026-08-21 08:04:10 -07:00
parent 564f5ae4f6
commit 303fb7a5aa
3 changed files with 44 additions and 2 deletions
+6
View File
@@ -10,3 +10,9 @@ ACCESS_CODE=
KEY_VAULTS_SECRET=
# System-agent background model routing (avoids the gpt-5-mini default 403ing on the scoped key)
SYSTEM_AGENT=topic=openai/summarizer,translation=openai/gen,agentMeta=openai/gen,queryRewrite=openai/summarizer,historyCompress=openai/summarizer,thread=openai/summarizer
# Picker contents. NEVER auto-discovered: -all clears Lobe's built-in OpenAI
# catalogue, then each +name re-adds one, so a seat added to LiteLLM stays
# invisible until it is listed here AND the container is bounced. Keep it to
# LIVE, CHAT-CAPABLE models: a retired name left here becomes a picker entry
# that 400s on click, and TTS/embedding/reranker seats cannot chat at all.
OPENAI_MODEL_LIST=-all,+gen,+gen-reasoning,+char-rp,+summarizer,+summarizer-large,+classifier,+image-judge,+coder-fast,+chat-judge,+sec,+sec-reasoning
+28 -1
View File
@@ -158,11 +158,38 @@ week. Report sustained volume, and any voice string not on the list above, to
## Credential posture
> ### ⚠️ CHANGED 2026-08-21 — this key is NO LONGER free-local-only
>
> On the operator's explicit instruction, infra-ops replaced the key's explicit
> model array with the **`all-proxy-models` access group**. `lobe-chat-esh` now
> reaches **everything behind the gateway, paid passthroughs included** —
> `glm-*`, `kimi-k3`, `gen-frontier*`. The scoping described below is history,
> kept because the reasoning still explains what the guard rail was for.
>
> **What this means in practice:** a paid call through this key spends real
> vendor credits, and the key has **`max_budget: None`** — no ceiling. The UI
> in front of it is LAN-exposed with an access code and nothing else. A spend
> cap is available on request from infra-ops; the operator has not asked for
> one, so it is uncapped by instruction, not by oversight.
>
> Two side-effects of the access group worth knowing: it **auto-includes future
> models**, so no more per-seat key edits, and it only ever resolves **live**
> models — which is how five retired names (`char-rp-fable`,
> `char-rp-reasoning`, `lfm2.5-2.6b`, `qwen3-reranker`,
> `reranker-a4-gte-modernbert`) dropped off it silently.
>
> **The picker is now the only gate.** `OPENAI_MODEL_LIST` decides what a user
> can select; the key no longer restricts anything. As of 2026-08-21 that list
> deliberately excludes the paid family — so exposing paid models to this UI is
> one env edit away, and should stay a conscious decision rather than a drift.
The original posture, for the record:
Deliberately **not** the shared all-agents key — that reaches the paid passthroughs
(GLM, Kimi), and a LAN-exposed chat UI holding it would let anyone who can reach the
port spend vendor credits from a pool shared across every project.
This stack uses a purpose-minted LiteLLM virtual key, `key_alias: lobe-chat-esh`,
This stack used a purpose-minted LiteLLM virtual key, `key_alias: lobe-chat-esh`,
scoped to the 20 free **local** models. Scoping was verified at mint time, both
directions:
+10 -1
View File
@@ -69,7 +69,16 @@ services:
- OPENAI_PROXY_URL=${OPENAI_PROXY_URL:-http://10.250.50.70:4000/v1}
# Pin the visible model list so the picker shows fleet seats rather than
# Lobe's built-in OpenAI catalogue (which would 404 against the gateway).
- OPENAI_MODEL_LIST=${OPENAI_MODEL_LIST:--all,+gen,+gen-reasoning,+char-rp,+char-rp-reasoning,+char-rp-fable,+summarizer,+summarizer-large,+classifier,+image-judge,+coder-fast,+chat-judge}
# ⚠️ THIS NEVER AUTO-DISCOVERS. `-all` clears Lobe's catalogue and each
# `+name` re-adds ONE model, so a seat added to LiteLLM stays invisible
# here until this list is edited and the container bounced. That is the
# price of the pin, paid deliberately: an unpinned picker offers models
# that fail on click. Two consequences to remember when editing:
# - a RETIRED model left in this list becomes a visible entry that 400s
# (char-rp-reasoning + char-rp-fable did exactly that until 2026-08-21)
# - the list is curated to LIVE, CHAT-CAPABLE seats: no TTS, embedding or
# reranker models (they cannot chat), and no paid passthroughs.
- OPENAI_MODEL_LIST=${OPENAI_MODEL_LIST:--all,+gen,+gen-reasoning,+char-rp,+summarizer,+summarizer-large,+classifier,+image-judge,+coder-fast,+chat-judge,+sec,+sec-reasoning}
# SYSTEM AGENT — the background model Lobe uses for auto-naming
# conversations (topic), history summarization, translation, query
# rewrite, thread naming, and assistant-meta generation. ITS DEFAULT IS