|
|
@@ -88,6 +88,32 @@ describe("ProviderTransform.options - setCacheKey", () => {
|
|
|
expect(result.promptCacheKey).toBe(sessionID)
|
|
|
})
|
|
|
|
|
|
+ test("should set promptCacheKey for the OpenAI SDK regardless of provider ID", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: {
|
|
|
+ ...mockModel,
|
|
|
+ providerID: "custom-openai",
|
|
|
+ api: { id: "gpt-5", url: "https://example.com", npm: "@ai-sdk/openai" },
|
|
|
+ },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.promptCacheKey).toBe(sessionID)
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should not set promptCacheKey for the OpenAI-compatible SDK by provider name", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: {
|
|
|
+ ...mockModel,
|
|
|
+ providerID: "openai",
|
|
|
+ api: { id: "gpt-5", url: "https://example.com", npm: "@ai-sdk/openai-compatible" },
|
|
|
+ },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.promptCacheKey).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
test("should not set promptCacheKey for openai when explicitly disabled", () => {
|
|
|
const openaiModel = {
|
|
|
...mockModel,
|
|
|
@@ -209,6 +235,70 @@ describe("ProviderTransform.options - setCacheKey", () => {
|
|
|
providerOptions: {},
|
|
|
})
|
|
|
expect(result.store).toBe(false)
|
|
|
+ expect(result.promptCacheKey).toBe(sessionID)
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should disable the Azure cache key without disabling store=false", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: {
|
|
|
+ ...mockModel,
|
|
|
+ providerID: "azure",
|
|
|
+ api: { id: "gpt-5", url: "https://azure.com", npm: "@ai-sdk/azure" },
|
|
|
+ },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: { setCacheKey: false },
|
|
|
+ })
|
|
|
+ expect(result.store).toBe(false)
|
|
|
+ expect(result.promptCacheKey).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should keep the Azure cache key for gpt-5.5 early return", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: {
|
|
|
+ ...mockModel,
|
|
|
+ providerID: "azure",
|
|
|
+ api: { id: "gpt-5.5", url: "https://azure.com", npm: "@ai-sdk/azure" },
|
|
|
+ },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.store).toBe(false)
|
|
|
+ expect(result.reasoningSummary).toBe("auto")
|
|
|
+ expect(result.promptCacheKey).toBe(sessionID)
|
|
|
+ })
|
|
|
+
|
|
|
+ for (const npm of ["@ai-sdk/deepinfra", "@ai-sdk/cerebras"]) {
|
|
|
+ test(`should set the snake-case cache key for ${npm}`, () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: { ...mockModel, providerID: "custom", api: { ...mockModel.api, npm } },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.prompt_cache_key).toBe(sessionID)
|
|
|
+ expect(result.promptCacheKey).toBeUndefined()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ test("should set promptCacheKey for the Mistral SDK", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: { ...mockModel, providerID: "custom", api: { ...mockModel.api, npm: "@ai-sdk/mistral" } },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.promptCacheKey).toBe(sessionID)
|
|
|
+ })
|
|
|
+
|
|
|
+ test("should not send an undocumented OpenRouter prompt_cache_key", () => {
|
|
|
+ const result = ProviderTransform.options({
|
|
|
+ model: {
|
|
|
+ ...mockModel,
|
|
|
+ providerID: "openrouter",
|
|
|
+ api: { ...mockModel.api, npm: "@openrouter/ai-sdk-provider" },
|
|
|
+ },
|
|
|
+ sessionID,
|
|
|
+ providerOptions: {},
|
|
|
+ })
|
|
|
+ expect(result.prompt_cache_key).toBeUndefined()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
@@ -722,6 +812,17 @@ describe("ProviderTransform.providerOptions", () => {
|
|
|
})
|
|
|
})
|
|
|
|
|
|
+ test("uses canonical sdk key for custom xAI models", () => {
|
|
|
+ const model = createModel({
|
|
|
+ providerID: "my-xai",
|
|
|
+ api: { id: "grok-4", url: "https://api.x.ai", npm: "@ai-sdk/xai" },
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(ProviderTransform.providerOptions(model, { promptCacheKey: "session" })).toEqual({
|
|
|
+ xai: { promptCacheKey: "session" },
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
test("forces reasoning for explicit effort even when model is not marked reasoning-capable", () => {
|
|
|
const model = createModel({
|
|
|
capabilities: {
|
|
|
@@ -3011,6 +3112,20 @@ describe("ProviderTransform.message - cache control on gateway", () => {
|
|
|
})
|
|
|
})
|
|
|
|
|
|
+ test("does not add explicit breakpoints when Anthropic automatic caching is enabled", () => {
|
|
|
+ const model = createModel({
|
|
|
+ providerID: "anthropic",
|
|
|
+ api: { id: "claude-sonnet-4", url: "https://api.anthropic.com", npm: "@ai-sdk/anthropic" },
|
|
|
+ })
|
|
|
+ const msgs = [
|
|
|
+ { role: "system", content: "You are a helpful assistant" },
|
|
|
+ { role: "user", content: "Hello" },
|
|
|
+ ] as any[]
|
|
|
+
|
|
|
+ const result = ProviderTransform.message(msgs, model, { cacheControl: { type: "ephemeral" } }) as any[]
|
|
|
+ expect(result.every((message) => message.providerOptions === undefined)).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
test("google-vertex-anthropic applies cache control", () => {
|
|
|
const model = createModel({
|
|
|
providerID: "google-vertex-anthropic",
|