feat(server): Prism MCP toolkit, spawn_thread(role), role kits and provider snapshot - #22
Merged
Merged
Conversation
Role kits (instructions, runtime mode, skills, thread-tool scope) and ordered model preferences for the six Prism roles, stored as the project-scoped server setting prismRoles, with a per-role patch. Adds the GET /api/prism/snapshot response schema for the router. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…shot endpoint (#19) Adds prism_submit, prism_status, prism_questions and prism_answer, which run the installed Model Router CLI with the calling thread as the T3 planner and a server URL plus an orchestration-scoped token supplied by the server. spawn_thread takes a Prism role, applies its kit and first eligible preferred model, and each role's thread-tool scope is enforced. GET /api/prism/snapshot returns providers, models, usage windows with resetsAt and the role kits resolved for a project. OpenCode usage now refreshes on the provider health interval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Each role keeps an ordered list of {instanceId, model, effort} per lane
(easy, medium, hard): the first entry is the primary choice, the rest are
fallbacks, and one model at another effort is its own entry. Adds
PrismLane (default medium) and per-lane patching. The snapshot carries
the same structure through PrismRoleKits.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…it (#19) spawn_thread takes an optional lane (default medium) and walks that role's lane list, primary first then fallbacks. prism_submit takes easy, medium or hard and maps them onto the installed router's small, default and hard lanes. PRISM_LANES stays module-local for knip; PrismLane.literals lists the lanes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lukemaj
added a commit
that referenced
this pull request
Sep 27, 2026
…ovider snapshot (#22) * feat(contracts): Prism role kits and provider snapshot schema (#19) Role kits (instructions, runtime mode, skills, thread-tool scope) and ordered model preferences for the six Prism roles, stored as the project-scoped server setting prismRoles, with a per-role patch. Adds the GET /api/prism/snapshot response schema for the router. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): Prism MCP toolkit, spawn_thread(role) and provider snapshot endpoint (#19) Adds prism_submit, prism_status, prism_questions and prism_answer, which run the installed Model Router CLI with the calling thread as the T3 planner and a server URL plus an orchestration-scoped token supplied by the server. spawn_thread takes a Prism role, applies its kit and first eligible preferred model, and each role's thread-tool scope is enforced. GET /api/prism/snapshot returns providers, models, usage windows with resetsAt and the role kits resolved for a project. OpenCode usage now refreshes on the provider health interval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: drop unused Prism exports flagged by knip (#19) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(contracts): Prism model lists per role and lane (#19) Each role keeps an ordered list of {instanceId, model, effort} per lane (easy, medium, hard): the first entry is the primary choice, the rest are fallbacks, and one model at another effort is its own entry. Adds PrismLane (default medium) and per-lane patching. The snapshot carries the same structure through PrismRoleKits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): pick role models by lane in spawn_thread and prism_submit (#19) spawn_thread takes an optional lane (default medium) and walks that role's lane list, primary first then fallbacks. prism_submit takes easy, medium or hard and maps them onto the installed router's small, default and hard lanes. PRISM_LANES stays module-local for knip; PrismLane.literals lists the lanes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lukemaj
added a commit
that referenced
this pull request
Sep 27, 2026
…ovider snapshot (#22) * feat(contracts): Prism role kits and provider snapshot schema (#19) Role kits (instructions, runtime mode, skills, thread-tool scope) and ordered model preferences for the six Prism roles, stored as the project-scoped server setting prismRoles, with a per-role patch. Adds the GET /api/prism/snapshot response schema for the router. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): Prism MCP toolkit, spawn_thread(role) and provider snapshot endpoint (#19) Adds prism_submit, prism_status, prism_questions and prism_answer, which run the installed Model Router CLI with the calling thread as the T3 planner and a server URL plus an orchestration-scoped token supplied by the server. spawn_thread takes a Prism role, applies its kit and first eligible preferred model, and each role's thread-tool scope is enforced. GET /api/prism/snapshot returns providers, models, usage windows with resetsAt and the role kits resolved for a project. OpenCode usage now refreshes on the provider health interval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: drop unused Prism exports flagged by knip (#19) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(contracts): Prism model lists per role and lane (#19) Each role keeps an ordered list of {instanceId, model, effort} per lane (easy, medium, hard): the first entry is the primary choice, the rest are fallbacks, and one model at another effort is its own entry. Adds PrismLane (default medium) and per-lane patching. The snapshot carries the same structure through PrismRoleKits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): pick role models by lane in spawn_thread and prism_submit (#19) spawn_thread takes an optional lane (default medium) and walks that role's lane list, primary first then fallbacks. prism_submit takes easy, medium or hard and maps them onto the installed router's small, default and hard lanes. PRISM_LANES stays module-local for knip; PrismLane.literals lists the lanes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lukemaj
added a commit
that referenced
this pull request
Sep 27, 2026
…ovider snapshot (#22) * feat(contracts): Prism role kits and provider snapshot schema (#19) Role kits (instructions, runtime mode, skills, thread-tool scope) and ordered model preferences for the six Prism roles, stored as the project-scoped server setting prismRoles, with a per-role patch. Adds the GET /api/prism/snapshot response schema for the router. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): Prism MCP toolkit, spawn_thread(role) and provider snapshot endpoint (#19) Adds prism_submit, prism_status, prism_questions and prism_answer, which run the installed Model Router CLI with the calling thread as the T3 planner and a server URL plus an orchestration-scoped token supplied by the server. spawn_thread takes a Prism role, applies its kit and first eligible preferred model, and each role's thread-tool scope is enforced. GET /api/prism/snapshot returns providers, models, usage windows with resetsAt and the role kits resolved for a project. OpenCode usage now refreshes on the provider health interval. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: drop unused Prism exports flagged by knip (#19) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(contracts): Prism model lists per role and lane (#19) Each role keeps an ordered list of {instanceId, model, effort} per lane (easy, medium, hard): the first entry is the primary choice, the rest are fallbacks, and one model at another effort is its own entry. Adds PrismLane (default medium) and per-lane patching. The snapshot carries the same structure through PrismRoleKits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(server): pick role models by lane in spawn_thread and prism_submit (#19) spawn_thread takes an optional lane (default medium) and walks that role's lane list, primary first then fallbacks. prism_submit takes easy, medium or hard and maps them onto the installed router's small, default and hard lanes. PRISM_LANES stays module-local for knip; PrismLane.literals lists the lanes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #19. Stream A of toolboxmd/model-router#115.
Problem
Planners reach Prism (Model Router) through a CLI and have to find a T3 token themselves,
spawn_threadcannot start roles, role preferences have no home, and the router has no way to read Chromeria's providers, models and limits.Change
packages/contracts/src/prism.ts,prismSnapshot.ts; pushed early as 2c7afaa, lanes as 9d22ee3, for streams B and C): six roles with kits (instructions, runtime mode, skills, thread-tool scope) and, per lane (easy,medium,hard), an ordered list of{instanceId, model, effort?}: first entry primary, the rest fallbacks, one model at another effort is its own entry. Stored as the project-scoped server settingprismRoles, with a per-role, per-lane patch; the snapshot response schema carries the same structure. No capability tags.toolkits/prism/):prism_submit,prism_status,prism_questions,prism_answerrun the newest installedmodel-routerCLI (PRISM_ROUTER_BINoverrides) with--planner-t3-thread= the calling thread, the server's own URL and a fresh token scoped toorchestration:read+orchestration:operate(30-day TTL, never admin).laneiseasy/medium/hard, mapped to the installed router'ssmall/default/harduntil the router accepts the new names. Planner threads only. Descriptions say when to useprism_submitversusspawn_thread(role).spawn_thread(role, lane?)(lane defaults tomedium): applies the role's kit: instructions and skills lead the first message, runtime mode, and the first entry of that lane's list that is enabled in Providers, offered by the instance and not at a 100 % usage window before itsresetsAt, unless a model or instance is named. A role with preferences but no eligible model refuses with the reasons (no silent substitution); a role without preferences uses this thread's model. The role is encoded in the child id (sub.<parent>.<role>-<rand>), so it survives restarts.projectscope plus Prism tools; dispatcher read/list/message its own children; reviewer read and list withprojectscope; worker, correction, recovery none. Children without a role prefix (direct spawns, today's router threads) keep their previous tools and get no Prism tools.GET /api/prism/snapshot[?projectId=](bearer withorchestration:read): each provider instance with enabled flag, status, models (capabilities carry the options) and usage windows withresetsAt, plus the role kits resolved for the project.refreshOnInterval: true).docs/fork.md:contracts/src/index.ts,contracts/src/settings.ts,McpHttpServer.ts, threadstools.ts/handlers.ts,OpenCodeDriver.ts.Proof
roles.test.ts(role from id, tool scope per role, eligibility, usage blocking, first message),prism/handlers.test.ts(submit argv, router output and errors, state dir, newest-version discovery),snapshotRoute.test.ts,contracts/prism.test.ts; threads, prism, snapshot andMcpHttpServersuites 58/58;sharedproject settings 49/49; web settings 454/454; driver suites 95/95 in the documented host-neutral env (3CodexDrivertests fail only with Homebrew on PATH, asdocs/fork.mddescribes).vp lint,vp fmt --check,scripts/fork-check.sh: pass.hard= [opencode/muse high (instance disabled), claude-haiku-4-5 high] started onclaude-haiku-4-5effort high (fallback); reviewer without lane started on themediumprimaryclaude-sonnet-5effort low;prism_submitlaneeasyreached the router as--lane smalland persistedimplementation_small; recovery reported its own empty lanes in the snapshot.T3CODE_HOME=/tmp/prism-live/home, port 38917, router state in/tmp, router wrapped to force--no-start): unauthenticated snapshot 401; with token 200 with real Codex and Claude windows andresetsAt; settings edits appear in the snapshot. A Claude Haiku 4.5 planner thread called every tool:spawn_thread(role: reviewer)createdsub.live-planner.reviewer-…on the reviewer's preferred model (claude-haiku-4-5, effort low) with the kit's instructions and skills first; that reviewer'slist_threads(scope: project)worked and itsspawn_threadwas refused withThis role may only read threads.;spawn_thread(role: worker)refused withNo eligible model for this role: opencode/opencode/muse (instance disabled).;prism_submitpersisted a job withplanner_t3_thread,planner_harness: t3, lane small and the server URL, the router received a token scoped toorchestration:read/orchestration:operate;prism_statusreturnedpending;prism_questionsreturned none.Not covered
providerModelPreferences), so the server cannot see it; eligibility uses enabled instances and offered models.BackgroundPolicy).dispatcher-…/worker-…to get role scopes (stream B).Model and harness: Claude Opus 5.5 in Claude Code.
🤖 Generated with Claude Code