mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 01:32:22 +03:00
Compare commits
5 Commits
green/8728
...
fix/minima
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52b60d846 | ||
|
|
aebd481607 | ||
|
|
12c64667a9 | ||
|
|
a316c8db52 | ||
|
|
25cf9d9065 |
@@ -1,17 +1,14 @@
|
||||
import type { RegistryEntry } from "../../../shared.ts";
|
||||
import { getAnthropicCompatHeaders, ANTHROPIC_VERSION_HEADER } from "../../../shared.ts";
|
||||
|
||||
export const minimax_cnProvider: RegistryEntry = {
|
||||
id: "minimax-cn",
|
||||
alias: "minimax-cn", // unique alias (was colliding with minimax)
|
||||
format: "claude",
|
||||
format: "openai",
|
||||
executor: "default",
|
||||
baseUrl: "https://api.minimaxi.com/anthropic/v1/messages",
|
||||
baseUrl: "https://api.minimaxi.com/v1/chat/completions",
|
||||
modelsUrl: "https://api.minimaxi.com/v1/models",
|
||||
urlSuffix: "?beta=true",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
headers: getAnthropicCompatHeaders(),
|
||||
models: [
|
||||
// Keep parity with minimax to ensure model discovery works for minimax-cn connections.
|
||||
// #3110: MiniMax M3 — frontier coding model with 1M context
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import type { RegistryEntry } from "../../shared.ts";
|
||||
import { getAnthropicCompatHeaders, ANTHROPIC_VERSION_HEADER } from "../../shared.ts";
|
||||
|
||||
export const minimaxProvider: RegistryEntry = {
|
||||
id: "minimax",
|
||||
alias: "minimax",
|
||||
format: "claude",
|
||||
format: "openai",
|
||||
executor: "default",
|
||||
baseUrl: "https://api.minimax.io/anthropic/v1/messages",
|
||||
baseUrl: "https://api.minimax.io/v1/chat/completions",
|
||||
modelsUrl: "https://api.minimax.io/v1/models",
|
||||
urlSuffix: "?beta=true",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
headers: getAnthropicCompatHeaders(),
|
||||
models: [
|
||||
// T12/T28: MiniMax default upgraded from M2.5 to M2.7
|
||||
// #3110: MiniMax M3 — frontier coding model with 1M context
|
||||
|
||||
@@ -289,8 +289,6 @@ export class DefaultExecutor extends BaseExecutor {
|
||||
case "glm":
|
||||
case "glmt":
|
||||
case "kimi-coding":
|
||||
case "minimax":
|
||||
case "minimax-cn":
|
||||
return `${this.config.baseUrl}?beta=true`;
|
||||
case "agentrouter":
|
||||
return this.usesClaudeCodeProtocol(credentials)
|
||||
|
||||
@@ -17,8 +17,10 @@ describe("Cache Control Policy - Claude Protocol Providers", () => {
|
||||
// These should be detected via targetFormat
|
||||
assert.equal(providerSupportsCaching("bailian-coding-plan", "claude"), true);
|
||||
assert.equal(providerSupportsCaching("glm", "claude"), true);
|
||||
assert.equal(providerSupportsCaching("minimax", "claude"), true);
|
||||
assert.equal(providerSupportsCaching("minimax-cn", "claude"), true);
|
||||
// minimax/minimax-cn use openai format (#3110 / image 403 fix);
|
||||
// caching support for their OpenAI-compatible endpoint is TBD
|
||||
assert.equal(providerSupportsCaching("minimax", "openai"), false);
|
||||
assert.equal(providerSupportsCaching("minimax-cn", "openai"), false);
|
||||
assert.equal(providerSupportsCaching("kimi-coding", "claude"), true);
|
||||
|
||||
// #3955 — OpenAI / Codex use automatic prefix caching (no cache_control needed).
|
||||
@@ -66,15 +68,17 @@ describe("Cache Control Policy - Claude Protocol Providers", () => {
|
||||
true
|
||||
);
|
||||
|
||||
// minimax now uses openai format — caching behavior may differ;
|
||||
// cache_control preservation depends on whether it joins CACHING_PROVIDERS
|
||||
assert.equal(
|
||||
shouldPreserveCacheControl({
|
||||
userAgent: claudeCodeUA,
|
||||
isCombo: false,
|
||||
targetProvider: "minimax",
|
||||
targetFormat: "claude",
|
||||
targetFormat: "openai",
|
||||
settings: { alwaysPreserveClientCache: "auto" },
|
||||
}),
|
||||
true
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -73,6 +73,26 @@ describe("MiniMax M3 model registration (#3110)", () => {
|
||||
assert.equal(m3.contextLength, 1_048_576);
|
||||
});
|
||||
|
||||
it("minimax uses openai format (not claude) so images work via /v1/chat/completions", () => {
|
||||
const entry = REGISTRY.minimax;
|
||||
assert.ok(entry, "minimax registry entry must exist");
|
||||
assert.equal(
|
||||
entry.format,
|
||||
"openai",
|
||||
"minimax must use openai format — the Anthropic-compatible /anthropic/v1/messages endpoint rejects images with 403; images work on the OpenAI-compatible /v1/chat/completions endpoint. See Hermes Agent #15715."
|
||||
);
|
||||
});
|
||||
|
||||
it("minimax-cn uses openai format (not claude) so images work via /v1/chat/completions", () => {
|
||||
const entry = REGISTRY["minimax-cn"];
|
||||
assert.ok(entry, "minimax-cn registry entry must exist");
|
||||
assert.equal(
|
||||
entry.format,
|
||||
"openai",
|
||||
"minimax-cn must use openai format — parity with minimax; the Anthropic endpoint on api.minimaxi.com also rejects images."
|
||||
);
|
||||
});
|
||||
|
||||
it("nvidia provider does NOT list minimaxai/minimax-m3 (removed in #3329 — 404 upstream)", () => {
|
||||
const entry = REGISTRY.nvidia;
|
||||
assert.ok(entry, "nvidia registry entry must exist");
|
||||
|
||||
@@ -137,12 +137,12 @@ describe("responseSanitizer/reasoning — MiniMax M3 textual reasoning-tag route
|
||||
});
|
||||
|
||||
describe("responseSanitizer/reasoning — MiniMax M3 fix regression guards", () => {
|
||||
it("direct minimax tier (claude format) stays unaffected", () => {
|
||||
it("direct minimax tier (openai format) stays unaffected for textual reasoning tags", () => {
|
||||
assert.equal(isTextualReasoningTagNativeRoute("minimax", "minimax-m3"), false);
|
||||
assert.equal(shouldParseTextualReasoningTags("minimax", "MiniMax-M3"), false);
|
||||
});
|
||||
|
||||
it("direct minimax-cn tier (claude format) stays unaffected", () => {
|
||||
it("direct minimax-cn tier (openai format) stays unaffected for textual reasoning tags", () => {
|
||||
assert.equal(isTextualReasoningTagNativeRoute("minimax-cn", "minimax-m3"), false);
|
||||
assert.equal(shouldParseTextualReasoningTags("minimax-cn", "MiniMax-M3"), false);
|
||||
});
|
||||
|
||||
@@ -145,14 +145,14 @@ test("preserves zero timeout so readiness checks can be disabled", () => {
|
||||
assert.deepEqual(result.reasons, ["disabled"]);
|
||||
});
|
||||
|
||||
test("bumps small requests to third-party Claude-format replicas (Minimax M3, ZAI, bailian, agentrouter) — guards against #3825-class false 504s on long reasoning warm-ups", () => {
|
||||
// Provider registry lists Minimax with `format: "claude"` — the readiness budget
|
||||
test("bumps small requests to third-party Claude-format replicas (agentrouter, ZAI, bailian) — guards against #3825-class false 504s on long reasoning warm-ups", () => {
|
||||
// Provider registry lists agentrouter with `format: "claude"` — the readiness budget
|
||||
// must fire UNCONDITIONALLY for those replicas, like the codex_gpt_5_5_high
|
||||
// bump, because their reasoning warm-ups routinely exceed the default 80s window.
|
||||
const result = resolveStreamReadinessTimeout({
|
||||
baseTimeoutMs: 80_000,
|
||||
provider: "minimax",
|
||||
model: "MiniMax-M3",
|
||||
provider: "agentrouter",
|
||||
model: "claude-opus-4-8",
|
||||
body: { messages: items(3), tools: tools(2) },
|
||||
});
|
||||
|
||||
@@ -163,6 +163,23 @@ test("bumps small requests to third-party Claude-format replicas (Minimax M3, ZA
|
||||
);
|
||||
});
|
||||
|
||||
test("does NOT bump Minimax (M3) — #3110 moved it from claude to openai format so images work, and the readiness bump is keyed off the registry's `format: \"claude\"` field", () => {
|
||||
// Minimax's replica quirk (long reasoning warm-up) hasn't changed, but this
|
||||
// policy intentionally keys off the translator format, not the provider
|
||||
// name — the registry is the single source of truth (see isClaudeFormatReasoningProvider
|
||||
// doc comment). Now that minimax routes through the OpenAI translator, it no
|
||||
// longer matches, mirroring the OpenAI/non-Claude exclusion below.
|
||||
const result = resolveStreamReadinessTimeout({
|
||||
baseTimeoutMs: 80_000,
|
||||
provider: "minimax",
|
||||
model: "MiniMax-M3",
|
||||
body: { messages: items(3), tools: tools(2) },
|
||||
});
|
||||
|
||||
assert.equal(result.timeoutMs, 80_000);
|
||||
assert.ok(!result.reasons.includes("claude_format_heavy_reasoning"));
|
||||
});
|
||||
|
||||
test("bumps ZAI (claude-format replica) readiness budget the same way", () => {
|
||||
const result = resolveStreamReadinessTimeout({
|
||||
baseTimeoutMs: 80_000,
|
||||
@@ -213,13 +230,13 @@ test("does NOT double-bump when codex-high reasoning and Claude-format replica b
|
||||
// Claude-format providers later, the readiness bump must not stack.
|
||||
const result = resolveStreamReadinessTimeout({
|
||||
baseTimeoutMs: 80_000,
|
||||
provider: "minimax",
|
||||
model: "MiniMax-M3-high",
|
||||
provider: "agentrouter",
|
||||
model: "claude-opus-4-8-high",
|
||||
body: { messages: items(3), tools: tools(2), reasoning_effort: "high" },
|
||||
});
|
||||
|
||||
// Should be bumped by exactly one reason — claude_format_heavy_reasoning —
|
||||
// because minimax is not a codex provider, the codex_* path never fires.
|
||||
// because agentrouter is not a codex provider, the codex_* path never fires.
|
||||
assert.equal(result.timeoutMs, 110_000);
|
||||
assert.ok(result.reasons.includes("claude_format_heavy_reasoning"));
|
||||
assert.ok(!result.reasons.includes("codex_gpt_5_5_high_reasoning"));
|
||||
@@ -229,8 +246,8 @@ test("caps Claude-format replica bump at the configured maxTimeoutMs", () => {
|
||||
const result = resolveStreamReadinessTimeout({
|
||||
baseTimeoutMs: 80_000,
|
||||
maxTimeoutMs: 100_000,
|
||||
provider: "minimax",
|
||||
model: "MiniMax-M3",
|
||||
provider: "agentrouter",
|
||||
model: "claude-opus-4-8",
|
||||
body: { messages: items(500), tools: tools(20), instructions: "x".repeat(800_000) },
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user