feat(providers): let custom connections opt into prompt-cache capability (#6880) (#7257)

Add a per-connection cache capability override (supportsPromptCaching,
cacheControlPassthrough) stored in provider_specific_data.cache, consulted
first by providerSupportsCaching() / providerHonorsOpenAIFormatCacheControl()
before falling back to the hardcoded CACHING_PROVIDERS name sets. Unblocks
prompt_cache_key injection, the compression cache-aware guard, and
cache_control passthrough for openai-compatible-chat-<uuid>-style custom
connections that can never match the hardcoded provider-name sets. Default
(no override) is byte-identical to current behavior.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-17 10:41:09 -03:00
committed by GitHub
parent 98966fdac9
commit 6c8392fa45
10 changed files with 393 additions and 25 deletions

View File

@@ -15,6 +15,44 @@ function isHttpUrl(value: string): boolean {
const CODEX_REASONING_EFFORT_VALUES = new Set(["none", "low", "medium", "high", "xhigh", "max"]);
const REQUEST_DEFAULT_SERVICE_TIER_VALUES = new Set(["default", "priority", "fast", "flex"]);
const CACHE_PASSTHROUGH_VALUES = new Set(["strip", "openai-format", "claude-format"]);
// #6880 — per-connection prompt-cache capability override, extracted so
// validateProviderSpecificData() stays under the complexity gate.
function validateCacheBlock(data: Record<string, unknown>, ctx: z.RefinementCtx): void {
const cache = data.cache;
if (cache === undefined) return;
if (!cache || typeof cache !== "object" || Array.isArray(cache)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "providerSpecificData.cache must be an object",
path: ["cache"],
});
return;
}
const cacheRecord = cache as Record<string, unknown>;
const supportsPromptCaching = cacheRecord.supportsPromptCaching;
if (supportsPromptCaching !== undefined && typeof supportsPromptCaching !== "boolean") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "providerSpecificData.cache.supportsPromptCaching must be a boolean",
path: ["cache", "supportsPromptCaching"],
});
}
const cacheControlPassthrough = cacheRecord.cacheControlPassthrough;
if (
cacheControlPassthrough !== undefined &&
(typeof cacheControlPassthrough !== "string" ||
!CACHE_PASSTHROUGH_VALUES.has(cacheControlPassthrough))
) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
'providerSpecificData.cache.cacheControlPassthrough must be one of "strip", "openai-format", "claude-format"',
path: ["cache", "cacheControlPassthrough"],
});
}
}
export function validateProviderSpecificData(
data: Record<string, unknown> | undefined,
@@ -163,6 +201,8 @@ export function validateProviderSpecificData(
}
}
validateCacheBlock(data, ctx);
const consoleApiKey = data.consoleApiKey;
if (consoleApiKey !== undefined && consoleApiKey !== null && typeof consoleApiKey !== "string") {
ctx.addIssue({