15 Commits
Author SHA1 Message Date
Nathan Schneider 12da5c1268 docs: chat task models — OWUI task model pinned to greenpt/glm-5.3-flash, suggestions state 2026-10-19 14:53:20 -06:00
Nathan Schneider 1f3f0ce9b8 librechat-sandbox: per-member image billing restored; system key is safety-net only 2026-10-19 08:50:14 -06:00
Nathan Schneider fde5d143c5 librechat-sandbox: image gen bills to system key (no gate); fallback usage monitored in digest 2026-10-19 08:30:40 -06:00
Nathan Schneider 0e708a99c6 librechat-sandbox: homepage-canonical palette + green logo (flash-glitch fix) 2026-10-18 23:50:54 -06:00
Nathan Schneider 467d19357d librechat-sandbox: per-member key auto-load (portal feed + sync-keys.js), redaction gotcha 2026-10-18 23:29:16 -06:00
Nathan Schneider 6a0d092e53 librechat-sandbox: manifest-pinned deploy flow, builder-cache + ECONNRESET pitfalls, branding overlay, keyless image path; current deployed tag 2026-10-18 22:53:12 -06:00
Nathan Schneider bac352f50e LibreChat sandbox: accessible image generation via MCP tool; two MCP servers; new overlay tag 2026-10-18 20:54:31 -06:00
Nathan Schneider 34a23a34f3 LibreChat sandbox: rewrite maintenance doc for the volume-config + overlay-image architecture
Documents the verified setup: config/env/MCP on the persistent volume,
brand assets via the pinned overlay image, /app/data/env precedence over
cloudron env, the manifest.dockerImage deploy mechanism, image-gen as an
agent tool, and the 2026-10-18 crash-loop root cause (hand-edited manifest).
2026-10-18 20:31:03 -06:00
Nathan Schneider fa979a5ed9 Add LibreChat sandbox maintenance documentation 2026-10-18 15:32:23 -06:00
inference-admin 5bb99b8592 getting-started: add PWA install note for the chat on phones 2026-10-17 15:07:34 -06:00
inference-bot e7c86b16ba models: fix incorrect 'biggest context' claim for qwen3.5-122b (issue #4 — GLM/DeepSeek have 1M) 2026-10-16 16:32:08 -06:00
inference-bot d3c3c8f8f7 models: normalize Green column to ✅ format; explain privacy column terms (architectural/policy/ZDR) 2026-10-16 11:05:11 -06:00
inference-bot 884340427f models: dedupe green emoji legend; fix image-gen instructions (Integrations button > Image) 2026-10-16 10:59:05 -06:00
inference-bot 9699ff08cc models: remove PublicAI provider; Regolo becomes the Apertus provider; emoji = feature tier; add Qwen-Image image-generation section 2026-10-16 10:50:46 -06:00
inference-bot 0d4a62a2da models: add Regolo provider (Apertus 70B, Qwen 3.5 122B) + image generation via regolo/qwen-image 2026-10-16 10:29:48 -06:00
4 changed files with 240 additions and 20 deletions

No files matched your search

+14
View File
@@ -62,6 +62,20 @@ Your usage draws from your monthly allowance; you can see it on the
If the chat ever says your balance is out, that's the allowance, not an error — If the chat ever says your balance is out, that's the allowance, not an error —
see "Your allowance" below. see "Your allowance" below.
### Add the chat to your phone
The chat works like an app on your phone — no app store needed. Open
[chat.inference.coop](https://chat.inference.coop) in your phone's browser and
log in, then:
- **iPhone (Safari):** tap the **Share** button (the square with an arrow),
then **Add to Home Screen**.
- **Android (Chrome):** tap the **⋮** menu, then **Add to Home Screen**
(or **Install app**).
You'll get an icon on your home screen that opens the chat full-screen, like
any other app. Your login stays active — just tap and chat.
## 3. Get involved in governance ## 3. Get involved in governance
You don't just use the co-op; you help run it. Decisions about models, pricing, You don't just use the co-op; you help run it. Decisions about models, pricing,
+27
View File
@@ -0,0 +1,27 @@
# Chat task models (titles, tags, suggestions)
Both chat front doors generate small helper outputs — conversation titles,
tags, retrieval queries — with a model separate from the one answering the
member. These tasks are pinned to a small, inexpensive model so they never
bill against the member's chosen (larger) model.
## Open WebUI (chat.inference.coop)
- Title generation and tag generation are **enabled**; follow-up reply
suggestions and input autocomplete are **disabled** (October 2026).
- The task model (`task.model.default` in the Postgres `config` table) is
pinned to `greenpt/glm-5.3-flash` — a small, inexpensive model — so titles
and tags always run on it regardless of which model the member is chatting
with. Before October 2026 it was empty, which meant helper tasks ran on the
member's selected model.
- Config lives in the app's Postgres database (`config` table, key/value rows
with JSON values) and is read at startup: change a row, then restart the
app (`cloudron restart --app <id>`; note `restart` takes no `--timeout`).
## LibreChat (librechat-test.inference.coop)
- Title generation is configured in `/app/data/librechat.yaml`:
`titleConvo: true`, `titleModel: greenpt/glm-5.3-flash`,
`titleMethod: completion` — the same small GreenPT model.
- LibreChat v0.8.8 has no reply-suggestion feature; there is nothing to
disable on that front.
+156
View File
@@ -0,0 +1,156 @@
# LibreChat sandbox maintenance
The LibreChat evaluation instance at **librechat-test.inference.coop**
(Cloudron app `4023ccbf-d57a-4500-97df-14de9cf3516e`, appstore package
`ai.librechat.cloudronapp@1.4.1`, which bundles **LibreChat v0.8.8**).
The single source of truth for the deployment is the repo
**[co-op/librechat-custom](https://git.inference.coop/co-op/librechat-custom)**
— its README is the full runbook (config deploy, image build/deploy, rollback,
env vars, branding overlay, known state). This doc is the operator-facing
summary.
## Architecture: what lives where
- **App config** — `/app/data/librechat.yaml` (persistent volume, mirrored
byte-identically in the repo). Holds the "Inference Co-op" custom endpoint
(gateway), the 8-model chat picker, speech, web search, and the two MCP
servers. Volume edits deploy via `cloudron exec` (base64), never via the
image — the image never touches `/app/data`.
- **Env file** — `/app/data/env` (persistent volume). **`start.sh` sources it
AFTER the process env, so it wins over `cloudron env`** — that is where
`APP_TITLE="Inference Co-op"`, `ALLOW_EMAIL_LOGIN=false` (password login
removed; Cloudron SSO is the only login path), and
`SCHEDULES_SINGLE_PROCESS=true` must live.
- **Other env vars** — via `cloudron env`: `TTS_API_KEY`/`STT_API_KEY`
(dedicated LiteLLM virtual key, alias `librechat-speech`, $5/30d, audio
models only — never the gateway master key), `IMAGE_GEN_OAI_BASEURL` +
`IMAGE_GEN_OAI_MODEL` (agent image tool → gateway), `SEARXNG_INSTANCE_URL`.
- **MCP servers** — `/app/data/mcp/server.py` (docs search, `search_docs`,
starts at boot) and `/app/data/mcp/image_server.py` (image generation,
`generate_image`, `startup: false`); both mirrored in the repo under
`mcp/`, stdlib-only Python.
- **Branding overlay** (logo, favicons, PWA icons, `<title>`, `custom.css`,
`custom2.js`) — baked into a pinned overlay image `FROM` the official
appstore image. Deployed tag (last verified 2026-10-19):
`registry.inference.coop/co-op/librechat-custom:20261019-fc9b11e`.
- **Branding CSS/JS** — `custom.css` overrides LibreChat's Tailwind theme
variables on `html.light`/`html.dark` using the HOMEPAGE's canonical
palette (`--cream #faf8f5`, `--wash #eef4ea`, `--green-deep #5b8c5a`,
`--green-mid #6ba86b`, `--ink #2d3327`, `--muted #6b7a62`) and brands
the loading flash (`#loading-container`); the login logo is the green
pine-dots vector (white-plate variant was invisible on cream — the
'flash on load' glitch), cache-busted via `?v=3` in the client bundle.
and hides the register/sign-up prompt via
`p:has(> a[href*="register"])`; `custom2.js` is a MutationObserver that
hides the prompt when React renders it (the auth form renders after
`load`). The `interface.theme` block in the yaml remains
forward-compatible only (inert on v0.8.8).
## Image generation (two member-facing paths)
1. **MCP tool (default, no key ever)**: the `inference-image` MCP server
exposes `generate_image` in the composer's **+** palette — no agent setup,
no key prompt. Per-member billing via `customUserVars.IC_API_KEY` (seeded
from the portal) + `env: IC_API_KEY: "{{IC_API_KEY}}"`; a system-key
fallback (`system-image-fallback`, $5/30d) covers the rare empty-value
case. The `customUserVars` gate blocks a not-yet-seeded member until the
next sync (≤10 min) — accepted as a short delay over billing everything
to the system account.
2. **Agent tool**: LibreChat's built-in "OpenAI Image Tools"
(`IMAGE_GEN_OAI_BASEURL`/`IMAGE_GEN_OAI_MODEL` → gateway; members paste
their own key — v0.8.8 limitation).
## Update policy
- The app is **image-sourced** (the `--force` update moved it off the
appstore source), so Cloudron will not auto-update it. This is deliberate —
same lockdown model as LiteLLM.
- **Image deploys**: build `--no-cache`, write the new tag into
`CloudronManifest.json.dockerImage` (the only editable field), commit, then
`cloudron update --app <id> --force`. **`--image` alone is IGNORED** when
the manifest sits in the deploy directory. **The remote builder's cache can
serve stale COPY layers even when file content changed** (six consecutive
"Build successful" runs did on 2026-10-19) — so after every image deploy,
verify: the Cloudron API's `manifest.dockerImage`, container-file md5 vs
repo md5, the served HTML, and the rendered DOM. Full checklist in the
repo README.
- **When a new appstore package ships**: pull its manifest copy into the repo
(`GET /api/v1/apps/<id>` → `.manifest`), repoint `dockerImage` to the
rebuilt overlay, bump the Dockerfile `FROM` to the new `manifest.dockerImage`
(pinned), rebuild, verify in the sandbox, then update.
- **Rollback**: repoint `CloudronManifest.json.dockerImage` to the previous
tag and rerun `cloudron update --force` (or the original appstore image).
Cloudron also snapshots the app before every image update.
## Hard-won pitfalls (do not re-learn these)
- `cloudron update` deploys **`manifest.dockerImage`** from the manifest in
the deploy directory — the `--image` flag alone is ignored (and the update
output still prints the `--image` value, so it *looks* right). The repo
manifest is a byte-identical copy of the OFFICIAL appstore manifest except
`dockerImage`; editing anything else in it (or hand-writing one that omits
the addons) strips `postgresql`/`mongodb`/`oidc`/`sendmail`/`localstorage`
from the app and crash-loops it (`mkdir: Read-only file system`). That is
what broke the sandbox on 2026-10-18.
- The remote builder's layer cache can pin COPY steps to old file content
even across "successful" rebuilds — use `--no-cache` after asset edits and
confirm by comparing container-file md5 against the repo file.
- Deploy `librechat.yaml` only via base64 round-trip. A `sed` insert once
broke the YAML indentation and LibreChat **silently fell back to defaults**
(all custom branding/models/MCP gone) with a single log line.
- Reading large files from the container over `cloudron exec` with a plain
`cat` resets the connection (`ECONNRESET`) — pipe through
`gzip | base64 | fold` and decode locally.
- `cloudron env set` alone does NOT disable the password form —
`ALLOW_EMAIL_LOGIN` must be flipped in `/app/data/env` (precedence above).
- Image generation in LibreChat is the **MCP tool** (composer **+** palette);
the agent "OpenAI Image Tools" path also exists. Image models in the chat
picker were the source of the old 500 errors and are deliberately excluded.
- No `branding:` block exists in LibreChat's config schema, and the login
page has no `.login-page`/`.primary` classes to target — theming happens by
overriding the Tailwind CSS variables on `html.light`/`html.dark`
(`--surface-primary`, `--accent-primary`, …) from the overlay `custom.css`.
## Per-member key auto-load (no API-key prompts)
Members never enter an API key. The portal provisions each member's LiteLLM
key at onboarding; the sandbox seeds it into LibreChat's user-key store:
- `GET /admin/librechat/keys` on the portal returns active members' chat keys
(dedicated `X-Sync-Token` auth — `LIBRECHAT_SYNC_TOKEN` on both apps).
- `/app/data/sync-keys.js` (in the LibreChat container, mirrored in the repo
as `sync-keys.js`) fetches that feed and seeds the `keys` collection
(chat endpoint, `apiKey: "user_provided"`) and `pluginauths`
(`mcp:inference-image` → `IC_API_KEY`, injected per-user via
`customUserVars` so image generation bills to the member's own team).
- Members without a sandbox account are skipped until they first log in; run
the sync after onboarding waves and on a schedule (the command is in the
repo README). Idempotent.
- Encryption matches LibreChat's own (`CREDS_KEY`/`CREDS_IV`, read from
`/proc/1/environ` — exec sessions don't inherit the app env).
> Terminal output redacts values after `apiKey:` as `***` even for harmless
> strings (`user_provided`, `${TTS_API_KEY}`). Probe lengths/counts instead
> of trusting redacted output.
## Verification (after any change)
```bash
cloudron logs --app 4023ccbf-d57a-4500-97df-14de9cf3516e --lines 60 | \
grep -iE 'custom config|error|invalid|MCP|schedules'
curl -s https://librechat-test.inference.coop/api/config # appTitle, emailLoginEnabled
```
Expected: `Custom config file loaded`, `[MCP][inference-docs]` initialized
with tool `search_docs`, `inference-image` registered (its `Tools: undefined`
boot line is expected — per-user startup), `[schedules] engine started`,
`appTitle: Inference Co-op`, `emailLoginEnabled: false`. The login page shows
the co-op logo, the co-op favicon, a single "Login with Inference
Cooperative" (Cloudron SSO) path with no email/password form, **no
"Don't have an account?" line**, and the cream/green co-op color scheme.
After an IMAGE deploy, additionally run the four-step verification in the
repo README (API `manifest.dockerImage`, container md5 vs repo md5, served
HTML tags, rendered DOM colors).
+43 -20
View File
@@ -16,20 +16,18 @@ provider today is best on both.
|---|---|---|---|---| |---|---|---|---|---|
| **Tinfoil** | *private* | **Strongest — architectural** | Not a green claim | Runs in hardware enclaves (TEEs) with end-to-end encryption (EHBP), verifiable via remote attestation. Neither we nor Tinfoil can read your prompts or responses at inference time. Energy mix is not disclosed. | | **Tinfoil** | *private* | **Strongest — architectural** | Not a green claim | Runs in hardware enclaves (TEEs) with end-to-end encryption (EHBP), verifiable via remote attestation. Neither we nor Tinfoil can read your prompts or responses at inference time. Energy mix is not disclosed. |
| **GreenPT** | *green* | **Policy-based** | **Strongest — 100% renewable** | Standard (non-enclave) hosting in the EU; privacy rests on GreenPT's commitments and EU data rules, not on cryptography. Compute runs on 100% renewable energy. | | **GreenPT** | *green* | **Policy-based** | **Strongest — 100% renewable** | Standard (non-enclave) hosting in the EU; privacy rests on GreenPT's commitments and EU data rules, not on cryptography. Compute runs on 100% renewable energy. |
| **PublicAI** | *public* | Policy-based | Undisclosed | A gateway for **publicly developed, sovereign models** — open-weight models built by national/public programs rather than private labs. Privacy is policy-based (no enclave); energy mix is not disclosed. | | **Regolo** | *green* | Policy-based — **zero data retention** | **100% renewable** | EU-hosted (Italy, Seeweb) with a stated zero-data-retention policy: prompts are not stored or reused. Compute runs on 100% renewable energy. |
**Reading the gradations:** **Reading the gradations:**
- **Privacy:** *architectural* (Tinfoil) beats *policy-based* (GreenPT, PublicAI). An - **Privacy:** *architectural* (Tinfoil) beats *policy-based* (GreenPT,
enclave protects you even if the provider is compromised; a policy protects Regolo). An enclave protects you even if the provider is compromised; a
you only as far as the provider keeps its word. Both are better than a policy protects you only as far as the provider keeps its word. Both are
provider with neither. better than a provider with neither — and Regolo adds a written
- **Green energy:** *100% renewable* (GreenPT) beats *undisclosed* (Tinfoil, zero-data-retention commitment on top of its policy.
PublicAI). GreenPT reports its energy mix; the others do not, so we can't - **Green energy:** *100% renewable* (GreenPT, Regolo) beats *undisclosed*
claim greenness for them. (Tinfoil). GreenPT and Regolo both run on 100% renewable energy; Tinfoil's
- **Sovereignty:** *publicly developed* (PublicAI) is its own value — the models mix is not disclosed.
come from public/national AI programs, built as public goods rather than
proprietary products. It's a third axis, independent of privacy and energy.
Trade-offs are real: the most private option (Tinfoil) isn't the greenest, and Trade-offs are real: the most private option (Tinfoil) isn't the greenest, and
the greenest option (GreenPT) isn't the most private. The point of the co-op is the greenest option (GreenPT) isn't the most private. The point of the co-op is
@@ -61,30 +59,39 @@ per-token billing). The cached-input rate applies when a model reuses a
shared prompt prefix (multi-turn conversations, agent loops); most providers shared prompt prefix (multi-turn conversations, agent loops); most providers
charge a steep discount for it. Models with `—` don't offer a distinct charge a steep discount for it. Models with `—` don't offer a distinct
cache-read price. **Vision** means the model accepts images as input cache-read price. **Vision** means the model accepts images as input
(screenshots, photos, documents to reason about) — all models output text. (screenshots, photos, documents to reason about). **Image generation** is
None of our current models generate images. available via the chat's image feature (the 🎨 button) using
`regolo/qwen-image`.
The emoji in the model name marks its **value tier** (the same icons used in the chat picker): The emoji in the model name marks its **value tier** (the same icons used in the chat picker):
- 🔒 **Private** — Tinfoil: architecturally private (TEE enclaves) - 🔒 **Private** — Tinfoil: architecturally private (TEE enclaves)
- 🌱 **Green** — GreenPT: 100% renewable energy - 🌱 **Green** — GreenPT and Regolo: renewable-powered EU hosts (Regolo adds
- 📖 **Public** — PublicAI: publicly developed, sovereign open models a zero-data-retention commitment). The 🌱 emoji marks renewable-powered
providers, not a specific company.
| Model | Provider | Privacy | Green | Vision | Context | Pricing (in / out / cached) | Notes | | Model | Provider | Privacy | Green | Vision | Context | Pricing (in / out / cached) | Notes |
|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|
| `🌱 greenpt/deepseek-v4.1-flash` | GreenPT | policy | 100% renewable | ✅ | 1M | $0.22 / $1.10 / $0.011 | **Default.** DeepSeek's multimodal reasoning model, renewable energy; TEE twin below. | | `🌱 greenpt/deepseek-v4.1-flash` | GreenPT | policy | ✅ 100% renewable | ✅ | 1M | $0.22 / $1.10 / $0.011 | **Default.** DeepSeek's multimodal reasoning model, renewable energy; TEE twin below. |
| `🔒 tinfoil/deepseek-v4-1-flash` | Tinfoil | architectural | undisclosed | ✅ | 1M | $0.65 / $1.45 / $0.13 | TEE-protected version of the default; image input, tool calling, long docs/agents. | | `🔒 tinfoil/deepseek-v4-1-flash` | Tinfoil | architectural | undisclosed | ✅ | 1M | $0.65 / $1.45 / $0.13 | TEE-protected version of the default; image input, tool calling, long docs/agents. |
| `🔒 tinfoil/glm-5.3` | Tinfoil | architectural | undisclosed | — | 1M | $1.80 / $5.75 / $0.45 | GLM flagship, TEE-protected; strongest private-tier model for agentic coding and long-horizon tasks. | | `🔒 tinfoil/glm-5.3` | Tinfoil | architectural | undisclosed | — | 1M | $1.80 / $5.75 / $0.45 | GLM flagship, TEE-protected; strongest private-tier model for agentic coding and long-horizon tasks. |
| `🔒 tinfoil/gpt-oss-120b` | Tinfoil | architectural | undisclosed | — | 131K | $0.15 / $0.60 / — | Lightweight open-weight reasoning; cheapest private tier. | | `🔒 tinfoil/gpt-oss-120b` | Tinfoil | architectural | undisclosed | — | 131K | $0.15 / $0.60 / — | Lightweight open-weight reasoning; cheapest private tier. |
| `🌱 greenpt/glm-5.3-flash` | GreenPT | policy | 100% renewable | — | 1M | $0.11 / $0.44 / $0.022 | Fast GLM model, renewable energy. | | `🌱 greenpt/glm-5.3-flash` | GreenPT | policy | ✅ 100% renewable | — | 1M | $0.11 / $0.44 / $0.022 | Fast GLM model, renewable energy. |
| `🌱 greenpt/glm-5.3` | GreenPT | policy | 100% renewable | — | 1M | $1.10 / $4.40 / $0.275 | GLM flagship — strongest agentic model in the green tier. | | `🌱 greenpt/glm-5.3` | GreenPT | policy | ✅ 100% renewable | — | 1M | $1.10 / $4.40 / $0.275 | GLM flagship — strongest agentic model in the green tier. |
| `📖 publicai/apertus-v1.5-8b` | PublicAI | policy | undisclosed | ✅ | 262K | $0.10 / $0.20 / — | Fully open sovereign model, small/fast, image understanding. | | `🌱 regolo/apertus-70b` | Regolo | policy + ZDR | ✅ 100% renewable | ✅ | 65K | $0.46 / $2.44 / — | Fully open sovereign model (Apache-2.0), large/capable, image understanding. |
| `📖 publicai/apertus-v1.5-70b` | PublicAI | policy | undisclosed | ✅ | 262K | $0.82 / $2.92 / — | Fully open sovereign model, large/capable, image understanding. | | `🌱 regolo/qwen3.5-122b` | Regolo | policy + ZDR | ✅ 100% renewable | ✅ | 262K | $1.16 / $4.87 / — | Large vision+reasoning MoE (Qwen 3.5, 122B-A10B); 262K context. |
Vision is verified working through the co-op gateway (base64 image input via Vision is verified working through the co-op gateway (base64 image input via
`/v1/chat/completions`, standard OpenAI format). In the chat UI, just attach `/v1/chat/completions`, standard OpenAI format). In the chat UI, just attach
an image to your message while using a ✅ model. an image to your message while using a ✅ model.
**Reading the Privacy column:** *architectural* means the protection is built
into the infrastructure (TEE enclaves) — even the provider can't read your
prompts. *Policy* means the provider commits, by contract and policy, not to
store or reuse your data. *ZDR* (zero data retention) is a stronger policy:
the provider keeps no copy of prompts or outputs at all after the response is
delivered.
**Same model, two providers:** `glm-5.3` (Z.ai's GLM flagship) is offered both **Same model, two providers:** `glm-5.3` (Z.ai's GLM flagship) is offered both
on GreenPT (renewable, $1.10/$4.40) and on Tinfoil (TEE-protected, $1.80/$5.75) on GreenPT (renewable, $1.10/$4.40) and on Tinfoil (TEE-protected, $1.80/$5.75)
— pick the axis that matters to you. The fast `glm-5.3-flash` variant is — pick the axis that matters to you. The fast `glm-5.3-flash` variant is
@@ -131,6 +138,22 @@ curl https://gateway.inference.coop/v1/chat/completions \
]}]}' ]}]}'
``` ```
### Image generation
`🌱 regolo/qwen-image` (Regolo, EU-hosted, zero data retention) generates
images from a text prompt. In the chat, press the **Integrations** button
below the message box, choose **Image**, and describe what you want — the
generated image appears in the conversation. Via the API:
```bash
curl https://gateway.inference.coop/v1/images/generations \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{"model": "regolo/qwen-image", "prompt": "a watercolor painting of a mountain lake", "n": 1, "size": "512x512"}'
```
The response returns base64-encoded JPEG(s). Billed per pixel generated.
### About the Apertus models ### About the Apertus models
Apertus is the **Swiss AI Initiative's** open foundation model, built by a Apertus is the **Swiss AI Initiative's** open foundation model, built by a