From 303fb7a5aa59d76a24b9fe5a9d226ffcb7298e67 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 21 Aug 2026 08:04:10 -0700 Subject: [PATCH] feat(lobe-chat): add the sec seats to the picker, drop two retired ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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,+` 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. --- stacks/lobe-chat/.env.example | 6 ++++++ stacks/lobe-chat/README.md | 29 ++++++++++++++++++++++++++++- stacks/lobe-chat/compose.yaml | 11 ++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/stacks/lobe-chat/.env.example b/stacks/lobe-chat/.env.example index add19a3..9089c66 100644 --- a/stacks/lobe-chat/.env.example +++ b/stacks/lobe-chat/.env.example @@ -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 diff --git a/stacks/lobe-chat/README.md b/stacks/lobe-chat/README.md index 65371db..e7374f0 100644 --- a/stacks/lobe-chat/README.md +++ b/stacks/lobe-chat/README.md @@ -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: diff --git a/stacks/lobe-chat/compose.yaml b/stacks/lobe-chat/compose.yaml index a11ea2a..e039ad4 100644 --- a/stacks/lobe-chat/compose.yaml +++ b/stacks/lobe-chat/compose.yaml @@ -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