diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 0cadd57200..9539ce35aa 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -39,12 +39,12 @@ export class DeepSeekHandler implements ApiHandler { if (chunk.usage) { yield { type: "usage", - inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) but we use this to do the truncation algo, so we can't report cache stats right now because of how deepseek api reports input AND the cache reads/writes, while anthropic reports them as separate tokens + inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) where the input tokens is the sum of the cache hits/misses, while anthropic reports them as separate tokens. This is important to know for 1) context management truncation algorithm, and 2) cost calculation (NOTE: we report both input and cache stats but for now set input price to 0 since all the cost calculation will be done using cache hits/misses) outputTokens: chunk.usage.completion_tokens || 0, // @ts-ignore-next-line - // cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, + cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, // @ts-ignore-next-line - // cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, + cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, } } } diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 8170d41afc..32e50de5d7 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -98,6 +98,10 @@ export class OpenRouterHandler implements ApiHandler { // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) + if (this.getModel().id === "deepseek/deepseek-chat") { + shouldApplyMiddleOutTransform = true + } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 78cc71b460..62ec46ee2d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -726,6 +726,13 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 0.3 modelInfo.cacheReadsPrice = 0.03 break + case "deepseek/deepseek-chat": + modelInfo.supportsPromptCache = true + // see api.ts/deepSeekModels for more info + modelInfo.inputPrice = 0 + modelInfo.cacheWritesPrice = 0.14 + modelInfo.cacheReadsPrice = 0.014 + break } models[rawModel.id] = modelInfo diff --git a/src/shared/api.ts b/src/shared/api.ts index 5f2b42b416..d87d13d272 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -359,10 +359,10 @@ export const deepSeekModels = { maxTokens: 8_000, contextWindow: 64_000, supportsImages: false, - supportsPromptCache: false, // technically supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it - inputPrice: 0.14, + supportsPromptCache: true, // supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it + inputPrice: 0, // technically there is no input price, it's all either a cache hit or miss (ApiOptions will not show this) outputPrice: 0.28, - // cacheWritesPrice: 0.14, - // cacheReadsPrice: 0.014, + cacheWritesPrice: 0.14, + cacheReadsPrice: 0.014, }, } as const satisfies Record