@@ -51,14 +51,14 @@ function resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention
|
||||
}
|
||||
|
||||
function getCacheControl(
|
||||
baseUrl: string,
|
||||
model: Model<"anthropic-messages">,
|
||||
cacheRetention?: CacheRetention,
|
||||
): { retention: CacheRetention; cacheControl?: CacheControlEphemeral } {
|
||||
const retention = resolveCacheRetention(cacheRetention);
|
||||
if (retention === "none") {
|
||||
return { retention };
|
||||
}
|
||||
const ttl = retention === "long" && baseUrl.includes("api.anthropic.com") ? "1h" : undefined;
|
||||
const ttl = retention === "long" && getAnthropicCompat(model).supportsLongCacheRetention ? "1h" : undefined;
|
||||
return {
|
||||
retention,
|
||||
cacheControl: { type: "ephemeral", ...(ttl && { ttl }) },
|
||||
@@ -166,6 +166,7 @@ const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
||||
function getAnthropicCompat(model: Model<"anthropic-messages">): Required<AnthropicMessagesCompat> {
|
||||
return {
|
||||
supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
|
||||
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -833,7 +834,7 @@ function buildParams(
|
||||
isOAuthToken: boolean,
|
||||
options?: AnthropicOptions,
|
||||
): MessageCreateParamsStreaming {
|
||||
const { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);
|
||||
const { cacheControl } = getCacheControl(model, options?.cacheRetention);
|
||||
const params: MessageCreateParamsStreaming = {
|
||||
model: model.id,
|
||||
messages: convertMessages(context.messages, model, isOAuthToken, cacheControl),
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
CacheRetention,
|
||||
Context,
|
||||
Model,
|
||||
OpenAIResponsesCompat,
|
||||
SimpleStreamOptions,
|
||||
StreamFunction,
|
||||
StreamOptions,
|
||||
@@ -35,18 +36,18 @@ function resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention
|
||||
return "short";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prompt cache retention based on cacheRetention and base URL.
|
||||
* Only applies to direct OpenAI API calls (api.openai.com).
|
||||
*/
|
||||
function getPromptCacheRetention(baseUrl: string, cacheRetention: CacheRetention): "24h" | undefined {
|
||||
if (cacheRetention !== "long") {
|
||||
return undefined;
|
||||
}
|
||||
if (baseUrl.includes("api.openai.com")) {
|
||||
return "24h";
|
||||
}
|
||||
return undefined;
|
||||
function getCompat(model: Model<"openai-responses">): Required<OpenAIResponsesCompat> {
|
||||
return {
|
||||
sendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true,
|
||||
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
||||
};
|
||||
}
|
||||
|
||||
function getPromptCacheRetention(
|
||||
compat: Required<OpenAIResponsesCompat>,
|
||||
cacheRetention: CacheRetention,
|
||||
): "24h" | undefined {
|
||||
return cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : undefined;
|
||||
}
|
||||
|
||||
// OpenAI Responses-specific options
|
||||
@@ -169,6 +170,7 @@ function createClient(
|
||||
apiKey = process.env.OPENAI_API_KEY;
|
||||
}
|
||||
|
||||
const compat = getCompat(model);
|
||||
const headers = { ...model.headers };
|
||||
if (model.provider === "github-copilot") {
|
||||
const hasImages = hasCopilotVisionInput(context.messages);
|
||||
@@ -180,7 +182,7 @@ function createClient(
|
||||
}
|
||||
|
||||
if (sessionId) {
|
||||
if (model.compat?.sendSessionIdHeader !== false) {
|
||||
if (compat.sendSessionIdHeader) {
|
||||
headers.session_id = sessionId;
|
||||
}
|
||||
headers["x-client-request-id"] = sessionId;
|
||||
@@ -203,12 +205,13 @@ function buildParams(model: Model<"openai-responses">, context: Context, options
|
||||
const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);
|
||||
|
||||
const cacheRetention = resolveCacheRetention(options?.cacheRetention);
|
||||
const compat = getCompat(model);
|
||||
const params: ResponseCreateParamsStreaming = {
|
||||
model: model.id,
|
||||
input: messages,
|
||||
stream: true,
|
||||
prompt_cache_key: cacheRetention === "none" ? undefined : options?.sessionId,
|
||||
prompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),
|
||||
prompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),
|
||||
store: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -296,12 +296,16 @@ export interface OpenAICompletionsCompat {
|
||||
cacheControlFormat?: "anthropic";
|
||||
/** Whether to send known session-affinity headers (`session_id`, `x-client-request-id`, `x-session-affinity`) from `options.sessionId` when caching is enabled. Default: false. */
|
||||
sendSessionAffinityHeaders?: boolean;
|
||||
/** Whether the provider supports long prompt cache retention (`prompt_cache_retention: "24h"` or Anthropic-style `cache_control.ttl: "1h"`, depending on format). Default: true. */
|
||||
supportsLongCacheRetention?: boolean;
|
||||
}
|
||||
|
||||
/** Compatibility settings for OpenAI Responses APIs. */
|
||||
export interface OpenAIResponsesCompat {
|
||||
/** Whether to send the OpenAI `session_id` cache-affinity header from `options.sessionId` when caching is enabled. Default: true. */
|
||||
sendSessionIdHeader?: boolean;
|
||||
/** Whether the provider supports `prompt_cache_retention: "24h"`. Default: true. */
|
||||
supportsLongCacheRetention?: boolean;
|
||||
}
|
||||
|
||||
/** Compatibility settings for Anthropic Messages-compatible APIs. */
|
||||
@@ -314,6 +318,8 @@ export interface AnthropicMessagesCompat {
|
||||
* Default: true.
|
||||
*/
|
||||
supportsEagerToolInputStreaming?: boolean;
|
||||
/** Whether the provider supports Anthropic long cache retention (`cache_control.ttl: "1h"`). Default: true. */
|
||||
supportsLongCacheRetention?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user