core/config: default DeepSeek models v4-flash and v4-pro

When preset deepseek omits models, seed deepseek-v4-flash and
deepseek-v4-pro as text-capable entries for selection and docs.
This commit is contained in:
2026-07-15 13:57:29 +08:00
parent fb61f6bc32
commit 2052967824
7 changed files with 40 additions and 4 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ lmproto/deepseek/openai_compat/ ← Extends base via inheritance + extra fields
- **`openai_compatible/model.py`** — tagged chat messages (`SystemChatMessage`, `UserChatMessage`, …), tools, request/response, streaming chunks.
- **`openai_compatible/client.py`** — `BaseOpenAIClient` / `OpenAIClient` via `niquests` async + SSE.
- **`openai_compatible/config.py`** — `OpenAIConfig` (token + base URL).
- **DeepSeek** — `DeepseekOpenAIClient`; models add `reasoning_content`, `prefix`, `ThinkingOptions`.
- **DeepSeek** — `DeepseekOpenAIClient`; models add `reasoning_content`, `prefix`, `ThinkingOptions`. Config default model ids: `deepseek-v4-flash`, `deepseek-v4-pro`.
### Config (`config/`)
+1 -1
View File
@@ -58,7 +58,7 @@ confirm_destructive = true
max_context_tokens = 200000
```
Supported provider presets today: `openai`, `openai-compatible`, `deepseek` (OpenAI convention). Anthropic presets are modeled in config but not wired in the runtime client yet.
Supported provider presets today: `openai`, `openai-compatible`, `deepseek` (OpenAI convention; default models `deepseek-v4-flash` and `deepseek-v4-pro` if `models` is omitted). Anthropic presets are modeled in config but not wired in the runtime client yet.
If `[database]` is omitted (or SQLite `url` is empty/`":memory:"`), chat uses a durable file under the user data dir (e.g. `~/.local/share/plyngent/chat.db` on Linux).
+4 -2
View File
@@ -36,11 +36,13 @@ access_key_or_token = "sk-replace-me"
# "gpt-4o-mini" = { text = true }
# --- DeepSeek (OpenAI-compatible convention) ---
# Default models if [providers.*.models] is omitted: deepseek-v4-flash, deepseek-v4-pro.
# [providers.deepseek]
# preset = "deepseek"
# access_key_or_token = "sk-replace-me"
# url = "https://api.deepseek.com"
# # url defaults to https://api.deepseek.com/v1 when empty
# extras = { convention = "openai" }
#
# [providers.deepseek.models]
# "deepseek-chat" = { text = true }
# "deepseek-v4-flash" = { text = true }
# "deepseek-v4-pro" = { text = true }
+5
View File
@@ -38,6 +38,11 @@ _MINIMAL_CONFIG = """\
#
# [providers.example.models]
# "gpt-4o-mini" = { text = true }
#
# [providers.deepseek]
# preset = "deepseek"
# access_key_or_token = "sk-..."
# # models default to deepseek-v4-flash and deepseek-v4-pro if omitted
"""
+9
View File
@@ -58,9 +58,18 @@ class AnthropicProvider(ProviderConfig, tag="anthropic"):
"""Anthropic API provider."""
def _default_deepseek_models() -> dict[str, ModelConfig]:
"""Current DeepSeek text catalog when TOML omits ``models``."""
return {
"deepseek-v4-flash": ModelConfig(text=True),
"deepseek-v4-pro": ModelConfig(text=True),
}
class DeepseekProvider(ProviderConfig, tag="deepseek"):
"""Deepseek API provider with optional extras (e.g. convention)."""
models: dict[str, ModelConfig] = field(default_factory=_default_deepseek_models)
extras: dict[str, str] = field(default_factory=dict)
+18
View File
@@ -43,6 +43,9 @@ def test_read_valid_config() -> None:
assert isinstance(providers["test2"], OpenAICompatibleProvider)
assert isinstance(providers["test3"], AnthropicProvider)
assert isinstance(providers["foo1"], DeepseekProvider)
# TOML omitted models → DeepSeek defaults.
assert set(providers["foo1"].models) == {"deepseek-v4-flash", "deepseek-v4-pro"}
assert providers["foo1"].models["deepseek-v4-flash"].text is True
db = config.database
assert db["implementation"] == "sqlite"
assert db["url"] == ":memory:"
@@ -50,6 +53,21 @@ def test_read_valid_config() -> None:
assert db["password"] is None
def test_deepseek_default_models_on_construct() -> None:
provider = DeepseekProvider(access_key_or_token="sk-test")
assert set(provider.models) == {"deepseek-v4-flash", "deepseek-v4-pro"}
def test_deepseek_explicit_models_override_defaults() -> None:
from plyngent.config import ModelConfig
provider = DeepseekProvider(
access_key_or_token="sk-test",
models={"custom-only": ModelConfig(text=True)},
)
assert set(provider.models) == {"custom-only"}
def test_read_empty_config() -> None:
config = plyngent.config.load(Path(__file__).parent / "plyngent-empty.toml")
assert isinstance(config.providers, Mapping)
@@ -43,6 +43,8 @@ def test_deepseek_openai_convention() -> None:
client = create_client(provider)
assert isinstance(client, DeepseekOpenAIClient)
assert provider_to_openai_config(provider).base_url == "https://api.deepseek.com/v1"
assert "deepseek-v4-flash" in provider.models
assert "deepseek-v4-pro" in provider.models
def test_deepseek_anthropic_convention_not_implemented() -> None: