Skip to content

feat(models): verify provider connection when saving an AI model#495

Merged
m43i merged 2 commits into
mainfrom
feat/466-model-test-connection
Jul 2, 2026
Merged

feat(models): verify provider connection when saving an AI model#495
m43i merged 2 commits into
mainfrom
feat/466-model-test-connection

Conversation

@bjrump

@bjrump bjrump commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Saving the AI model form now verifies the connection against the provider first. A new admin-only POST /models/test endpoint runs a minimal, type-appropriate probe with the submitted configuration (without persisting anything); if it fails, the dialog blocks the save and shows an actionable inline error (auth / model not found / unreachable) including the provider's message.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring (no functional changes)
  • Documentation update
  • CI/CD or infrastructure change

Changes Made

  • packages/ai/src/probe.ts (new): probeModelConfiguration sends a minimal probe per model type — text/subagent/extract/image: a tiny completion; embedding: one embed call; audio/video: transcription of a generated 0.5 s silent WAV — with a 15 s timeout and no retries, and classifies failures into auth, not_found, unreachable, or unknown with the provider message.
  • POST /models/test in apps/api/src/routes/models.ts, gated by requireOrganizationAdmin like the other model admin routes. A blank API key together with model_id reuses the stored (write-only) key, so the edit flow can test without re-entering credentials.
  • ModelFormDialog runs the probe on save — on create always, on edit only when connection config changed (adapter, provider model, key, URL, resource name), so a pure rename never fails on an unreachable provider. Failures render inline above the footer and clear when a connection field changes. de + en strings.
  • Fixed mapModelError to unwrap Result.tryPromise's UnhandledException wrapper (same pattern as mapChatError); previously every model-route error (including the existing INVALID_MODEL/MODEL_NOT_FOUND paths) surfaced as 500.

Related Issues

Closes #466

Testing

  • I have tested these changes locally
  • I have added/updated tests as appropriate
  • All existing tests pass

Unit tests for the probe classification and WAV payload (packages/ai/src/__tests__/probe.test.ts) plus new ModelFormDialog tests for blocked saves, probe-skipping on rename, and the stored-key reference. Verified end-to-end against the dev stack: wrong key → auth, dead endpoint → unreachable, stored-key flow for text and embedding models → success; in the browser: save with a broken provider model shows the error and keeps the dialog open, a valid config saves and closes.

Checklist

  • My code follows the project's coding standards
  • I have updated documentation as needed
  • I have run make generate if SQL queries were modified (backend)
  • I have updated barrel exports if components were added (frontend)

Screenshots (if applicable)

Failed probe blocks the save and shows the reason plus the provider detail inline above the dialog footer.

Saving the AI model form now runs a minimal, type-appropriate probe
against the provider first (text: 1 short completion, embedding: one
embed call, audio/video: tiny silent WAV transcription) and blocks the
save with an actionable inline error (auth / not found / unreachable)
when it fails. On edit the probe only runs when connection config
changed and reuses the stored API key via model_id.

Also fixes mapModelError to unwrap Result.tryPromise's
UnhandledException wrapper so model routes return their intended
status codes instead of 500.

Closes #466
@bjrump bjrump added the enhancement New feature or request label Jul 2, 2026
@bjrump
bjrump requested a review from m43i as a code owner July 2, 2026 11:23
@bjrump bjrump self-assigned this Jul 2, 2026
@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR verifies AI model provider connections before saving. The main changes are:

  • New admin-only POST /models/test endpoint.
  • Provider-specific probe logic for text, embedding, audio, and video models.
  • Save-time connection checks in the model form.
  • Inline translated probe errors in the dialog.
  • Model route error mapping for wrapped route errors.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/api/src/routes/models.ts Adds the model test endpoint, stored-key probe flow, validation before probing, and wrapped model-route error handling.
apps/frontend/components/admin/ModelFormDialog.tsx Adds connection-change detection, pre-save probing, stored-key references on edit, and inline probe errors.
apps/frontend/lib/api/models.ts Adds the frontend API helper for the model connection test endpoint.
packages/ai/src/probe.ts Adds model probe execution, provider error classification, and a generated silent WAV payload for transcription probes.
packages/contracts/src/routes.ts Adds the model test request and result contract types.

Reviews (2): Last reviewed commit: "docs(api): note stored-key reuse trust m..." | Re-trigger Greptile

Comment thread apps/api/src/routes/models.ts
Comment thread apps/frontend/components/admin/ModelFormDialog.tsx
@m43i
m43i added this pull request to the merge queue Jul 2, 2026
Merged via the queue into main with commit 082e83a Jul 2, 2026
3 checks passed
@m43i
m43i deleted the feat/466-model-test-connection branch July 2, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Test connection when configuring an AI Model

2 participants