From 29853219bc2e15681cd2dd2beee3eb0bc668f5af Mon Sep 17 00:00:00 2001 From: Replit Agent Date: Tue, 16 Jun 2026 21:35:24 +0000 Subject: [PATCH] Improve AI model compatibility warnings and error handling Add detection for OpenAI models that only support v1/responses and are not compatible with chat completions, providing user-friendly warnings during model selection and clearer error messages upon connection testing or AI analysis execution. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0d01f99a-ea6a-447d-82fd-311715434a39 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: ac489071-6c6a-4584-9740-76bf6ca16040 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/e32d2b99-1721-47dd-833c-98b372f48008/0d01f99a-ea6a-447d-82fd-311715434a39/upEITG1 Replit-Helium-Checkpoint-Created: true --- artifacts/api-server/src/lib/aiAnalysis.ts | 6 +++++ .../skillguard/src/i18n/locales/de/admin.ts | 2 ++ .../skillguard/src/i18n/locales/en/admin.ts | 2 ++ .../skillguard/src/i18n/locales/es/admin.ts | 2 ++ artifacts/skillguard/src/pages/admin.tsx | 21 +++++++++++++++++- attached_assets/image_1781645514678.png | Bin 0 -> 19570 bytes 6 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 attached_assets/image_1781645514678.png diff --git a/artifacts/api-server/src/lib/aiAnalysis.ts b/artifacts/api-server/src/lib/aiAnalysis.ts index d8daa25..bdd1f64 100644 --- a/artifacts/api-server/src/lib/aiAnalysis.ts +++ b/artifacts/api-server/src/lib/aiAnalysis.ts @@ -137,6 +137,12 @@ async function callOpenAiCompatible( }); if (!res.ok) { const body = await res.text(); + if (body.includes("v1/responses")) { + throw new Error( + `Das Modell "${provider.model}" unterstützt nur /v1/responses, nicht /v1/chat/completions. ` + + `Bitte wählen Sie ein Chat-kompatibles Modell (z.\u202fB. gpt-4o, gpt-4-turbo, gpt-3.5-turbo).`, + ); + } throw new Error( `HTTP ${res.status}: ${redactSecrets(body.slice(0, 300), provider.apiToken)}`, ); diff --git a/artifacts/skillguard/src/i18n/locales/de/admin.ts b/artifacts/skillguard/src/i18n/locales/de/admin.ts index 3b4509c..f81de1a 100644 --- a/artifacts/skillguard/src/i18n/locales/de/admin.ts +++ b/artifacts/skillguard/src/i18n/locales/de/admin.ts @@ -16,6 +16,8 @@ export default { noneFoundTried: "Keine Modelle gefunden – bitte das Modell manuell eingeben.", noneFoundHint: "Testen Sie die Verbindung, um verfügbare Modelle automatisch zu laden, oder geben Sie das Modell manuell ein.", + responsesOnlyWarning: + "Dieses Modell unterstützt nur /v1/responses, nicht /v1/chat/completions. Die KI-Analyse wird fehlschlagen. Bitte wählen Sie ein Chat-kompatibles Modell (z.\u202fB. gpt-4o, gpt-4-turbo).", }, providers: { heading: "KI-Provider", diff --git a/artifacts/skillguard/src/i18n/locales/en/admin.ts b/artifacts/skillguard/src/i18n/locales/en/admin.ts index ba2edb3..cb898e4 100644 --- a/artifacts/skillguard/src/i18n/locales/en/admin.ts +++ b/artifacts/skillguard/src/i18n/locales/en/admin.ts @@ -16,6 +16,8 @@ export default { noneFoundTried: "No models found – please enter the model manually.", noneFoundHint: "Test the connection to load available models automatically, or enter the model manually.", + responsesOnlyWarning: + "This model only supports /v1/responses, not /v1/chat/completions. AI analysis will fail. Please choose a chat-compatible model (e.g. gpt-4o, gpt-4-turbo).", }, providers: { heading: "AI providers", diff --git a/artifacts/skillguard/src/i18n/locales/es/admin.ts b/artifacts/skillguard/src/i18n/locales/es/admin.ts index 3dbc7c0..9f4c7cc 100644 --- a/artifacts/skillguard/src/i18n/locales/es/admin.ts +++ b/artifacts/skillguard/src/i18n/locales/es/admin.ts @@ -16,6 +16,8 @@ export default { noneFoundTried: "No se encontraron modelos: introduzca el modelo manualmente.", noneFoundHint: "Pruebe la conexión para cargar automáticamente los modelos disponibles, o introduzca el modelo manualmente.", + responsesOnlyWarning: + "Este modelo solo admite /v1/responses, no /v1/chat/completions. El análisis de IA fallará. Seleccione un modelo compatible con chat (p.\u202fej. gpt-4o, gpt-4-turbo).", }, providers: { heading: "Proveedores de IA", diff --git a/artifacts/skillguard/src/pages/admin.tsx b/artifacts/skillguard/src/pages/admin.tsx index a955611..2744487 100644 --- a/artifacts/skillguard/src/pages/admin.tsx +++ b/artifacts/skillguard/src/pages/admin.tsx @@ -42,14 +42,29 @@ const PROVIDER_PRESETS: Partial> = { ], }; -function ModelField({ models, loading, tried, value, onChange }: { +const RESPONSES_ONLY_RE = /^o\d/i; + +function isResponsesOnlyModel(model: string, apiType: string): boolean { + return apiType === "openai" && RESPONSES_ONLY_RE.test(model.trim()); +} + +function ModelField({ models, loading, tried, value, onChange, apiType }: { models: string[]; loading: boolean; tried: boolean; value: string; onChange: (v: string) => void; + apiType: string; }) { const { t } = useTranslation(); + const warnResponsesOnly = value && isResponsesOnlyModel(value, apiType); + + const warning = warnResponsesOnly ? ( +

+ {t("admin.modelField.responsesOnlyWarning")} +

+ ) : null; + if (loading) { return (
@@ -71,6 +86,7 @@ function ModelField({ models, loading, tried, value, onChange }: {

{t("admin.modelField.found", { count: models.length })}

+ {warning}
); } @@ -83,6 +99,7 @@ function ModelField({ models, loading, tried, value, onChange }: { ? t("admin.modelField.noneFoundTried") : t("admin.modelField.noneFoundHint")}

+ {warning} ); } @@ -368,6 +385,7 @@ function ProviderTab() { models={addModels} loading={addModelsLoading} tried={addModelsTried} + apiType={addForm.apiType} value={addForm.model} onChange={(v) => setAddForm(f => ({ ...f, model: v }))} /> @@ -498,6 +516,7 @@ function ProviderTab() { models={editModels} loading={editModelsLoading} tried={editModelsTried} + apiType={editForm.apiType} value={editForm.model} onChange={(v) => setEditForm(f => ({ ...f, model: v }))} /> diff --git a/attached_assets/image_1781645514678.png b/attached_assets/image_1781645514678.png new file mode 100644 index 0000000000000000000000000000000000000000..b3641e52fde1050fcef7406dd1696da537c78555 GIT binary patch literal 19570 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∓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 literal 0 HcmV?d00001