diff --git a/app/[lang]/admin/page.tsx b/app/[lang]/admin/page.tsx
index 091bd57..6045be1 100644
--- a/app/[lang]/admin/page.tsx
+++ b/app/[lang]/admin/page.tsx
@@ -384,7 +384,7 @@ function ProviderDetail({
try {
const data = await adminFetch("/api/admin/test-model", password, {
method: "POST",
- body: JSON.stringify({ providerId: provider.id, modelId }),
+ body: JSON.stringify({ provider, modelId }),
})
setTestResults((prev) => ({
...prev,
@@ -693,10 +693,6 @@ function ProviderDetail({
)}
-
- Note: Test runs against saved credentials — save your
- changes first.
-
diff --git a/app/api/admin/test-model/route.ts b/app/api/admin/test-model/route.ts
index 9b93c5f..4d6e3d3 100644
--- a/app/api/admin/test-model/route.ts
+++ b/app/api/admin/test-model/route.ts
@@ -1,45 +1,52 @@
import { POST as validateModel } from "@/app/api/validate-model/route"
import { checkAdminAuth } from "@/lib/admin/auth"
-import { loadAdminProviders } from "@/lib/admin/providers"
+import {
+ AdminProviderSchema,
+ loadAdminProviders,
+ mergeSecrets,
+} from "@/lib/admin/providers"
export const runtime = "nodejs"
export const dynamic = "force-dynamic"
-// Test a stored admin provider's model. The client only has masked
-// secrets, so credentials are filled in server-side from settings.json
-// and passed to the existing validate-model handler.
+// Test a model with the client's CURRENT provider state (which may be
+// unsaved). Secret fields arrive either as plaintext (newly typed) or as
+// masked {isSet} markers, which are resolved against settings.json — so
+// testing works both before and after saving.
export async function POST(req: Request) {
const authError = checkAdminAuth(req)
if (authError) return authError
- let body: { providerId?: string; modelId?: string }
+ let body: { provider?: unknown; modelId?: string }
try {
body = await req.json()
} catch {
return Response.json({ error: "Invalid JSON body" }, { status: 400 })
}
- const stored = loadAdminProviders().find((p) => p.id === body.providerId)
- if (!stored || !body.modelId) {
+ const parsed = AdminProviderSchema.safeParse(body.provider)
+ if (!parsed.success || !body.modelId) {
return Response.json(
- { valid: false, error: "Unknown provider or model" },
+ { valid: false, error: "Invalid provider or model" },
{ status: 400 },
)
}
+ const [resolved] = mergeSecrets([parsed.data], loadAdminProviders())
+
return validateModel(
new Request(new URL("/api/validate-model", req.url), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
- provider: stored.provider,
- apiKey: stored.apiKey,
- baseUrl: stored.baseUrl,
+ provider: resolved.provider,
+ apiKey: resolved.apiKey,
+ baseUrl: resolved.baseUrl,
modelId: body.modelId,
- awsAccessKeyId: stored.awsAccessKeyId,
- awsSecretAccessKey: stored.awsSecretAccessKey,
- awsRegion: stored.awsRegion,
- vertexApiKey: stored.vertexApiKey,
+ awsAccessKeyId: resolved.awsAccessKeyId,
+ awsSecretAccessKey: resolved.awsSecretAccessKey,
+ awsRegion: resolved.awsRegion,
+ vertexApiKey: resolved.vertexApiKey,
}),
}),
)