mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 03:12:35 +00:00
fix(pdf): use MiniMax text model fallback
This commit is contained in:
committed by
Peter Steinberger
parent
1a60c19743
commit
89bb62e2d7
@@ -32,7 +32,12 @@ vi.mock("./model-config.helpers.js", () => ({
|
||||
if (provider === "google") {
|
||||
return Boolean(process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY);
|
||||
}
|
||||
if (provider === "minimax" || provider === "minimax-cn") {
|
||||
if (
|
||||
provider === "minimax" ||
|
||||
provider === "minimax-cn" ||
|
||||
provider === "minimax-portal" ||
|
||||
provider === "minimax-portal-cn"
|
||||
) {
|
||||
return Boolean(process.env.MINIMAX_API_KEY);
|
||||
}
|
||||
return false;
|
||||
@@ -113,7 +118,7 @@ describe("resolvePdfModelConfigForTool", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not add configured MiniMax chat models as automatic PDF image fallbacks", () => {
|
||||
it("uses configured MiniMax chat models for PDF text extraction fallback", () => {
|
||||
vi.stubEnv("MINIMAX_API_KEY", "minimax-test");
|
||||
const cfg = {
|
||||
...withDefaultModel("openai/gpt-5.4"),
|
||||
@@ -126,7 +131,7 @@ describe("resolvePdfModelConfigForTool", () => {
|
||||
id: "MiniMax-M2.7",
|
||||
name: "MiniMax M2.7",
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128_000,
|
||||
maxTokens: 8_192,
|
||||
@@ -138,7 +143,27 @@ describe("resolvePdfModelConfigForTool", () => {
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(resolvePdfModelConfigForTool({ cfg, agentDir: TEST_AGENT_DIR })).toEqual({
|
||||
primary: "minimax/MiniMax-VL-01",
|
||||
primary: "minimax/MiniMax-M2.7",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses the default MiniMax chat model for PDF text extraction fallback", () => {
|
||||
vi.stubEnv("MINIMAX_API_KEY", "minimax-test");
|
||||
const cfg = {
|
||||
...withDefaultModel("minimax-portal/MiniMax-M2.7"),
|
||||
models: {
|
||||
providers: {
|
||||
"minimax-portal": {
|
||||
baseUrl: "https://api.minimax.io/anthropic",
|
||||
api: "anthropic-messages",
|
||||
models: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expect(resolvePdfModelConfigForTool({ cfg, agentDir: TEST_AGENT_DIR })).toEqual({
|
||||
primary: "minimax-portal/MiniMax-M2.7",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
resolveDefaultMediaModel,
|
||||
} from "../../media-understanding/defaults.js";
|
||||
import type { AuthProfileStore } from "../auth-profiles/types.js";
|
||||
import { isMinimaxVlmProvider } from "../minimax-vlm.js";
|
||||
import { isMinimaxVlmModel, isMinimaxVlmProvider } from "../minimax-vlm.js";
|
||||
import {
|
||||
coerceImageModelConfig,
|
||||
type ImageModelConfig,
|
||||
@@ -55,6 +55,78 @@ function resolveImageCandidateRefs(params: {
|
||||
.filter((value): value is string => Boolean(value));
|
||||
}
|
||||
|
||||
function formatProviderModelRef(providerId: string, modelId: string): string {
|
||||
const slash = modelId.indexOf("/");
|
||||
if (slash > 0 && modelId.slice(0, slash).trim() === providerId) {
|
||||
return modelId;
|
||||
}
|
||||
return `${providerId}/${modelId}`;
|
||||
}
|
||||
|
||||
function isMinimaxVlmModelRef(ref: string): boolean {
|
||||
const slash = ref.indexOf("/");
|
||||
if (slash <= 0) {
|
||||
return false;
|
||||
}
|
||||
return isMinimaxVlmModel(ref.slice(0, slash), ref.slice(slash + 1));
|
||||
}
|
||||
|
||||
function resolveMinimaxTextExtractionCandidateRefs(params: {
|
||||
cfg?: OpenClawConfig;
|
||||
primary: { provider: string; model: string };
|
||||
primaryProviderOk: boolean;
|
||||
agentDir: string;
|
||||
authStore?: AuthProfileStore;
|
||||
}): string[] {
|
||||
const candidates: string[] = [];
|
||||
const addCandidate = (providerId: string, modelId: string) => {
|
||||
const provider = providerId.trim();
|
||||
const model = modelId.trim();
|
||||
if (!provider || !model || isMinimaxVlmModel(provider, model)) {
|
||||
return;
|
||||
}
|
||||
const ref = formatProviderModelRef(provider, model);
|
||||
if (!candidates.includes(ref)) {
|
||||
candidates.push(ref);
|
||||
}
|
||||
};
|
||||
|
||||
if (params.primaryProviderOk && isMinimaxVlmProvider(params.primary.provider)) {
|
||||
addCandidate(params.primary.provider, params.primary.model);
|
||||
}
|
||||
|
||||
const providers = params.cfg?.models?.providers;
|
||||
if (!providers || typeof providers !== "object") {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
for (const [providerKey, providerCfg] of Object.entries(providers)) {
|
||||
const providerId = providerKey.trim();
|
||||
if (
|
||||
!providerId ||
|
||||
!isMinimaxVlmProvider(providerId) ||
|
||||
!hasAuthForProvider({
|
||||
provider: providerId,
|
||||
agentDir: params.agentDir,
|
||||
authStore: params.authStore,
|
||||
})
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const modelId = (providerCfg?.models ?? [])
|
||||
.find((model) => {
|
||||
const id = model?.id?.trim();
|
||||
return Boolean(id) && Array.isArray(model?.input) && model.input.includes("text");
|
||||
})
|
||||
?.id?.trim();
|
||||
if (modelId) {
|
||||
addCandidate(providerId, modelId);
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
export function resolvePdfModelConfigForTool(params: {
|
||||
cfg?: OpenClawConfig;
|
||||
agentDir: string;
|
||||
@@ -138,6 +210,13 @@ export function resolvePdfModelConfigForTool(params: {
|
||||
agentDir: params.agentDir,
|
||||
workspaceDir: params.workspaceDir,
|
||||
authStore: params.authStore,
|
||||
}).filter((ref) => !isMinimaxVlmModelRef(ref));
|
||||
const minimaxTextExtractionCandidates = resolveMinimaxTextExtractionCandidateRefs({
|
||||
cfg: params.cfg,
|
||||
primary,
|
||||
primaryProviderOk: providerOk,
|
||||
agentDir: params.agentDir,
|
||||
authStore: params.authStore,
|
||||
});
|
||||
|
||||
if (params.cfg?.models?.providers && typeof params.cfg.models.providers === "object") {
|
||||
@@ -180,11 +259,19 @@ export function resolvePdfModelConfigForTool(params: {
|
||||
} else if (providerOk && primarySupportsNativePdf && (providerVision || providerDefault)) {
|
||||
preferred = providerVision ?? `${primary.provider}/${providerDefault}`;
|
||||
} else {
|
||||
preferred = nativePdfCandidates[0] ?? genericImageCandidates[0] ?? null;
|
||||
preferred =
|
||||
nativePdfCandidates[0] ??
|
||||
minimaxTextExtractionCandidates[0] ??
|
||||
genericImageCandidates[0] ??
|
||||
null;
|
||||
}
|
||||
|
||||
if (preferred?.trim()) {
|
||||
for (const candidate of [...nativePdfCandidates, ...genericImageCandidates]) {
|
||||
for (const candidate of [
|
||||
...nativePdfCandidates,
|
||||
...minimaxTextExtractionCandidates,
|
||||
...genericImageCandidates,
|
||||
]) {
|
||||
if (candidate !== preferred) {
|
||||
addFallback(candidate);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user