feat(frontend): Add LLM registry admin UI - #12468
Conversation
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
43a98fb to
ca4843b
Compare
There was a problem hiding this comment.
All 8 specialists have reported. Let me compile the verdict.
PR #12468 — "fix(frontend): Add type definitions and update component imports"
Author: unknown | Requested by: ntindle | Files: 137 changed (+15,068/−7,840)
Key files: server/v2/llm/ (new), data/llm_registry/ (new), admin/llms/ (new frontend), blocks/github/ (consolidation + deletions), copilot/ (cleanup)
🎯 Verdict: BLOCK
What This PR Does
This PR is significantly larger than its title suggests. It's actually Part 5 of a 5-part stacked PR series that introduces a complete LLM Registry system (Prisma schema, backend CRUD API, admin dashboard UI). Alongside that, it consolidates GitHub blocks (deleting 9+ blocks), removes the entire copilot notification system, cleans up credential selection, and regenerates the OpenAPI spec. The commit message ("Add type definitions and update component imports") describes only the final commit — the actual PR title on GitHub is "feat(frontend): Add LLM registry admin UI."
Specialist Findings
🛡️ Security requires_admin_user. All DB operations use Prisma (no SQL injection risk). However, the frontend admin actions.ts has a TODO: Add auth token from session — requests are sent without authentication, making the admin UI non-functional and creating a footgun if someone "fixes" it by disabling backend auth. The public /api/llm/models route exposes disabled models via ?enabled_only=false without requiring admin auth. LlmModelCost exposes credential_provider/credential_id to all authenticated users, leaking infrastructure details. The proxy route change reverts a known streaming truncation fix.
⚠️ actions.ts:12-14— No auth token in admin API calls (TODO left in code)⚠️ routes.py:42-53—enabled_only=falseaccessible to non-admins⚠️ model.py:17-18— Credential identifiers exposed in public API⚠️ proxy/[...path]/route.ts— Streaming revert re-introduces file truncation bug
🏗️ Architecture ✅ — The LLM Registry follows good patterns: clean data-layer separation (data/llm_registry/), proper Pydantic response models, CQRS-lite with read routes separate from admin write routes. Prisma schema is well-structured with correct FK constraints and check constraints. GitHub block consolidation is clean with zero orphaned imports. Copilot cleanup is complete.
⚠️ admin_routes.py:28— Admin router has no prefix (repeats/llm/in every decorator) while public router usesAPIRouter(prefix="/llm")— inconsistent pattern⚠️ data/llm_registry/model.py:6— Data layer imports from blocks layer (from backend.blocks.llm import ModelMetadata) — wrong dependency direction, acceptable only as transitional step⚠️ registry.py— Module-level global mutable state (_dynamic_models,_schema_options,_lock) will be problematic for testing and multi-process deployments
⚡ Performance
- 🔴
schema.prisma:LlmModelCost— Missing plain index onllmModelId. Only partial unique indexes exist (with WHERE clauses), which PostgreSQL cannot use for plain FK joins or CASCADE deletes.refresh_llm_registry()will sequential-scan the costs table. - 🟠
registry.py:61-62— Single-instance in-memory cache with no cross-process invalidation. Admin mutations only refresh the responding instance; all others serve stale data until restart. - 🟠
admin_routes.py— Redundant DB round-trips: every update/delete does 3 queries (find by slug → find by ID in db_write → actual mutation). - 🟡
registry.py:183-193—get_default_model_slug()re-sorts all models on every call instead of caching during refresh. - 🟡
registry.py:66-163— Lock held during entire DB fetch + processing; should fetch outside lock and do atomic swap.
🧪 Testing 🔴 — Zero test coverage for the entire LLM Registry feature. This is the most significant gap. 984 lines of new backend code (registry.py 240 lines, db_write.py 294 lines, admin_routes.py 309 lines, routes.py 141 lines) and 3,185 lines of new frontend code ship with no tests at all. Additionally, test_github_blocks.py was deleted but prepare_pr_api_url() and surviving blocks still use the tested patterns — coverage lost for surviving code. The test_perplexity.py removal is mostly correct (tested code was deleted), but the PerplexityModel enum behavioral change (validation error instead of silent fallback) has no test proving the new behavior.
- 🔴 New LLM Registry: 0% coverage across 6 backend files and 16 frontend files
⚠️ test_gmail.pyremoval leaves_get_email_bodywith no protection againsthtml2textraising during.handle()- ✅
run_block_test.pyremaining tests correctly cover the simplified execution path - ✅
review_routes_test.pymock path updates are correct
📖 Quality 🔴 — Build-breaking import errors across the entire admin LLM UI. (Cross-confirmed by QA)
- 🔴 All 9+ modal components import non-existent functions from
actions.ts: components use names likedeleteLlmModelAction,createLlmProviderAction,toggleLlmModelActionbut the file exportsdeleteModel,createProvider, etc. Six functions are completely missing:deleteLlmCreatorAction,updateLlmCreatorAction,fetchLlmModelUsage,toggleLlmModelAction,setRecommendedModelAction,revertLlmMigrationAction. ⚠️ routes.py:55-76,112-136—LlmModelCost(...)mapping duplicated verbatim in two route handlers⚠️ admin_routes.py:126,178,246,291—import prisma.modelsrepeated as function-level import in 4 handlers⚠️ blocks/github/repo.py— 1174 lines after consolidation,repo_url.replace("https://github.com/", "")inlined 3 times
📦 Product 🔴 — 9+ GitHub blocks silently deleted with no migration path.
- 🔴
GithubListCommitsBlock(8b13f579),GithubGetCommitBlock(389eee51),GithubMergePullRequestBlock(77456c22),GithubCompareBranchesBlock,GithubSearchCodeBlock,GithubGetRepositoryTreeBlock,GithubGetRepositoryInfoBlock,GithubForkRepositoryBlock,GithubStarRepositoryBlock— all deleted with no data migration. Existing user agents referencing these block IDs will silently break. - 🟡 Copilot notification removal — users lose all background completion feedback (WebSocket listener, browser notifications, sound, title badge, sidebar auto-refresh)
- 🟡
useCredentialsInput.ts— Multi-type credential selection replaced with priority waterfall (OAuth always wins); users needing API key for providers that also support OAuth can't select it - ✅ Branch/file blocks consolidated with same block IDs preserved — no breakage there
📬 Discussion
- PR has merge conflicts with
dev(confirmed bygithub-actionsbot) - No reviewers assigned, no human comments, no inline review threads
- CodeRabbit automated review skipped because PR is still Draft
- This is actually the entire 5-PR stacked series (#12357 → #12359 → #12371 → #12467 → #12468), carrying the cumulative diff. All 5 PRs are OPEN with none merged. Review should proceed bottom-up.
- PR title mismatch: commit message says "fix(frontend)" but actual GitHub PR title is "feat(frontend): Add LLM registry admin UI" — and even that understates the scope
🔎 QA 🔴 — Existing features (login, signup, copilot, build, library, marketplace, password reset) all work cleanly. The new admin LLM Registry page (/admin/llms) is completely broken — build errors from wrong Table component import paths (@/components/atoms/Table/Table should be @/components/molecules/Table/Table) and non-existent action function imports (10+ files affected). The copilot page shows no artifacts from the notification removal — the cleanup is visually clean.
Blockers (Must Fix)
admin/llms/— Build errors across all 10+ modal/table components — Wrong import paths for Table (atoms→molecules) and non-existent action function names. The entire admin LLM UI is non-functional. (Quality 🔴 + QA 🔴)admin/llms/actions.ts:12-14— No auth token sent with admin API calls —TODO: Add auth token from sessionmeans all admin CRUD operations fail with 401. (Security 🟠)actions.ts— 6 action functions completely missing —deleteLlmCreatorAction,updateLlmCreatorAction,fetchLlmModelUsage,toggleLlmModelAction,setRecommendedModelAction,revertLlmMigrationActionare imported but never defined. (Quality 🔴)blocks/github/commits.py,repo_branches.py,repo_files.py— 9+ blocks deleted with no migration —GithubListCommitsBlock,GithubMergePullRequestBlock, and 7 others removed. Existing agents using these block IDs will silently break at runtime. Need deprecation notices or registry fallback. (Product 🔴)- Merge conflicts with
dev— PR cannot be merged in its current state. (Discussion⚠️ ) schema.prisma:LlmModelCost— Missing index onllmModelId— Partial unique indexes cannot serve FK joins; will cause sequential scans. (Performance 🔴)
Should Fix (Follow-up OK)
data/llm_registry/,server/v2/llm/— Zero test coverage — 984 lines of new backend code with no tests. At minimum: registry refresh tests, admin CRUD happy-path tests, public listing tests. (Testing 🔴)routes.py:42-53—enabled_only=falseaccessible to non-admins — Should require admin auth or be removed from public route. (Security 🟡)model.py:17-18— Credential identifiers in public API response —credential_provider,credential_id,credential_typeexposed to all authenticated users. (Security 🟡)registry.py— In-memory cache with no cross-instance invalidation — Admin mutations only refresh one instance. Add Redis pub/sub or TTL refresh. (Performance 🟠)admin_routes.py— 3 DB queries per mutation — Redundant slug→ID→mutation round-trips. (Performance 🟠)proxy/[...path]/route.ts— Streaming revert re-introduces truncation bug — Original code intentionally buffered to prevent file corruption. (Security 🟡)- Copilot sidebar auto-refresh removed —
refetchInterval: 10_000deleted; sidebar no longer updates. Users get no feedback on background task completion. (Product 🟡) useCredentialsInput.ts— Credential type selection regression — Multi-type providers default to OAuth with no way to choose API key. (Product 🟡)
Risk Assessment
Merge risk: HIGH | Rollback: MODERATE (schema migration adds tables, doesn't alter existing ones; block deletions are the risk)
Additional context from Discussion Analyst: This PR carries the cumulative diff of 5 stacked PRs (#12357–#12468), none of which are merged. The PR is still in Draft status with zero human reviews. The recommended path is to resolve merge conflicts, merge the stack bottom-up starting with the schema PR (#12357), or collapse into a single feature PR with the import/naming issues fixed.
REVIEW_COMPLETE
PR: #12468
Verdict: BLOCK
Blockers: 6
|
3dc0e11 to
25e6500
Compare
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟡 Medium Risk — Some Line OverlapThese PRs have some overlapping changes:
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 4 conflict(s), 4 medium risk, 2 low risk (out of 10 PRs with file overlap) Auto-generated on push. Ignores: |
2d30300 to
aa4bfcf
Compare
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
e61394a to
2ed0408
Compare
6e9731f to
8410448
Compare
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
2ed0408 to
2951d2c
Compare
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
be328c1 to
afe119c
Compare
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
Complete admin interface for managing LLM providers, models, and creators: - Provider CRUD with credential configuration - Model CRUD with cost management, enable/disable toggle - Creator CRUD for model creators - Recommended model selector - Admin layout sidebar entry for LLM Registry - Table atom component for data display
…e/disable, migration list/revert
- toggleLlmModelAction now sends migration params (migrate_to_slug, reason, custom_credit_cost)
- deleteLlmModelAction passes replacement_model_slug query param
- fetchLlmModelUsage calls real /llm/models/{slug}/usage endpoint
- fetchLlmMigrations calls real /llm/migrations endpoint
- revertLlmMigrationAction calls /llm/migrations/{id}/revert
- Fix model usage calls to use slug instead of UUID
…l guard, required migration DisableModelModal.tsx: - Fix field name: usage.node_count (was usage.usage_count — always undefined) - Recommended model: show blocking error UI instead of disable form; skip usage fetch entirely since the action is not allowed - Usage > 0: remove optional migration checkbox; migration is now required and the form is always shown — submit disabled until a replacement is picked - Usage = 0: unchanged — simple disable with no migration needed - Extract RecommendedModelBlock and DisableForm as named sub-components
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
1 similar comment
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
… fix falsy update checks - Rename provider_id -> provider_name in createLlmModelAction to match backend - Remove stale provider_id field from updateLlmModelAction (not in UpdateLlmModelRequest) - Replace any types with unknown/typed alternatives in adminFetch - Fix falsy value checks in update actions to use !== null
|
Closing in favor of the LLM registry restack: the admin UI (read slice; the editing slice follows as the next PR in the stack) is now #13612 (fresh re-cut onto current dev — the original migrations and seed data had drifted ~4 months). The design and much of the code here carried over directly; @Bentlybro is credited as co-author on the carried commits. Full stack starts at #13605. Thanks for the groundwork — the reviewed schema and cache design survived contact with the restack almost unchanged. |








Summary
Add admin UI for LLM registry management - Part 5 of 5 in incremental rollout.
Builds on PR #12467 (admin write API) to provide full visual management interface.
Changes
Admin Page (`/admin/llms`)
Main Components
Dashboard (`LlmRegistryDashboard.tsx`):
Tables:
CRUD Modals:
Other:
Features
✅ Admin-only access (role-based)
✅ Full CRUD operations with modals
✅ Real-time cache revalidation after mutations
✅ Migration tracking and revert
✅ Recommended model management
✅ Responsive design
✅ Error boundaries
✅ Based on original PR #11699 design
Design
UI copied directly from original PR #11699 implementation - proven design, fully functional.
API calls will need updating to match new admin endpoint structure.
Testing
Stacked PRs
Next Steps
After this PR merges, the LLM registry will be fully operational for admin management.
Block integration (consuming the registry in LLM blocks) comes in a future PR.