feat(admin): unlimited AI model waterfall with full Claude + OpenAI catalog, per-entry effort and fast mode - #388
Conversation
…atalog The AI workflow model order was capped at 3 entries from a closed 3-model union. The waterfall is now unlimited (bounded only by uniqueness against the catalog) and the catalog covers every current Claude model (Fable 5, Opus 5/4.8/4.7/4.6, Sonnet 5/4.6, Haiku 4.5) and OpenAI model (GPT-5.6 Sol/Terra/Luna through GPT-4o, codex and o-series included), each addable with a per-entry reasoning-effort tier and normal/fast mode. - Entries are composed option ids `<model>[:<effort>][:fast]`, validated per model (efforts a model supports; fast only where the provider sells a fast lane: Anthropic fast mode on Opus 5/4.8, OpenAI priority processing). Storage stays a string array, so the persisted key, endpoint shape, and legacy ids remain compatible. - Reads are now forgiving per entry: unknown ids are dropped instead of collapsing the whole stored order; writes stay strict. - New provider-aware resolvers: direct Anthropic clients use the first Anthropic-capable entry, OpenAI clients the first OpenAI entry, each stopping at the `default` sentinel. - Lopu musings and Claude moderation apply the resolved entry's model and effort (`output_config.effort`); musings also honor fast mode (beta) and OpenAI `reasoning_effort` + priority tier, with a bare retry so a rejected knob never kills the provider. - Admin editor: reorderable unlimited list plus a model/effort/speed picker replacing the three fixed add buttons; per-model gating of the effort and speed selects; duplicate-entry guard. - Docs, TESTING.md checklists, and the AI model routing contract updated; unit suites extended (settings 15, lopu 5, moderation 52 all green; typecheck adds no new errors over baseline). The github-actions control plane still allowlists the legacy trio and fails closed to ["default"] for any new entry; widening that closed grammar is a separate follow-up on the github-actions branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🧹 Develop S3 preview removedThe PR-specific alias and every workflow-created develop deployment were removed when this PR closed. The ordinary generated Vercel Preview remains available on the shared development runtime. |
…fall Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ull Claude + OpenAI catalog, per-entry effort and fast mode
|
|
…ull Claude + OpenAI catalog, per-entry effort and fast mode
|
🤝 Merged Conflicted files:
Please review the merge commit before relying on it. |
…ull Claude + OpenAI catalog, per-entry effort and fast mode
…d conflicts) Conflicted paths: .github/workflows/all-branch.yml, graphify-out/GRAPH_REPORT.md, graphify-out/graph.json, graphify-out/manifest.json, remix/CHANGELOG.md Resolved by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/32730712296 Co-Authored-By: Claude <noreply@anthropic.com>
`graphify extract` with LLM semantic extraction (graphify 0.9.4, claude-cli backend); unchanged content served from the tracked semantic cache. Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/32730712296
…ull Claude + OpenAI catalog, per-entry effort and fast mode # Conflicts: # graphify-out/cache/semantic/b72c0b5bfbc6a13338a54cbeb0197715411e8d71d4021d5e53e2d4a565d205bc.json # graphify-out/cache/semantic/c4d90b648c3b7e1d2f9f5b3fabbd8999abf03f2e3bce2989672675eae96f380f.json
🦄 Lopu review — PR #388Reviewed 🔴
|
Lopu repository reviewLopu reviewed this PR against develop as Thingtime's principal PR and repository manager. Using Claude Opus 5. The PR head moved during review, so Lopu preserved the newer branch and did not overwrite it. Lopu review — PR #388Unlimited AI model waterfall with the full Claude + OpenAI catalog, per-entry effort and fast mode
What I comparedFull head against its target base (16 files, +1030/−204): the composed-id core Dispatching check — stale, not a defect
CodeQL on the exact reviewed head CodeQL dispositionThe trusted snapshot ( Findings1. Blocking (fixed) — an Admin effort tier permanently stalls image moderation
This PR newly makes the classifier send That is materially worse here than for musings. Fixed by mirroring the pattern this PR already established for musings:
Pinned in 2. Stale docs (fixed) — the control-plane limitation is resolved, not pendingThe PR body, PR #391 merged into 3. Overstated bound (comment fixed) — the route body cap rationale
Verified, no change needed
Noted, deliberately not changed
Validation runFrom the PR worktree at the live head
Files changed in this review
AssessmentStrong PR. The composed-id grammar is well designed — forgiving reads, strict The one remaining defect was the PR's own round-1 lesson not being carried |
…ull Claude + OpenAI catalog, per-entry effort and fast mode # Conflicts: # graphify-out/cache/semantic/b72c0b5bfbc6a13338a54cbeb0197715411e8d71d4021d5e53e2d4a565d205bc.json # graphify-out/cache/semantic/c4d90b648c3b7e1d2f9f5b3fabbd8999abf03f2e3bce2989672675eae96f380f.json
…ull Claude + OpenAI catalog, per-entry effort and fast mode # Conflicts: # graphify-out/cache/semantic/b72c0b5bfbc6a13338a54cbeb0197715411e8d71d4021d5e53e2d4a565d205bc.json # graphify-out/cache/semantic/c4d90b648c3b7e1d2f9f5b3fabbd8999abf03f2e3bce2989672675eae96f380f.json
…ull Claude + OpenAI catalog, per-entry effort and fast mode # Conflicts: # graphify-out/cache/semantic/b72c0b5bfbc6a13338a54cbeb0197715411e8d71d4021d5e53e2d4a565d205bc.json # graphify-out/cache/semantic/c4d90b648c3b7e1d2f9f5b3fabbd8999abf03f2e3bce2989672675eae96f380f.json
…ull Claude + OpenAI catalog, per-entry effort and fast mode
|
🤝 Merged No AI resolution was needed by merge time; the branch was updated with a plain merge commit.
Please review the merge commit before relying on it. |
# Conflicts: # graphify-out/GRAPH_REPORT.md # graphify-out/cache/semantic/0075b70deb734762e680e31448d5d7ae4b722ff8da30f12d46758df11755b4ed.json # graphify-out/cache/semantic/de8ff3e2ff6a82e160a628793b1662887bf981d5c49910aa565b93b280999024.json # graphify-out/graph.json # graphify-out/manifest.json
Structural `graphify update` followed by LLM semantic `graphify extract` (graphify 0.9.4, claude-cli backend); unchanged content served from the tracked semantic cache. Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/33017058364
🦄 Lopu review — PR #388 (round 2)Reviewed
🔧 The control-plane follow-up is done — and it was worse than "preference ignored"Round 1 called the fail-closed behaviour "real and safe" and deferred it. Safe, yes, but All three consumers validate with a single whole-array Replaying your own live-browser order against the real workflow script: That root cause lives in The interesting part for you: I could not fix it by listing the eight Claude models. 🐛 One gap left on this branch: the bare retry misses the case it was added for
So Suggestion: treat Two smaller ones, both optional:
🔒 CodeQL — 16 open alerts, none from this diffInspected all 16. Five fixed here, eleven dispositioned with evidence. Nothing real was The one worth your attention is genuinely serious and unrelated to this PR: Also fixed: The eleven dispositions are React keys / DOM ids with no security context, a local Raycast Verdict: ship it. The strict-write / forgiving-read asymmetry is the right asymmetry, 🦄 Posted by Lopu, Thingtime's repository steward. |
…d; derive picker providers Review round-2 follow-ups: a decorated musing attempt that completes with zero text deltas (reasoning ate the output budget) now falls through to the bare retry on the SAME provider instead of silently skipping the admin's preference; the waterfall choices read is hoisted above the provider loop (one durable read per musing); the Admin picker's provider groups derive from the catalog so a future provider needs no editor edit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Round-2 follow-ups applied in 523fc3b: the starved-decorated-stream case now retries bare on the same provider before falling through (both providers, symmetric with the throw path — no retry after first emitted delta); the waterfall choices read is hoisted above the provider loop (one durable read per musing); PICKER_PROVIDERS now derives from the catalog. Suites green: settings 15, lopu 5, routing contract OK. |
… time machine The Set-based merge guard was semantically sound but CodeQL's barrier recognition wants literal key comparisons, so both assignment sites kept their medium alerts — same guard, spelled as === comparisons. The live timeline uuid still used Math.random (only the dead debugUuid lines were fixed earlier); now crypto.randomUUID(), clearing the remaining high alert. test:autosave 23/23, test:persist 11/11. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ith zero alerts) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🦄 Lopu review — PR #388 (round 3)Thanks @lopugit — I verified all three round-2 follow-ups on ✅ Round-2 follow-ups verifiedI drove the real
Your "symmetric with the throw path" is exact — the guard is byte-identical in both providers, I also checked the thing the hoist could have broken: the read now sits outside the provider ✅
|
|
Round-3 ack: pulled the two new routing-contract pins (fall-through count + hoisted read) — self-test passes locally. On the SSE harness: yes please, land it as |
…nfiguration not found', zero alerts on head) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…del-selection-0281b1 # Conflicts: # graphify-out/GRAPH_REPORT.md # graphify-out/manifest.json
…del-selection-0281b1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…del-selection-0281b1 # Conflicts: # graphify-out/cache/semantic-cas/v1/129c97e7142fd9d3c042ef3512fd1b648e78a05516b07de0040404a84d04b16f/bb576b10b5ab75d14925375c67018ae316c2ecc3d5787313afd3ea9e7d8aa14d.json # graphify-out/cache/semantic-cas/v1/c37511213916202466aaf153b4bd78e57e8f7d25a26451c61e9beb6c5e13f182/a7a65bdd76faae60f21944b6c0949dc2990f63381381271e6414042331988daa.json # graphify-out/snapshots/v1/a9ed916a43e75213953a479a7e7991d01541b9c1e0b1785e72d7ddcbd3b30d09/49a0724cbf70b9a56bd398b7c85302d27bea176c16b0b37652d008e5aab1452d/graph.json
|
Implemented the approved The harness runs the real Anthropic and OpenAI SDKs against an in-process SSE server and mocks only the Mongo-backed waterfall read. It now proves:
Validation on the exact pushed head:
|
🦄 Lopu review — PR #388 (round 5)Thanks @lopugit — This round I widened the lens past the musing path and found one real defect left in the other 🔴 An Admin effort tier permanently stalls image moderationRound 1 established the mechanic for musings: both providers bill internal reasoning against the const response = await client.messages.create({
model: choice.model,
...(effort ? { output_config: { effort } } : {}),
max_tokens: 2048, // ← the verdict AND the reasoning share this
...
});Put This is worse than the musing case, and that is the part worth pausing on. A starved musing Fix — mirrors the pattern this PR already established, rather than inventing a second one:
Pinned in 📄 The control-plane warning is now stale — it says the opposite of the truth
#391 merged into 📏 Bounds measured rather than estimatedThe route comment justified
Off by ~10x. The cap is admin-authenticated and harmless, so I kept 64 KB as growth headroom and ✅ Also checked, nothing found
🟡 One heads-up for local runs
Note on the head: my worktree was cut at Validated on Assessment: I'd merge this once the moderation budget lands. The composed-id grammar is 🦄 Lopu · autonomous PR review · head |
|
✅ Promoted to An earlier run stood aside on this PR; that verdict no longer applies. |
|
✅ Promotion #441 has verified source lineage at current |
|
🚀 Promotion PR for |
What
The Admin → System "AI workflow model order" was capped at 3 entries from a closed 3-model list. This PR makes the waterfall unlimited and expands the catalog to every current Claude and OpenAI model, each addable with a per-entry reasoning-effort tier and normal/fast mode.
Catalog (33 base models)
low…max,xhighonly where it exists); fast mode on Opus 5 / Opus 4.8 (Anthropic fast-mode research preview).none…max+ultra), GPT-5.5, GPT-5.4 (+Mini), GPT-5.3 Codex (+Spark), GPT-5.2 (+Pro), GPT-5.1 (+Codex/Mini/Max), GPT-5 (+Mini/Nano), o3 (+Pro), o4-mini, GPT-4.1 family, GPT-4o family — "fast" maps to OpenAI priority processing where sold.Design
<model>[:<effort>][:fast](e.g.claude-opus-5:high:fast,gpt-5.6-sol:ultra). Storage stays a plain string array — the persisted key, endpoint shape, and the legacy bare ids (default,claude-fable-5,claude-opus-5) remain fully compatible. Segment order tolerated on parse, canonicalized on store.defaultrequired); reads are now forgiving per entry — an unknown id from a newer deploy is dropped instead of collapsing the whole stored order to["default"].defaultsentinel (defaultstill means "that client's provider-valid default model").output_config.effort+ fast mode (beta) on the Claude side and model +reasoning_effort+service_tier: priorityon the OpenAI side, with a one-shot bare retry so a knob the provider rejects never kills the whole provider. Claude moderation applies model + effort (fast deliberately ignored for a background classifier).ai-model-routing-contract.mjspins the new shapes.Provider · Effort · Fast mode.The
github-actionsbranch workflow still validates against the closed legacy trio and fails closed to["default"](with a warning) for any waterfall containing new/composed entries — admin preference is safely ignored, never misapplied. Widening that closed grammar (parse composed ids, filter to Claude-capable entries, keep the injection-safe charset) is a deliberate separate change on thegithub-actionscontrol plane.Testing
test:settings15 ✓,test:lopu5 ✓,test:moderation52 ✓,test:ai-model-routing✓; typecheck ratchet: no new errors from changed files (the +7 drift is pre-existing in unrelated baseline files).High effort · Fast, GPT-5.6 SolUltra, GPT-5.3 CodexExtra-high(no speed select, correctly), Claude Haiku 4.5 (no effort/speed selects, correctly); 5 entries total (beyond the old cap); reordered Opus 5 to Primary; saved; GET returns['claude-opus-5:high:fast','default','gpt-5.6-sol:ultra','gpt-5.3-codex:xhigh','claude-haiku-4-5']; full reload paints the saved order. Desktop + mobile (375px) verified top-to-bottom of the section — no clipping/overflow/horizontal scroll./api/v1/lopu/musingsmoke on the dev stack streams (fallback mode, no keys) — the rewritten module loads in the real server.🤖 Generated with Claude Code