Commit Graph
129 Commits
Author SHA1 Message Date
Ubuntu 250ca6e8f0 manifest: pin dockerImage to 20261026-9495daa (the image now running) 2026-10-26 16:45:22 +00:00
Ubuntu 9495daa701 newsletter: the unsubscribe PUT needs the email field — it was a silent 400
The end-to-end probe against the live listmonk caught this: PUT
/api/subscribers/{id} with {"lists": []} returns 400 {"message":"Invalid
email."}, leaving the subscriber on the list. It needs {"email": ..., "lists":
[]}. The failed request was only a log warning, so the reconcile's main job —
taking lapsed members off the Members list — has never worked; only the DELETE
branch did anything, which is the branch this series just removed.

Now both classes unsubscribe successfully and keep their record.
2026-10-26 16:42:10 +00:00
Ubuntu 7bb676eb68 newsletter: unsubscribe stale subscribers instead of deleting them; sweep: apply the documented fail-safe
Two findings from the retrospective review of 394cccfb..e24c272e (#34).

listmonk_reconcile() deleted subscribers with no members row outright. That
destroyed the subscriber's consent/unsubscribe history, and a stray test account
is indistinguishable from a real person who subscribed outside the portal. Both
classes now leave the list the same way — PUT {"lists": []} — and the record is
kept as a suppression marker; nothing is purged automatically. The summary log
line reports counts by reason instead of subscriber addresses. Subscriber
pagination also gains a short-page fallback so a missing `total` cannot truncate
the reconcile at page 1.

reconcile_memberships() called fetch_members() unguarded, so the documented
fail-safe — skip reconciliation rather than deactivate everyone missing from a
partial list — was unreachable: since fetch_members() now raises, the sweep
returned a 500 instead of {"status": "skipped"}. It now catches the failure and
returns reason "member_fetch_failed". The two webhook call sites are left
unguarded on purpose: a payment webhook should fail loudly so OC retries it, and
it self-heals.

Refs #34
2026-10-26 16:38:52 +00:00
Ubuntu ac0bdb6518 manifest: pin dockerImage to the deployed tag
The repo didn't record which image is live, so it couldn't answer "what is
deployed here?" — the tag lived only on the Cloudron app. Pin it to the image
deployed 2026-10-26 so the repo mirrors production, as our other repos do.

Consequence, same as librechat-custom: when the CLI runs from this directory this
manifest now wins over `cloudron update --image <tag>`, so a future release pins
the new tag here and commits it as part of the deploy.
2026-10-26 16:27:53 +00:00
Ubuntu 492019088e loomio: only rename auto-generated handles, never one a human chose
Testing the previous commit against the live Loomio user list showed it would
also have renamed a member whose handle was chosen by hand (a working name
would have become the sanitized OIDC uid) — the uid is domain-shaped, so the
sanitizer produced a different, wrong target. The function is scoped to
Loomio's own auto-generated handles: the email local part with
non-alphanumerics stripped plus a random suffix. Gate on that shape.

Verified against the live user list (70 users) before building: exactly one
handle changes — the member whose username fix 422'd on every sweep — no
computed target violates Loomio's rule, and the hand-chosen handle is left
alone.
2026-10-26 16:19:42 +00:00
inference-bot 178a4aa360 loomio: sanitize usernames instead of falling back to another invalid one
The username fix rejected a dot-containing OAuth uid and then substituted the
email local part, which carries the same dots — so Loomio answered 422
("Usernames must contain lower case letters, numbers, underscores, and internal
hyphens only") on every sweep, for the one member whose Cloudron username has a
dot. Normalize instead: disallowed characters become underscores, and leading
and trailing hyphens/underscores are stripped. Also log the Loomio user id
rather than the member's email.
2026-10-26 16:07:23 +00:00
inference-bot e24c272e2e org-link fix: INSERT bound 4 values to 3 placeholders (500 on every link); slug = org slug 2026-10-21 21:16:59 -06:00
inference-bot d8d80d9594 newsletter reconcile: Members list mirrors ACTIVE members
Root cause of test accounts receiving the newsletter: LISTMONK_API_USER was
set EMPTY in the portal env - env-present beats the code default, so every
listmonk_sync authenticated with an empty user and 403'd silently. Fixed both
the env (set to portal-sync) and the code (empty env falls back to default).

New: listmonk_reconcile() - the Members list must mirror ACTIVE members.
Stale subscribers are removed: members marked inactive are taken off the list
(record kept as suppression marker); addresses that are not members at all
(test/deleted accounts) are deleted outright. Wired as step 4 of the nightly
membership sweep + POST /admin/newsletter/reconcile for on-demand runs.
2026-10-21 16:32:36 -06:00
inference-bot e4da4da2c6 pagination fix: OC MemberCollection has NO cursor pageInfo — use offset+totalCount pagination (verified against the live API); the cursor query 400'd, taking the sweep and org endpoints down 2026-10-20 23:30:32 -06:00
inference-bot 42c664c076 OC member queries: cursor pagination via fetch_all_member_nodes() — members(limit:100) silently hid everyone past member #100 (same class as the Cloudron 25-per-page trap). Helper RAISES on any page failure so callers' fail-safes apply (never a partial list — the sweep would deactivate everyone missing from one); fetch_members returns [] on failure (sweep skips), fetch_org_backers propagates (sweep keeps linked accounts active), webhook payer lookup and /admin/org-link wrapped. 2026-10-20 23:26:18 -06:00
inference-bot fed4a7005e audit fixes: two latent NameErrors in the org code — webhook org branch referenced undefined org_name (crashed on an unlinked org's first payment), org-links GET referenced undefined name (crashed when a linked org's dues show inactive) 2026-10-20 23:21:51 -06:00
inference-bot d87cbf9650 admin overview: expose matrix_mxid (dashboard-set external handle) per member 2026-10-20 23:01:24 -06:00
inference-bot dcffbb1b98 org-links GET: remaining name-column reference 2026-10-20 22:57:40 -06:00
inference-bot 394cccfbcb org links: members table has no name column — drop it from org SQL/unpackings (names come from OC/Cloudron) 2026-10-20 22:55:55 -06:00
inference-bot 72614f8f19 Organizational memberships: OC org contributors (type ORGANIZATION) never expose an email, so all three automated paths missed them (webhook email lookup, nightly sweep, /join). Add: members.org_slug link column + fetch_org_backers() (org BACKER/Membership nodes); sweep keeps linked accounts active while the org's dues are active and deactivates on lapse (fail-safe keeps active if the org fetch errors); webhook re-activates linked accounts on org dues and emails the operator for unlinked orgs; POST /admin/org-link (link + full provision incl. Cloudron signup link) and GET /admin/org-links (live dues status); admin overview gains an 'org' field. 2026-10-20 22:45:37 -06:00
inference-bot 5425efee1f overview: normalize float-residue spend (e.g. -5.55e-17 after cycle reset) to 0 so the panel never renders -0.00 2026-10-19 11:42:58 -06:00
inference-bot fd13bc6ea2 broker/matrix-mxid GET: local_mxid_for_email was async-def but never awaited — response contained a coroutine and FastAPI 500'd ('coroutine object is not iterable'), so the dashboard silently showed no registered Matrix ID. Make it a plain sync def (blocking urllib). 2026-10-19 10:47:49 -06:00
inference-bot 97ebe69553 portal: /admin/librechat/keys — dedicated-token feed of member chat keys for the sandbox's key auto-load 2026-10-18 23:15:38 -06:00
inference-bot 7f04920327 broker: retire the old LiteLLM key before re-creating a same-name key
LiteLLM requires unique key aliases, so re-creating a key with an existing
(email, name) pair 400s ('alias already exists') — breaking key rotation
from the dashboard. The stored LiteLLM hash lets us retire the old key
first; the ON CONFLICT upsert then tracks the new key.

Surfaced by the LibreChat sandbox work: the portal chat-key rotation for
an SSO member failed with exactly this 400.
2026-10-17 18:00:49 -06:00
Inferencebot 003689868f Remove PublicAI; Regolo becomes the Apertus provider; emoji = feature tier (🌱 green for greenpt+regolo), qwen-image via image feature only 2026-10-16 10:48:10 -06:00
Inferencebot ced82b09d0 portal: filter image-gen models from chat picker by name (gateway strips mode from /v1/models) 2026-10-16 10:26:04 -06:00
Inferencebot 5091c9e644 portal: add Regolo models to picker (Apertus 70B, Qwen 3.5 122B, Qwen Image); exclude image-gen from chat list 2026-10-16 10:24:27 -06:00
Inferencebot 106b563748 sync: invite members to MATRIX_EXTRA_ROOMS too (restricted rooms aren't federation-discoverable until joined) 2026-10-14 16:40:35 -06:00
Inferencebot 24f0c0f745 fix: import urllib.parse on the retire path (NameError broke the sweep) 2026-10-14 10:55:30 -06:00
Inferencebot b2689d9cd1 Matrix sync: revoke stale local-account invites too (directory hygiene + one-identity completeness) 2026-10-14 10:54:24 -06:00
Inferencebot b342ca0ee3 README: document membership sweep + rag refresh scheduled tasks 2026-10-12 19:33:29 -06:00
Inferencebot 49638ba36a rag_refresh: retry attach up to 3x (transient 400 while file processes) 2026-10-12 19:29:17 -06:00
Inferencebot 49376813ae rag_refresh: parse OWUI files-list {items:[...]} shape; unfiltered list + client-side name filter 2026-10-12 19:26:06 -06:00
Inferencebot bca11a1657 Move docs-RAG refresh into the portal container (Gitea raw API + scheduler addon, 3:30am daily) 2026-10-12 19:23:00 -06:00
Inferencebot cb04958460 scheduler addon belongs under addons (manifest schema), not top level 2026-10-12 18:23:50 -06:00
Inferencebot b58929076e Restore nightly membership sweep scheduler (3am daily) — was silently missing from manifest 2026-10-12 18:21:27 -06:00
Inferencebot 81b640ba74 matrix-mxid: return invite_sent so the dashboard can confirm the invite is on its way 2026-10-12 09:01:22 -06:00
Inferencebot e56d0456bb Chat models: silent auto-RAG via legacy FC (no knowledge tool, no narration) 2026-10-10 13:41:20 -06:00
Inferencebot 92e7ddec05 Matrix sync: retire local @username:inference.coop accounts when a member sets a dashboard MXID (one identity per member) 2026-10-10 13:29:26 -06:00
Inferencebot 05feed5f24 Strengthen docs-KB steering: firm negative instruction after soft hint proved insufficient 2026-10-09 22:44:00 -06:00
Inferencebot 2eab2abb0d Overview: separate admin/operator accounts into their own category (excluded from member counts) 2026-10-08 15:08:21 -06:00
Inferencebot a7a283d552 Steer docs-KB tool usage: params.system hint to query only co-op-relevant questions 2026-10-08 09:38:05 -06:00
Inferencebot 32420f60f4 Friendly names: tinfoil/glm-5.3 (replaces deprecated flash variant) 2026-10-07 22:07:44 -06:00
Inferencebot 1a227642d9 Attach co-op docs knowledge collection to every model (auto-RAG, no KB browsing wandering) 2026-10-07 10:52:08 -06:00
Inferencebot e18cd4b703 Provisioning: add new members to Open WebUI docs-RAG access group at signup 2026-10-07 10:38:32 -06:00
Inferencebot 2a5277007e Model list: also filter embedding models out of the chat picker 2026-10-07 09:44:15 -06:00
Inferencebot 3d258e9a2d Loomio sync: only invite activated members (avoid invite email before account setup) 2026-10-07 09:19:24 -06:00
inference-bot 38005127cb Expose credits_remaining (purchased minus cycle overspend) in broker usage + admin overview 2026-10-03 13:59:29 -06:00
inference-bot 052a109040 Fix credit model: allowance is a floor, credits add on top (max_budget = allowance + credits, not reduced by cycle overspend) 2026-10-03 13:06:02 -06:00
inference-bot 563881d63c Matrix: member-set extra MXID (matrix_mxid column + broker get/set + sync prefers it) 2026-10-03 10:48:13 -06:00
inference-bot 3cdc250d52 Chat model picker: value-tier emoji + friendly names in /v1/models (🔒 private / 🌱 green / 📖 public), id stays canonical 2026-10-02 22:30:11 -06:00
inference-bot 1fe0e47802 Update code-comment example (green-r -> glm-5.3-flash) 2026-10-02 22:04:54 -06:00
inference-bot 29823e87d5 Matrix mxid lookup: paginate Cloudron users API (25/page) — was missing page 2+ 2026-10-02 13:03:14 -06:00
inference-bot f86ead8653 Matrix invite: honor 429 retry_after_ms (3 attempts) 2026-10-02 12:29:41 -06:00
inference-bot 07a1f2ad4e Fix Cloudron users API response shape ({users: [...]}) 2026-10-02 12:28:39 -06:00