fix(dashboard): probe System One models through /v1/systemone

The inline model test sent a chat-completions payload and failed with
500 on decision models. Add a systemone branch to pingModelByKind that
submits a native state+questions probe, and restore the test button
that was hidden for System One models.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
decolua
2026-09-22 14:41:59 +07:00
parent f28e918e24
commit 20014b3104
2 changed files with 32 additions and 3 deletions

View File

@@ -119,7 +119,6 @@ export default function ModelsCard({ providerId, kindFilter, providerAliasOverri
const providerAlias = providerAliasOverride || getProviderAlias(providerId);
const effectiveType = kindFilter || "llm";
const supportsTest = kindFilter !== "systemone";
const fetchData = useCallback(async () => {
try {
@@ -239,7 +238,7 @@ export default function ModelsCard({ providerId, kindFilter, providerAliasOverri
onSetAlias={(alias) => handleSetAlias(model.id, alias)}
onDeleteAlias={() => handleDeleteAlias(existingAlias)}
testStatus={modelTestResults[model.id]}
onTest={supportsTest ? () => handleTestModel(model.id) : undefined}
onTest={() => handleTestModel(model.id)}
isTesting={testingModelId === model.id}
isFree={model.isFree}
/>
@@ -256,7 +255,7 @@ export default function ModelsCard({ providerId, kindFilter, providerAliasOverri
onSetAlias={() => {}}
onDeleteAlias={() => handleDeleteCustomModel(model.id)}
testStatus={modelTestResults[model.id]}
onTest={supportsTest ? () => handleTestModel(model.id) : undefined}
onTest={() => handleTestModel(model.id)}
isTesting={testingModelId === model.id}
isCustom
/>

View File

@@ -132,6 +132,36 @@ export async function pingModelByKind(model, kind, baseUrl = `http://127.0.0.1:$
return { ok: true, latencyMs, error: null, status: res.status };
}
if (kind === "systemone") {
const res = await fetch(`${baseUrl}/api/v1/systemone`, {
method: "POST",
headers,
body: JSON.stringify({
model,
state: "Customer: I was charged twice for my order this morning.",
questions: {
probe: { type: "noul", instructions: "Is the customer reporting a billing problem?" },
},
}),
signal: AbortSignal.timeout(15000),
});
const latencyMs = Date.now() - start;
const rawText = await res.text().catch(() => "");
let parsed = null;
try { parsed = rawText ? JSON.parse(rawText) : null; } catch {}
if (!res.ok) {
const detail = parsed?.error?.message || parsed?.msg || parsed?.message || parsed?.error || rawText;
return { ok: false, latencyMs, error: `HTTP ${res.status}${detail ? `: ${String(detail).slice(0, 240)}` : ""}`, status: res.status };
}
const hasAnswers = parsed?.answers && typeof parsed.answers === "object" && Object.keys(parsed.answers).length > 0;
if (!hasAnswers) {
return { ok: false, latencyMs, status: res.status, error: "Provider returned no answers for this model" };
}
return { ok: true, latencyMs, error: null, status: res.status };
}
const res = await fetch(`${baseUrl}/api/v1/chat/completions`, {
method: "POST",
headers,