--- kind: epic slug: model-provider-registry title: Model provider registry and per-role routing plan_slug: automation-foundation status: done priority: P1 tenant_id: global cursor_epic_id: null updated_at: "2026-07-03" agent_prompt: | Epic: model provider registry (docs/adr-model-routing.md). Server-only change — no UI component library inventing; reuse components/ui/. Admin-only mutations. Filter every DB query by workspace_id. One task per session; claim_task first. --- # Epic objective Deliver the workspace-scoped **model provider registry** and **role → alias routing** described in [docs/adr-model-routing.md](../../../docs/adr-model-routing.md): Drizzle schema, zod types in `packages/shared`, `resolveModel()`, tRPC CRUD + `testProvider`, Settings UI, and `agent_runs` model metadata on completion. This epic is the first shipped piece of the automation-foundation plan and unblocks future orchestrator/worker work. ## In scope / out of scope **In scope** - Tables `model_providers`, `role_model_routes`. - Pure resolver + unit tests. - tRPC router (workspace admin). - Settings pages: Providers, Role routing. - Seed/default routes for nine L2 roles + `gate-copilot` + `chat-default`. - `complete_task` optional model logging fields. - `.env.example` env var documentation. **Out of scope** - Orchestrator dispatch (consumes resolver later). - Worker inference loop. - Parsing `model_policy` from `.convoys/*.md` files (orchestrator reads later). - Billing/budget enforcement. ## Related tasks | Task | Link | |------|------| | Shared schemas and resolveModel | `./Task-shared-schemas-resolve-model.md` | | DB schema and migration | `./Task-db-model-providers-migration.md` | | tRPC models router | `./Task-trpc-models-router.md` | | Settings — providers UI | `./Task-settings-ai-providers-ui.md` | | Settings — role routing UI | `./Task-settings-role-routing-ui.md` | | agent_runs model fields + MCP | `./Task-agent-runs-model-logging.md` | ## Dependencies - Depends on: existing auth + workspace admin patterns in `apps/web`. - Blocks: orchestrator epic (needs `resolveModel`), worker epic (needs `ResolvedModel`). ## Acceptance criteria - [ ] Admin can create `claude-planning` (anthropic) and `qwen-coder` (openai_compatible + base URL) in a workspace. - [ ] Admin can map `role-implementer` → `qwen-coder`, `role-architect` → `claude-planning`. - [ ] `testProvider` returns success/failure without exposing API keys. - [ ] `resolveModel()` unit tests cover override order and missing-alias error. - [ ] At least one task in this epic completed via `claim_task` → `complete_task` with model metadata. ## Proposed timeline | Phase | Window | Notes | |-------|--------|-------| | Schema + resolver | Session 1–2 | Tasks: shared schemas, migration | | API | Session 3 | tRPC router | | UI | Session 4–5 | Both settings pages | | Logging | Session 6 | agent_runs + MCP | ## Pipeline / convoy mapping When running via agent-pipeline, architect briefs should align to tasks: | Brief # | Task slug | |---------|-----------| | 1 | `shared-schemas-resolve-model` | | 2 | `db-model-providers-migration` | | 3 | `trpc-models-router` | | 4 | `settings-ai-providers-ui` | | 5 | `settings-role-routing-ui` | | 6 | `agent-runs-model-logging` | Briefs 1–2 serial (schema depends on types); 4–5 can fan out after brief 3 if `files:` are disjoint.