mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 21:32:10 +03:00
fix: Claude passthrough (#1359), kimi-k2 reasoning (#1360), thinking leak (#1361), Ollama redirect (#1381)
- Eliminate lossy Claude→OpenAI→Claude round-trip for Claude-format providers - Expand isReasoner to include kimi-k2 and opencode-go provider models - Block thinking param leak to non-Claude antigravity models (gemini, gpt-oss) - Allow redirects for Ollama Cloud /v1/models endpoint (301)
This commit is contained in:
@@ -1164,52 +1164,16 @@ export async function handleChatCore({
|
||||
preserveCacheControl,
|
||||
});
|
||||
log?.debug?.("FORMAT", "claude-code-compatible bridge enabled");
|
||||
} else if (isClaudePassthrough && preserveCacheControl) {
|
||||
// Pure passthrough: when preserveCacheControl is true, forward the body
|
||||
// as-is without prior normalization. The OpenAI round-trip would strip
|
||||
// cache_control markers; even prepareClaudeRequest can alter structure.
|
||||
// Claude Code sends well-formed Messages API payloads — trust it.
|
||||
} else if (isClaudePassthrough) {
|
||||
// Pure passthrough: forward the body as-is without OpenAI round-trip.
|
||||
// The Claude→OpenAI→Claude double translation was lossy and corrupted
|
||||
// payloads at high context (150+ msgs, 100+ tools). Fix: #1359.
|
||||
// Claude Code sends well-formed Messages API payloads — trust them
|
||||
// regardless of combo strategy or cache_control settings.
|
||||
translatedBody = { ...body };
|
||||
translatedBody._disableToolPrefix = true;
|
||||
|
||||
log?.debug?.("FORMAT", "claude passthrough with cache_control preservation");
|
||||
} else if (isClaudePassthrough) {
|
||||
// Claude OAuth expects the same Claude Code prompt + structural normalization
|
||||
// as the OpenAI-compatible chat path. Round-trip through OpenAI to reuse the
|
||||
// working Claude translator instead of forwarding raw Messages payloads.
|
||||
const normalizeToolCallId = getModelNormalizeToolCallId(
|
||||
provider || "",
|
||||
model || "",
|
||||
sourceFormat
|
||||
);
|
||||
const preserveDeveloperRole = getModelPreserveOpenAIDeveloperRole(
|
||||
provider || "",
|
||||
model || "",
|
||||
sourceFormat
|
||||
);
|
||||
translatedBody = translateRequest(
|
||||
FORMATS.CLAUDE,
|
||||
FORMATS.OPENAI,
|
||||
model,
|
||||
{ ...body },
|
||||
stream,
|
||||
credentials,
|
||||
provider,
|
||||
reqLogger,
|
||||
{ normalizeToolCallId, preserveDeveloperRole, preserveCacheControl }
|
||||
);
|
||||
translatedBody = translateRequest(
|
||||
FORMATS.OPENAI,
|
||||
FORMATS.CLAUDE,
|
||||
model,
|
||||
{ ...translatedBody, _disableToolPrefix: true },
|
||||
stream,
|
||||
credentials,
|
||||
provider,
|
||||
reqLogger,
|
||||
{ normalizeToolCallId, preserveDeveloperRole, preserveCacheControl }
|
||||
);
|
||||
log?.debug?.("FORMAT", "claude->openai->claude normalized passthrough");
|
||||
log?.debug?.("FORMAT", `claude passthrough (preserveCache=${preserveCacheControl})`);
|
||||
} else {
|
||||
translatedBody = { ...body };
|
||||
|
||||
|
||||
@@ -207,7 +207,9 @@ export function translateRequest(
|
||||
// Inject reasoning_content = "" for DeepSeek/Reasoning models assistant messages with tool_calls
|
||||
// if omitted by the client, to avoid upstream 400 errors (e.g. "Messages with role 'assistant' that contain tool_calls must also include reasoning_content")
|
||||
const isReasoner =
|
||||
provider === "deepseek" || (typeof model === "string" && /r1|reason/i.test(model));
|
||||
provider === "deepseek" ||
|
||||
provider === "opencode-go" ||
|
||||
(typeof model === "string" && /r1|reason|kimi-k2/i.test(model));
|
||||
if (isReasoner && result.messages && Array.isArray(result.messages)) {
|
||||
for (const msg of result.messages) {
|
||||
if (
|
||||
|
||||
@@ -892,6 +892,8 @@ export async function GET(
|
||||
...SAFE_OUTBOUND_FETCH_PRESETS.modelsPagination,
|
||||
guard: getProviderOutboundGuard(),
|
||||
proxyConfig: proxy,
|
||||
// Ollama Cloud /v1/models returns 301 redirects (#1381)
|
||||
...(provider === "ollama-cloud" ? { allowRedirect: true } : {}),
|
||||
...fetchOptions,
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ const REASONING_UNSUPPORTED_PATTERNS = [
|
||||
"antigravity/claude-sonnet-4-6",
|
||||
"antigravity/claude-sonnet-4-5",
|
||||
"antigravity/claude-sonnet-4",
|
||||
// Non-Claude antigravity models don't support thinking params (#1361)
|
||||
"antigravity/gemini-",
|
||||
"antigravity/gpt-oss-",
|
||||
"antigravity/gemini-3",
|
||||
"antigravity/tab_",
|
||||
];
|
||||
|
||||
type CapabilityInput =
|
||||
|
||||
Reference in New Issue
Block a user