diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json index 92e7596606..c3906af85e 100644 --- a/client/src/locales/en/translation.json +++ b/client/src/locales/en/translation.json @@ -226,6 +226,7 @@ "com_endpoint_anthropic_effort": "Controls how much computational effort Claude applies. Lower effort saves tokens and reduces latency; higher effort produces more thorough responses. 'Max' enables the deepest reasoning on supported adaptive-thinking models.", "com_endpoint_anthropic_maxoutputtokens": "Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses. Note: models may stop before reaching this maximum.", "com_endpoint_anthropic_prompt_cache": "Prompt caching allows reusing large context or instructions across API calls, reducing costs and latency", + "com_endpoint_anthropic_prompt_cache_ttl": "How long a cached prompt prefix stays warm between requests. Leave unset to use the provider default (1 hour). The 1-hour cache keeps the prefix warm across longer gaps at a higher one-time write cost; choose 5 minutes for the legacy behavior.", "com_endpoint_anthropic_temp": "Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks. We recommend altering this or Top P but not both.", "com_endpoint_anthropic_thinking": "Enables internal reasoning for supported Claude models. For newer models (Opus 4.6+), uses adaptive thinking controlled by the Effort parameter. For legacy models, requires \"Thinking Budget\" to be set and lower than \"Max Output Tokens\".", "com_endpoint_anthropic_thinking_budget": "Determines the max number of tokens Claude is allowed use for its internal reasoning process. Larger budgets can improve response quality by enabling more thorough analysis for complex problems, although Claude may not use the entire budget allocated, especially at ranges above 32K. This setting must be lower than \"Max Output Tokens.\"", @@ -336,6 +337,8 @@ "com_endpoint_presets": "presets", "com_endpoint_presets_clear_warning": "Are you sure you want to clear all presets? This is irreversible.", "com_endpoint_prompt_cache": "Use Prompt Caching", + "com_endpoint_prompt_cache_ttl": "Prompt Cache Duration", + "com_endpoint_prompt_cache_ttl_default": "Default (1 hour)", "com_endpoint_prompt_prefix": "Custom Instructions", "com_endpoint_prompt_prefix_assistants": "Additional Instructions", "com_endpoint_prompt_prefix_assistants_placeholder": "Set additional instructions or context on top of the Assistant's main instructions. Ignored if empty.", diff --git a/package-lock.json b/package-lock.json index 0d9398d548..35b861e8f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44177,7 +44177,7 @@ }, "packages/data-provider": { "name": "librechat-data-provider", - "version": "0.8.505", + "version": "0.8.506", "license": "ISC", "dependencies": { "axios": "^1.16.0", diff --git a/packages/api/src/endpoints/anthropic/llm.spec.ts b/packages/api/src/endpoints/anthropic/llm.spec.ts index c48e641971..58f466f5e0 100644 --- a/packages/api/src/endpoints/anthropic/llm.spec.ts +++ b/packages/api/src/endpoints/anthropic/llm.spec.ts @@ -356,6 +356,46 @@ describe('getLLMConfig', () => { expect(result.llmConfig.promptCache).toBe(true); }); + it('should pass promptCacheTtl to llmConfig when configured', () => { + const result = getLLMConfig('test-api-key', { + modelOptions: { + model: 'claude-3-5-sonnet', + promptCache: true, + promptCacheTtl: '1h', + }, + }); + + expect(result.llmConfig.promptCache).toBe(true); + expect((result.llmConfig as Record).promptCacheTtl).toBe('1h'); + }); + + it('should omit promptCacheTtl when unset so the agents SDK applies its default', () => { + const result = getLLMConfig('test-api-key', { + modelOptions: { + model: 'claude-3-5-sonnet', + promptCache: true, + }, + }); + + expect(result.llmConfig.promptCache).toBe(true); + expect((result.llmConfig as Record).promptCacheTtl).toBeUndefined(); + }); + + it('should drop promptCacheTtl when promptCache is dropped via dropParams', () => { + const result = getLLMConfig('test-api-key', { + modelOptions: { + model: 'claude-3-5-sonnet', + promptCache: true, + promptCacheTtl: '1h', + }, + dropParams: ['promptCache'], + }); + + /** A dropped cache must not leave an orphaned TTL on the request. */ + expect(result.llmConfig.promptCache).toBeUndefined(); + expect((result.llmConfig as Record).promptCacheTtl).toBeUndefined(); + }); + it('should handle thinking and thinkingBudget options', () => { const result = getLLMConfig('test-api-key', { modelOptions: { diff --git a/packages/api/src/endpoints/anthropic/llm.ts b/packages/api/src/endpoints/anthropic/llm.ts index 9b1063c49b..512401d0ba 100644 --- a/packages/api/src/endpoints/anthropic/llm.ts +++ b/packages/api/src/endpoints/anthropic/llm.ts @@ -114,6 +114,8 @@ function getLLMConfig( const systemOptions = { thinking: options.modelOptions?.thinking ?? anthropicSettings.thinking.default, promptCache: options.modelOptions?.promptCache ?? anthropicSettings.promptCache.default, + promptCacheTtl: + options.modelOptions?.promptCacheTtl ?? anthropicSettings.promptCacheTtl.default, thinkingBudget: options.modelOptions?.thinkingBudget ?? anthropicSettings.thinkingBudget.default, effort: options.modelOptions?.effort ?? anthropicSettings.effort.default, @@ -126,6 +128,7 @@ function getLLMConfig( if (options.modelOptions) { delete options.modelOptions.thinking; delete options.modelOptions.promptCache; + delete options.modelOptions.promptCacheTtl; delete options.modelOptions.thinkingBudget; delete options.modelOptions.effort; delete options.modelOptions.thinkingDisplay; @@ -222,6 +225,10 @@ function getLLMConfig( /** Pass promptCache boolean for downstream cache_control application */ if (supportsCacheControl) { (requestOptions as Record).promptCache = true; + /** Pass an explicit TTL when configured; otherwise the agents SDK defaults to 1h */ + if (systemOptions.promptCacheTtl != null) { + (requestOptions as Record).promptCacheTtl = systemOptions.promptCacheTtl; + } } const headers = getClaudeHeaders(requestOptions.model ?? '', supportsCacheControl); @@ -297,6 +304,11 @@ function getLLMConfig( delete (requestOptions.invocationKwargs as Record)[param]; } }); + + /** A TTL is meaningless without caching — drop it alongside promptCache. */ + if (options.dropParams.includes('promptCache')) { + delete (requestOptions as Record).promptCacheTtl; + } } if (shouldOmitSamplingParameters) { diff --git a/packages/api/src/endpoints/openai/config.spec.ts b/packages/api/src/endpoints/openai/config.spec.ts index 84ab68f92c..ee49fd8fab 100644 --- a/packages/api/src/endpoints/openai/config.spec.ts +++ b/packages/api/src/endpoints/openai/config.spec.ts @@ -920,6 +920,46 @@ describe('getOpenAIConfig', () => { expect(result.provider).toBe('openrouter'); }); + it('should honor a TTL-only selection for OpenRouter (promptCache defaulted on)', () => { + /** + * Reproduces selecting only the promptCacheTtl dropdown without toggling + * the promptCache switch: modelOptions carries the TTL but not promptCache. + * OPENROUTER_DEFAULT_PARAMS still resolves caching on, so the TTL survives. + */ + const result = getOpenAIConfig( + mockApiKey, + { + modelOptions: { + model: 'anthropic/claude-sonnet-4.6', + promptCacheTtl: '1h', + } as Record, + }, + 'openrouter', + ); + + expect(result.llmConfig.promptCache).toBe(true); + expect((result.llmConfig as Record).promptCacheTtl).toBe('1h'); + expect(result.provider).toBe('openrouter'); + }); + + it('should drop the OpenRouter TTL when promptCache is explicitly disabled', () => { + const result = getOpenAIConfig( + mockApiKey, + { + modelOptions: { + model: 'anthropic/claude-sonnet-4.6', + promptCache: false, + promptCacheTtl: '1h', + } as Record, + }, + 'openrouter', + ); + + expect(result.llmConfig.promptCache).toBeUndefined(); + expect((result.llmConfig as Record).promptCacheTtl).toBeUndefined(); + expect(result.provider).toBe('openrouter'); + }); + it('should handle web_search with OpenRouter using plugins format', () => { const modelOptions = { model: 'gpt-4', diff --git a/packages/api/src/endpoints/openai/llm.spec.ts b/packages/api/src/endpoints/openai/llm.spec.ts index cb38b294b1..ec6330e0ea 100644 --- a/packages/api/src/endpoints/openai/llm.spec.ts +++ b/packages/api/src/endpoints/openai/llm.spec.ts @@ -5,8 +5,8 @@ import { ReasoningSummary, ReasoningParameterFormat, } from 'librechat-data-provider'; -import { getOpenAILLMConfig, extractDefaultParams, applyDefaultParams } from './llm'; import type * as t from '~/types'; +import { getOpenAILLMConfig, extractDefaultParams, applyDefaultParams } from './llm'; describe('getOpenAILLMConfig', () => { describe('Basic Configuration', () => { @@ -1100,6 +1100,44 @@ describe('getOpenAILLMConfig', () => { expect(dropped.llmConfig).not.toHaveProperty('promptCache'); }); + it('should resolve OpenRouter promptCacheTtl default/add/drop params', () => { + const fromDefault = getOpenAILLMConfig({ + apiKey: 'test-api-key', + streaming: true, + useOpenRouter: true, + defaultParams: { promptCache: true, promptCacheTtl: '1h' }, + modelOptions: { + model: 'anthropic/claude-sonnet-4.6', + }, + }); + const overridden = getOpenAILLMConfig({ + apiKey: 'test-api-key', + streaming: true, + useOpenRouter: true, + defaultParams: { promptCache: true, promptCacheTtl: '1h' }, + addParams: { promptCacheTtl: '5m' }, + modelOptions: { + model: 'anthropic/claude-sonnet-4.6', + }, + }); + const dropped = getOpenAILLMConfig({ + apiKey: 'test-api-key', + streaming: true, + useOpenRouter: true, + defaultParams: { promptCache: true, promptCacheTtl: '1h' }, + dropParams: ['promptCacheTtl'], + modelOptions: { + model: 'anthropic/claude-sonnet-4.6', + }, + }); + + expect((fromDefault.llmConfig as Record).promptCacheTtl).toBe('1h'); + expect((overridden.llmConfig as Record).promptCacheTtl).toBe('5m'); + /** promptCache stays on, but the TTL is dropped so the SDK applies its default */ + expect(dropped.llmConfig).toHaveProperty('promptCache', true); + expect((dropped.llmConfig as Record).promptCacheTtl).toBeUndefined(); + }); + it('should set includeReasoningContent for DeepSeek models via OpenRouter', () => { const result = getOpenAILLMConfig({ apiKey: 'test-api-key', diff --git a/packages/api/src/endpoints/openai/llm.ts b/packages/api/src/endpoints/openai/llm.ts index 2894c5a853..448c9a653d 100644 --- a/packages/api/src/endpoints/openai/llm.ts +++ b/packages/api/src/endpoints/openai/llm.ts @@ -454,10 +454,13 @@ export function getOpenAILLMConfig({ verbosity, web_search, promptCache, + promptCacheTtl, frequency_penalty, presence_penalty, ...modelOptions - } = cleanedModelOptions as Partial; + } = cleanedModelOptions as Partial< + t.OpenAIParameters & { promptCache?: boolean; promptCacheTtl?: '5m' | '1h' } + >; const llmConfig = Object.assign( { @@ -488,6 +491,7 @@ export function getOpenAILLMConfig({ let enableWebSearch = web_search; let enablePromptCache = promptCache; + let promptCacheTtlValue = promptCacheTtl; /** Apply defaultParams first - only if fields are undefined */ if (defaultParams && typeof defaultParams === 'object') { @@ -504,6 +508,12 @@ export function getOpenAILLMConfig({ } continue; } + if (key === 'promptCacheTtl') { + if (promptCacheTtlValue === undefined && (value === '5m' || value === '1h')) { + promptCacheTtlValue = value; + } + continue; + } if (key === 'reasoning_effort') { if (!reasoningEffort && typeof value === 'string') { reasoningEffort = value as OpenAILLMConfig['reasoning_effort']; @@ -555,6 +565,12 @@ export function getOpenAILLMConfig({ } continue; } + if (key === 'promptCacheTtl') { + if (value === '5m' || value === '1h') { + promptCacheTtlValue = value; + } + continue; + } if (key === 'reasoning_effort') { if (typeof value === 'string' || value == null) { reasoningEffort = value as OpenAILLMConfig['reasoning_effort']; @@ -617,6 +633,9 @@ export function getOpenAILLMConfig({ if (dropParams && dropParams.includes('promptCache')) { enablePromptCache = false; } + if (dropParams && dropParams.includes('promptCacheTtl')) { + promptCacheTtlValue = undefined; + } if (useOpenRouter && enableWebSearch) { /** OpenRouter expects web search as a plugins parameter */ @@ -629,6 +648,10 @@ export function getOpenAILLMConfig({ } if (useOpenRouter && enablePromptCache === true) { llmConfig.promptCache = true; + /** Pass an explicit TTL when configured; otherwise the agents SDK defaults to 1h */ + if (promptCacheTtlValue != null) { + llmConfig.promptCacheTtl = promptCacheTtlValue; + } } if (!useOpenRouter) { diff --git a/packages/api/src/types/openai.ts b/packages/api/src/types/openai.ts index a04d2cb815..7007cc447e 100644 --- a/packages/api/src/types/openai.ts +++ b/packages/api/src/types/openai.ts @@ -33,6 +33,7 @@ export type OAIClientOptions = Omit & { /** Replays `reasoning_content` on tool-bearing turns (DeepSeek thinking-mode, #13366). */ includeReasoningContent?: boolean; promptCache?: boolean; + promptCacheTtl?: '5m' | '1h'; _lc_stream_delay?: number; verbosity?: string | null; }; diff --git a/packages/data-provider/package.json b/packages/data-provider/package.json index 190e87353f..fa305e9c6c 100644 --- a/packages/data-provider/package.json +++ b/packages/data-provider/package.json @@ -1,6 +1,6 @@ { "name": "librechat-data-provider", - "version": "0.8.505", + "version": "0.8.506", "description": "data services for librechat apps", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/packages/data-provider/specs/bedrock.spec.ts b/packages/data-provider/specs/bedrock.spec.ts index f8dfd7f22a..1d0a804fc3 100644 --- a/packages/data-provider/specs/bedrock.spec.ts +++ b/packages/data-provider/specs/bedrock.spec.ts @@ -1271,4 +1271,34 @@ describe('bedrockInputParser', () => { expect(amrf.reasoning_config).toBeUndefined(); }); }); + + describe('promptCacheTtl tied to promptCache', () => { + test('preserves promptCacheTtl when caching is enabled (claude default)', () => { + const result = bedrockInputParser.parse({ + model: 'anthropic.claude-opus-4-6-v1', + promptCacheTtl: '1h', + }) as Record; + expect(result.promptCache).toBe(true); + expect(result.promptCacheTtl).toBe('1h'); + }); + + test('clears promptCacheTtl when promptCache is explicitly disabled', () => { + const result = bedrockInputParser.parse({ + model: 'anthropic.claude-opus-4-6-v1', + promptCache: false, + promptCacheTtl: '1h', + }) as Record; + expect(result.promptCacheTtl).toBeUndefined(); + }); + + test('clears promptCache and promptCacheTtl for non-caching models', () => { + const result = bedrockInputParser.parse({ + model: 'meta.llama3-1-70b-instruct-v1:0', + promptCache: true, + promptCacheTtl: '1h', + }) as Record; + expect(result.promptCache).toBeUndefined(); + expect(result.promptCacheTtl).toBeUndefined(); + }); + }); }); diff --git a/packages/data-provider/src/bedrock.ts b/packages/data-provider/src/bedrock.ts index 84ec3708dc..7e97d594a4 100644 --- a/packages/data-provider/src/bedrock.ts +++ b/packages/data-provider/src/bedrock.ts @@ -256,6 +256,7 @@ export const bedrockInputSchema = s.tConversationSchema thinkingDisplay: true, reasoning_effort: true, promptCache: true, + promptCacheTtl: true, /* Catch-all fields */ topK: true, additionalModelRequestFields: true, @@ -312,6 +313,7 @@ export const bedrockInputParser = s.tConversationSchema thinkingDisplay: true, reasoning_effort: true, promptCache: true, + promptCacheTtl: true, /* Catch-all fields */ topK: true, additionalModelRequestFields: true, @@ -336,6 +338,7 @@ export const bedrockInputParser = s.tConversationSchema 'topP', 'stop', 'promptCache', + 'promptCacheTtl', ]; const additionalFields: Record = {}; @@ -503,6 +506,15 @@ export const bedrockInputParser = s.tConversationSchema typedData.promptCache = undefined; } + /** + * A cache TTL is meaningless without caching — tie it to promptCache. When + * caching is off or unsupported for the model (cleared above), drop the TTL + * so an unsupported `1h` is never sent on a non-caching Bedrock request. + */ + if (typedData.promptCache !== true) { + typedData.promptCacheTtl = undefined; + } + if (Object.keys(additionalFields).length > 0) { typedData.additionalModelRequestFields = { ...((typedData.additionalModelRequestFields as Record | undefined) || {}), diff --git a/packages/data-provider/src/parameterSettings.ts b/packages/data-provider/src/parameterSettings.ts index f3ff5deedc..39ff99d7c9 100644 --- a/packages/data-provider/src/parameterSettings.ts +++ b/packages/data-provider/src/parameterSettings.ts @@ -406,6 +406,22 @@ const anthropic: Record = { showDefault: false, columnSpan: 2, }, + promptCacheTtl: { + key: 'promptCacheTtl', + label: 'com_endpoint_prompt_cache_ttl', + labelCode: true, + description: 'com_endpoint_anthropic_prompt_cache_ttl', + descriptionCode: true, + type: 'enum', + default: anthropicSettings.promptCacheTtl.default, + options: ['5m', '1h'], + component: 'dropdown', + optionType: 'conversation', + showDefault: false, + placeholder: 'com_endpoint_prompt_cache_ttl_default', + placeholderCode: true, + columnSpan: 2, + }, thinking: { key: 'thinking', label: 'com_endpoint_thinking', @@ -552,6 +568,22 @@ const bedrock: Record = { showDefault: false, columnSpan: 2, }, + promptCacheTtl: { + key: 'promptCacheTtl', + label: 'com_endpoint_prompt_cache_ttl', + labelCode: true, + description: 'com_endpoint_anthropic_prompt_cache_ttl', + descriptionCode: true, + type: 'enum', + default: undefined, + options: ['5m', '1h'], + component: 'dropdown', + optionType: 'conversation', + showDefault: false, + placeholder: 'com_endpoint_prompt_cache_ttl_default', + placeholderCode: true, + columnSpan: 2, + }, reasoning_effort: { key: 'reasoning_effort', label: 'com_endpoint_reasoning_effort', @@ -792,7 +824,11 @@ const openAI: SettingsConfiguration = [ librechat.fileTokenLimit, ]; -const openRouter: SettingsConfiguration = [...openAI, anthropic.promptCache]; +const openRouter: SettingsConfiguration = [ + ...openAI, + anthropic.promptCache, + anthropic.promptCacheTtl, +]; const openAICol1: SettingsConfiguration = [ baseDefinitions.model as SettingDefinition, @@ -829,6 +865,7 @@ const anthropicConfig: SettingsConfiguration = [ anthropic.topK, librechat.resendFiles, anthropic.promptCache, + anthropic.promptCacheTtl, anthropic.thinking, anthropic.thinkingBudget, anthropic.effort, @@ -851,6 +888,7 @@ const anthropicCol2: SettingsConfiguration = [ anthropic.topK, librechat.resendFiles, anthropic.promptCache, + anthropic.promptCacheTtl, anthropic.thinking, anthropic.thinkingBudget, anthropic.effort, @@ -871,6 +909,7 @@ const bedrockAnthropic: SettingsConfiguration = [ librechat.resendFiles, bedrock.region, bedrock.promptCache, + bedrock.promptCacheTtl, anthropic.thinking, anthropic.thinkingBudget, anthropic.effort, @@ -911,6 +950,7 @@ const bedrockGeneral: SettingsConfiguration = [ librechat.resendFiles, bedrock.region, bedrock.promptCache, + bedrock.promptCacheTtl, librechat.fileTokenLimit, ]; @@ -930,6 +970,7 @@ const bedrockAnthropicCol2: SettingsConfiguration = [ librechat.resendFiles, bedrock.region, bedrock.promptCache, + bedrock.promptCacheTtl, anthropic.thinking, anthropic.thinkingBudget, anthropic.effort, @@ -982,6 +1023,7 @@ const bedrockGeneralCol2: SettingsConfiguration = [ librechat.resendFiles, bedrock.region, bedrock.promptCache, + bedrock.promptCacheTtl, librechat.fileTokenLimit, ]; @@ -1092,7 +1134,7 @@ export const presetSettings: Record< [EModelEndpoint.custom]: openAIColumns, [Providers.OPENROUTER]: { col1: openAICol1, - col2: [...openAICol2, anthropic.promptCache], + col2: [...openAICol2, anthropic.promptCache, anthropic.promptCacheTtl], }, [EModelEndpoint.anthropic]: { col1: anthropicCol1, diff --git a/packages/data-provider/src/schemas.ts b/packages/data-provider/src/schemas.ts index 960f965928..108968d350 100644 --- a/packages/data-provider/src/schemas.ts +++ b/packages/data-provider/src/schemas.ts @@ -520,6 +520,9 @@ export const anthropicSettings = { promptCache: { default: true as const, }, + promptCacheTtl: { + default: undefined, + }, thinking: { default: true as const, }, @@ -909,6 +912,7 @@ export const tConversationSchema = z.object({ max_tokens: coerceNumber.optional(), /* Anthropic */ promptCache: z.boolean().optional(), + promptCacheTtl: z.enum(['5m', '1h']).optional(), system: z.string().optional(), thinking: z.boolean().optional(), thinkingBudget: coerceNumber.optional(), @@ -1062,6 +1066,7 @@ export const tQueryParamsSchema = tConversationSchema maxOutputTokens: true, /** @endpoints anthropic */ promptCache: true, + promptCacheTtl: true, thinking: true, thinkingBudget: true, thinkingLevel: true, @@ -1368,7 +1373,7 @@ export const openAISchema = openAIBaseSchema .catch(() => ({})); export const openRouterSchema = openAIBaseSchema - .merge(tConversationSchema.pick({ promptCache: true })) + .merge(tConversationSchema.pick({ promptCache: true, promptCacheTtl: true })) .transform((obj: Partial) => removeNullishValues(obj, true)) .catch(() => ({})); @@ -1403,6 +1408,7 @@ export const anthropicBaseSchema = tConversationSchema.pick({ topK: true, resendFiles: true, promptCache: true, + promptCacheTtl: true, thinking: true, thinkingBudget: true, effort: true, diff --git a/packages/data-provider/src/types.ts b/packages/data-provider/src/types.ts index 6a8db985e8..7cbafbb536 100644 --- a/packages/data-provider/src/types.ts +++ b/packages/data-provider/src/types.ts @@ -53,6 +53,7 @@ export type TEndpointOption = Pick< | 'additionalModelRequestFields' // Anthropic-specific | 'promptCache' + | 'promptCacheTtl' | 'thinking' | 'thinkingBudget' | 'thinkingLevel' diff --git a/packages/data-schemas/src/schema/defaults.ts b/packages/data-schemas/src/schema/defaults.ts index 148a2b5f42..1014843f28 100644 --- a/packages/data-schemas/src/schema/defaults.ts +++ b/packages/data-schemas/src/schema/defaults.ts @@ -87,6 +87,9 @@ export const conversationPreset: { promptCache: { type: BooleanConstructor; }; + promptCacheTtl: { + type: StringConstructor; + }; thinking: { type: BooleanConstructor; }; @@ -256,6 +259,9 @@ export const conversationPreset: { promptCache: { type: Boolean, }, + promptCacheTtl: { + type: String, + }, thinking: { type: Boolean, }, diff --git a/packages/data-schemas/src/schema/preset.ts b/packages/data-schemas/src/schema/preset.ts index 5af5163fd3..5bc438b99b 100644 --- a/packages/data-schemas/src/schema/preset.ts +++ b/packages/data-schemas/src/schema/preset.ts @@ -28,6 +28,7 @@ export interface IPreset extends Document { file_ids?: string[]; resendImages?: boolean; promptCache?: boolean; + promptCacheTtl?: '5m' | '1h'; thinking?: boolean; thinkingBudget?: number; effort?: string; diff --git a/packages/data-schemas/src/types/convo.ts b/packages/data-schemas/src/types/convo.ts index e8a8415ffd..471b37bcee 100644 --- a/packages/data-schemas/src/types/convo.ts +++ b/packages/data-schemas/src/types/convo.ts @@ -27,6 +27,7 @@ export interface IConversation extends Document { file_ids?: string[]; resendImages?: boolean; promptCache?: boolean; + promptCacheTtl?: '5m' | '1h'; thinking?: boolean; thinkingBudget?: number; effort?: string;