From f3cca2202f57699cc41ba1e850fd5abde48a0914 Mon Sep 17 00:00:00 2001 From: Jakub Zika Date: Sun, 3 May 2026 17:37:13 +0200 Subject: [PATCH] Add DeepSeek V4 Pro variants and API filter for variant matching - Add built-in variants for `deepseek-v4-pro` (`none`, `high`, `max`) - `variantsByModel` entries now support an optional `:api` filter (string or vector) to restrict variant matching by provider API type --- CHANGELOG.md | 3 +++ docs/config.json | 11 +++++++++++ docs/config/variants.md | 10 ++++++++++ src/eca/config.clj | 21 +++++++++++++++++---- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c138c2b8..aa1a7e226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Add built-in variants for `deepseek-v4-pro` (`none`, `high`, `max`). +- `variantsByModel` entries now support an optional `:api` filter (string or vector) to restrict variant matching by provider API type. + ## 0.131.1 - MCP tools that return image content blocks (e.g. an MCP image-generation/edit server) now render those images in the chat UI as `ChatImageContent` and replay them back to the LLM as image inputs on follow-up turns when the model supports vision. Implemented for `openai-responses` (synthetic user-role `input_image` after the `function_call_output`) and `anthropic` (mixed text + image blocks inside `tool_result.content`). `openai-chat` and `ollama` continue to receive a text placeholder until a parallel pattern is implemented there. diff --git a/docs/config.json b/docs/config.json index 5204393bf..fbd86c19c 100644 --- a/docs/config.json +++ b/docs/config.json @@ -475,6 +475,17 @@ "items": { "type": "string" } + }, + "api": { + "type": [ + "string", + "array" + ], + "description": "Restrict variants to the given API type(s). String for exact match, array for any-of. Absent = match all.", + "markdownDescription": "Restrict variants to the given API type(s). String for exact match, array for any-of. Absent = match all.", + "items": { + "type": "string" + } } }, "additionalProperties": false diff --git a/docs/config/variants.md b/docs/config/variants.md index 5e9ed3464..b941ea567 100644 --- a/docs/config/variants.md +++ b/docs/config/variants.md @@ -35,6 +35,16 @@ ECA ships with built-in variants for some known models via the `variantsByModel` | `high` | `{"reasoning": {"effort": "high", "summary": "auto"}}` | | `xhigh` | `{"reasoning": {"effort": "xhigh", "summary": "auto"}}` | +=== "DeepSeek" + + Applies to models matching `deepseek-v4-pro`. Only for providers using the `openai-chat` API. + + | Variant | Payload | + | ---------- | ------- | + | `none` | `{"thinking": {"type": "disabled"}}` | + | `high` | `{"reasoning_effort": "high"}` | + | `max` | `{"reasoning_effort": "max"}}` | + ## Custom Variants You can define your own variants per model under `providers..models..variants`. Custom variants are merged with built-in ones — if names clash, your definition wins. diff --git a/src/eca/config.clj b/src/eca/config.clj index b677da5b5..b9f241289 100644 --- a/src/eca/config.clj +++ b/src/eca/config.clj @@ -72,6 +72,11 @@ "xhigh" {:output_config {:effort "xhigh"} :thinking {:type "adaptive" :display "summarized"}} "max" {:output_config {:effort "max"} :thinking {:type "adaptive" :display "summarized"}}}) +(def ^:private deepseek-variants + {"none" {:thinking {:type "disabled"}} + "high" {:reasoning_effort "high"} + "max" {:reasoning_effort "max"}}) + (def ^:private initial-config* {:providers {"openai" {:api "openai-responses" :url "${env:OPENAI_API_URL:https://api.openai.com}" @@ -188,7 +193,9 @@ :variantsByModel {".*sonnet[-._]4[-._]6|opus[-._]4[-._][56]" {:variants anthropic-variants} ".*opus[-._]4[-._]7" {:variants anthropic-v2-variants} ".*gpt[-._]5(?:[-._](?:2|4|5)(?!\\d)|[-._]3[-._]codex)" {:variants openai-variants - :excludeProviders ["github-copilot"]}} + :excludeProviders ["github-copilot"]} + ".*deepseek[-._]v4[-._]pro" {:variants deepseek-variants + :api "openai-chat"}} :mcpTimeoutSeconds 60 :lspTimeoutSeconds 30 :streamIdleTimeoutSeconds 120 @@ -243,10 +250,16 @@ A variant set to {} is removed from the result, allowing users to disable built-in variants." [config provider model-name user-variants] - (let [builtin (when model-name - (some (fn [[pattern-str {:keys [variants excludeProviders]}]] + (let [provider-api (get-in config [:providers provider :api]) + api-match? (fn [api config-val] + (cond (sequential? config-val) (some #{api} config-val) + config-val (= api config-val) + :else true)) + builtin (when model-name + (some (fn [[pattern-str {:keys [variants excludeProviders api]}]] (when (and (regex-matches? pattern-str model-name) - (not (some #{provider} excludeProviders))) + (not (some #{provider} excludeProviders)) + (api-match? provider-api api)) variants)) (:variantsByModel config))) merged (cond