fix(providers): resolve 400 errors for GLM and Antigravity Claude adapter

This commit addresses issues #1514, #1520, and #1522. It ensures cache_control is only injected for supported Anthropic models and removes Gemini-specific validation tools from Vertex AI Claude adapter envelopes.
This commit is contained in:
diegosouzapw
2026-04-23 01:25:34 -03:00
parent 1c6c21fa9a
commit e628f0ea0d
2 changed files with 21 additions and 15 deletions

View File

@@ -148,11 +148,14 @@ export function prepareClaudeRequest(
): ClaudeRequestBody {
// 1. System: remove all cache_control, add only to last block with ttl 1h
// In passthrough mode, preserve existing cache_control markers
const supportsPromptCaching =
provider === "claude" || provider?.startsWith?.("anthropic-compatible-");
const systemBlocks = body.system;
if (systemBlocks && Array.isArray(systemBlocks) && !preserveCacheControl) {
body.system = systemBlocks.map((block, i) => {
const { cache_control, ...rest } = block;
if (i === systemBlocks.length - 1) {
if (i === systemBlocks.length - 1 && supportsPromptCaching) {
return { ...rest, cache_control: { type: "ephemeral", ttl: "1h" } };
}
return rest;
@@ -217,7 +220,7 @@ export function prepareClaudeRequest(
// - cache the second-to-last user turn for conversation reuse
// - cache the last assistant turn so the next user turn can reuse it
// Skip in passthrough mode to preserve client's cache_control markers
if (!preserveCacheControl) {
if (!preserveCacheControl && supportsPromptCaching) {
const userMessageIndexes = filtered.reduce<number[]>((indexes, msg, index) => {
if (msg?.role === "user") indexes.push(index);
return indexes;
@@ -238,7 +241,12 @@ export function prepareClaudeRequest(
if (msg.role === "assistant" && content.length > 0) {
// Add cache_control to last block of first (from end) assistant with content
// Skip in passthrough mode to preserve client's cache_control markers
if (!preserveCacheControl && !lastAssistantProcessed && markMessageCacheControl(msg)) {
if (
!preserveCacheControl &&
supportsPromptCaching &&
!lastAssistantProcessed &&
markMessageCacheControl(msg)
) {
lastAssistantProcessed = true;
}
@@ -283,10 +291,12 @@ export function prepareClaudeRequest(
const { cache_control, ...rest } = tool;
return rest;
});
for (let i = body.tools.length - 1; i >= 0; i--) {
if (!body.tools[i].defer_loading) {
body.tools[i].cache_control = { type: "ephemeral", ttl: "1h" };
break;
if (supportsPromptCaching) {
for (let i = body.tools.length - 1; i >= 0; i--) {
if (!body.tools[i].defer_loading) {
body.tools[i].cache_control = { type: "ephemeral", ttl: "1h" };
break;
}
}
}
}

View File

@@ -538,27 +538,23 @@ function wrapInCloudCodeEnvelopeForClaude(model, claudeRequest, credentials = nu
});
if (geminiTools) {
envelope.request.tools = geminiTools;
envelope.request.toolConfig = {
functionCallingConfig: { mode: "VALIDATED" },
};
}
}
// Add system instruction (Antigravity default)
const defaultPart = { text: ANTIGRAVITY_DEFAULT_SYSTEM };
const systemParts = [defaultPart];
let combinedSystemText = ANTIGRAVITY_DEFAULT_SYSTEM;
if (claudeRequest.system) {
if (Array.isArray(claudeRequest.system)) {
for (const block of claudeRequest.system) {
if (block.text) systemParts.push({ text: block.text });
if (block.text) combinedSystemText += "\n\n" + block.text;
}
} else if (typeof claudeRequest.system === "string") {
systemParts.push({ text: claudeRequest.system });
combinedSystemText += "\n\n" + claudeRequest.system;
}
}
envelope.request.systemInstruction = { role: "user", parts: systemParts };
envelope.request.systemInstruction = { role: "user", parts: [{ text: combinedSystemText }] };
const changedToolNameMap = buildChangedToolNameMap(toolNameMap);
if (changedToolNameMap) {