test(agents): normalize live model not-found skips

This commit is contained in:
Peter Steinberger
2026-03-08 13:43:31 +00:00
parent f930fcbd3f
commit f66cc886d3
3 changed files with 63 additions and 18 deletions

View File

@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest";
import {
isMiniMaxModelNotFoundErrorMessage,
isModelNotFoundErrorMessage,
} from "./live-model-errors.js";
describe("live model error helpers", () => {
it("detects generic model-not-found messages", () => {
expect(isModelNotFoundErrorMessage('{"code":404,"message":"model not found"}')).toBe(true);
expect(isModelNotFoundErrorMessage("model: MiniMax-M2.5-highspeed not found")).toBe(true);
expect(isModelNotFoundErrorMessage("request ended without sending any chunks")).toBe(false);
});
it("detects bare minimax 404 page-not-found responses", () => {
expect(isMiniMaxModelNotFoundErrorMessage("404 page not found")).toBe(true);
expect(isMiniMaxModelNotFoundErrorMessage("Error: 404 404 page not found")).toBe(true);
expect(isMiniMaxModelNotFoundErrorMessage("request ended without sending any chunks")).toBe(
false,
);
});
});

View File

@@ -0,0 +1,24 @@
export function isModelNotFoundErrorMessage(raw: string): boolean {
const msg = raw.trim();
if (!msg) {
return false;
}
if (/\b404\b/.test(msg) && /not(?:[_\-\s])?found/i.test(msg)) {
return true;
}
if (/not_found_error/i.test(msg)) {
return true;
}
if (/model:\s*[a-z0-9._-]+/i.test(msg) && /not(?:[_\-\s])?found/i.test(msg)) {
return true;
}
return false;
}
export function isMiniMaxModelNotFoundErrorMessage(raw: string): boolean {
const msg = raw.trim();
if (!msg) {
return false;
}
return /\b404\b.*\bpage not found\b/i.test(msg);
}

View File

@@ -9,6 +9,10 @@ import {
isAnthropicBillingError,
isAnthropicRateLimitError,
} from "./live-auth-keys.js";
import {
isMiniMaxModelNotFoundErrorMessage,
isModelNotFoundErrorMessage,
} from "./live-model-errors.js";
import { isModernModelRef } from "./live-model-filter.js";
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
import { ensureOpenClawModelsJson } from "./models-config.js";
@@ -82,23 +86,6 @@ function isGoogleModelNotFoundError(err: unknown): boolean {
return false;
}
function isModelNotFoundErrorMessage(raw: string): boolean {
const msg = raw.trim();
if (!msg) {
return false;
}
if (/\b404\b/.test(msg) && /not[_-]?found/i.test(msg)) {
return true;
}
if (/not_found_error/i.test(msg)) {
return true;
}
if (/model:\s*[a-z0-9._-]+/i.test(msg) && /not[_-]?found/i.test(msg)) {
return true;
}
return false;
}
function isChatGPTUsageLimitErrorMessage(raw: string): boolean {
const msg = raw.toLowerCase();
return msg.includes("hit your chatgpt usage limit") && msg.includes("try again in");
@@ -488,7 +475,11 @@ describeLive("live models (profile keys)", () => {
if (ok.res.stopReason === "error") {
const msg = ok.res.errorMessage ?? "";
if (allowNotFoundSkip && isModelNotFoundErrorMessage(msg)) {
if (
allowNotFoundSkip &&
(isModelNotFoundErrorMessage(msg) ||
(model.provider === "minimax" && isMiniMaxModelNotFoundErrorMessage(msg)))
) {
skipped.push({ model: id, reason: msg });
logProgress(`${progressLabel}: skip (model not found)`);
break;
@@ -572,6 +563,15 @@ describeLive("live models (profile keys)", () => {
logProgress(`${progressLabel}: skip (google model not found)`);
break;
}
if (
allowNotFoundSkip &&
model.provider === "minimax" &&
isMiniMaxModelNotFoundErrorMessage(message)
) {
skipped.push({ model: id, reason: message });
logProgress(`${progressLabel}: skip (model not found)`);
break;
}
if (
allowNotFoundSkip &&
model.provider === "minimax" &&