Skip to content

feat(backend/api): admin LLM registry API with audit logging - #13611

Closed
ntindle wants to merge 4 commits into
feat/llm-registry-v2-copilot-routingfrom
feat/llm-registry-v2-admin-api
Closed

feat(backend/api): admin LLM registry API with audit logging#13611
ntindle wants to merge 4 commits into
feat/llm-registry-v2-copilot-routingfrom
feat/llm-registry-v2-admin-api

Conversation

@ntindle

@ntindle ntindle commented Jul 18, 2026

Copy link
Copy Markdown
Member

Why

Part 7 of 9 of the LLM registry restack (#13605#13606#13607#13608#13609#13610→this). This is the front door that replaces the "hand-edit a JSON file and open a PR" model-management workflow: adding K3 becomes an authenticated admin call whose row is validated, audited, and propagated to every install.

What

Admin API at /api/admin/llm (all Security(requires_admin_user)), re-cut from @Bentlybro's #12467:

  • Kept: model CRUD ({slug:path} params), creator CRUD, usage counting, disable-with-replacement + revert
  • Dropped: provider CRUD — providers are a fixed seed set (read-only list retained for the UI)
  • source=LOCAL on every write — the importer's admin-wins contract from feat(backend): add idempotent LLM catalog importer and bundled catalog #13607
  • AuditLog per mutation (uses the existing AuditLog table; entity-typed actions like LLM_MODEL_DISABLED, before/after JSON; audit failure never fails the operation)
  • New columns wired end-to-end: visibility, min_subscription_tier, fallback_model_slug (existence-validated), kind
  • New endpoints: GET/PUT /routes (routing-cell upsert; model must exist + be enabled, HIDDEN allowed; response carries capability warnings — e.g. non-reasoning model in a thinking cell); GET /routes/warnings (the feat(backend/copilot): resolve copilot models through the LLM registry #13610 refusal records — typo'd LD slugs surface here); GET /catalog/export (regenerate the bundled catalog.json with a curl)

Fixes over the original branch

  • Unqualified "AgentNode" raw SQL → {schema_prefix} helpers (the exact bug class flagged in the original feat(platform): Add LLM registry core - DB layer + in-memory cache #12359 review; breaks non-platform schemas otherwise)
  • Latent revert bug: migration wrote provider-stripped node values but revert matched raw slugs — reverts could never have matched a node
  • The old branch's private refresh_runtime_caches copy replaced by the canonical one (single choke point for cache coherence)

Verification

  • 86/86 tests: full registry suite green + real-DB db_write tests (source=LOCAL assertions, AuditLog rows per action, cell operations, migration/revert round-trip at the SQL layer) + route-layer tests (auth, validation, capability warnings, HIDDEN acceptance, warnings/export endpoints)
  • poetry run format + poetry run lint clean

Known follow-ups (tickets, not scope): "reset to catalog" action (LOCAL is sticky by design); toggle-with-populated-graph integration test needs graph fixtures.

Checklist

  • All routes admin-gated; acting admin recorded on every mutation via AuditLog
  • Out-of-scope changes: none

Part 7 of 9 of the LLM registry restack. Re-cut of #12467's admin API
onto current dev layout (backend/api/features/admin/ +
backend/data/llm_registry/), reworked per the restack design:

- provider CRUD dropped (fixed seed rows; read-only list kept for UI);
  model CRUD, creator CRUD, disable-with-replacement + revert kept
- every write claims source=LOCAL — the importer's admin-wins contract
- AuditLog row per mutation (entity-typed actions, before/after
  snapshots; audit failure never fails the op)
- new columns wired through requests/db/responses: visibility,
  minSubscriptionTier, fallbackModelSlug (validated), kind
- unqualified "AgentNode" raw SQL fixed to {schema_prefix} helpers
  (the bug class majdyz flagged in the original review)
- fixed a latent revert bug: migrate wrote provider-stripped node
  values but revert matched raw slugs, so reverts could never match
- NEW: GET/PUT /api/admin/llm/routes (cell upsert with exists+enabled
  validation, HIDDEN allowed, capability warnings for e.g. non-reasoning
  models in thinking cells), GET /routes/warnings (recent LD-slug
  refusals from part 6), GET /catalog/export (catalog.json refresh via
  curl instead of prod DB access)

Follow-ups noted: "reset to catalog" admin action (LOCAL is sticky);
toggle-with-real-node-migration integration test needs graph fixtures.

Co-authored-by: Bentlybro <Github@bentlybro.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71bf4e3a-a982-4fe7-a5b6-bbd516c39635

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/llm-registry-v2-admin-api

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added platform/backend AutoGPT Platform - Back end size/xl labels Jul 18, 2026
@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.01%. Comparing base (c7d0167) to head (fe21b6b).

Additional details and impacted files
@@                          Coverage Diff                          @@
##           feat/llm-registry-v2-copilot-routing   #13611   +/-   ##
=====================================================================
  Coverage                                 76.01%   76.01%           
=====================================================================
  Files                                      2688     2688           
  Lines                                    204266   204266           
  Branches                                  19654    19653    -1     
=====================================================================
+ Hits                                     155266   155278   +12     
+ Misses                                    44657    44648    -9     
+ Partials                                   4343     4340    -3     
Flag Coverage Δ
platform-frontend 46.16% <ø> (+<0.01%) ⬆️
platform-frontend-e2e 31.07% <ø> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 82.83% <ø> (ø)
Platform Frontend 50.00% <ø> (+0.03%) ⬆️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ntindle and others added 3 commits July 18, 2026 01:40
Bare-dict list responses generated untyped orval clients. Adds
LlmModelsAdminListResponse et al., annotates the four GET list
endpoints, and includes the source field on provider/creator
responses (the admin UI shows source badges).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ints

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ntindle

ntindle commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

After a post-build design review we pivoted from the DB-registry to catalog-as-code: one canonical, schema-validated catalog file is the source of truth (models + costs + copilot routing), updated by PR (catalog-only diffs may ride hotfix→master; the /review bot covers the lane), propagated by CD, with LaunchDarkly demoted to optional cohort experiments and git history as the audit log. Rationale: the admin machinery mostly bought instant-mutation and non-engineer authoring we don't need, and LD is too unreliable to be the load-bearing control layer.

The retirement machinery (incl. the revert-matching fix found here) lives on as the CLI in #13625; the CRUD/audit/routing endpoints have no replacement by design — the PR is the write path, git is the audit.

@ntindle ntindle closed this Jul 20, 2026
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to ✅ Done in AutoGPT development kanban Jul 20, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform/backend AutoGPT Platform - Back end platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant