From 8ca55fd823ddcdd9e693745b105732321218c15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Fda=C5=9F=20Y=C3=BCrekli?= <25122236+cagdasyurekli@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:43:13 +0200 Subject: [PATCH 1/3] feat(providers): add DeepInfra provider and curated models (#619) Add DeepInfra as a first-class model provider and curate its latest model catalog: - Register deepinfra in coworker/providers/registry.py via _compat() pointing to https://api.deepinfra.com/v1/openai with DEEPINFRA_API_KEY. - Add 8 curated DeepInfra models to MATRIX in coworker/providers/matrix.py (DeepSeek V4 Flash/Pro including 0731 pinned snapshots, GLM 5.3 Flash/Pro, Kimi K3 and Kimi K2.7 Code) with verified context windows (128k, 256k, 1M). - Enables desktop context fill meter and compaction trigger without UI changes. - Add unit tests for routing, builder, key verification, context windows, and key isolation. Closes #619 --- coworker/providers/matrix.py | 28 +++++++++++++++++++++++++++- coworker/providers/registry.py | 8 ++++++++ tests/test_provider_router.py | 22 ++++++++++++++++++++++ tests/test_provider_verify.py | 10 ++++++++++ tests/test_providers.py | 27 +++++++++++++++++++++++---- tests/test_token_usage.py | 8 ++++++++ 6 files changed, 98 insertions(+), 5 deletions(-) diff --git a/coworker/providers/matrix.py b/coworker/providers/matrix.py index 052a19ff00..5d65ad154a 100644 --- a/coworker/providers/matrix.py +++ b/coworker/providers/matrix.py @@ -16,7 +16,7 @@ showing a made-up denominator. Values entered 2026-07-28 from vendor docs; verify alongside the id refresh. -Resellers: Together + Fireworks + OpenRouter. TODO: add Groq entries here AND its +Resellers: Together + Fireworks + OpenRouter + DeepInfra. TODO: add Groq entries here AND its descriptor in ``registry.py`` once the current provider surface is tested — deliberately deferred to bound how much needs verifying at once. """ @@ -228,6 +228,32 @@ class ModelEntry: "openrouter:stealth/ox-alpha": ModelEntry( "Ox Alpha · via OpenRouter", _AGENTIC, 1_048_576 ), + # DeepInfra curated models (OpenAI-compatible inference). Latest generation: + # DeepSeek V4, GLM 5.3, Kimi K3. Pinned snapshots (0731) and canonical slugs. + "deepinfra:deepseek-ai/DeepSeek-V4-Flash": ModelEntry( + "DeepSeek V4 Flash · via DeepInfra", _AGENTIC, 128_000 + ), + "deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731": ModelEntry( + "DeepSeek V4 Flash 0731 · via DeepInfra", _AGENTIC, 128_000 + ), + "deepinfra:deepseek-ai/DeepSeek-V4-Pro": ModelEntry( + "DeepSeek V4 Pro · via DeepInfra", _AGENTIC, 128_000 + ), + "deepinfra:deepseek-ai/DeepSeek-V4-Pro-0731": ModelEntry( + "DeepSeek V4 Pro 0731 · via DeepInfra", _AGENTIC, 128_000 + ), + "deepinfra:zai-org/GLM-5.3-Flash": ModelEntry( + "GLM-5.3 Flash · via DeepInfra", _AGENTIC_VISION, 1_000_000 + ), + "deepinfra:zai-org/GLM-5.3": ModelEntry( + "GLM-5.3 · via DeepInfra", _AGENTIC, 1_000_000 + ), + "deepinfra:moonshotai/Kimi-K3": ModelEntry( + "Kimi K3 · via DeepInfra", _AGENTIC_VISION, 1_000_000 + ), + "deepinfra:moonshotai/Kimi-K2.7-Code": ModelEntry( + "Kimi K2.7 Code · via DeepInfra", _AGENTIC, 256_000 + ), # -- cloud accounts (models running in the user's own AWS/GCP) ---------------- # Bedrock ids carry a family segment (claude/ → native Anthropic path, other/ → # Converse) plus AWS's own `-v:` version suffix. Some regions require the diff --git a/coworker/providers/registry.py b/coworker/providers/registry.py index 397efee10f..11308e026f 100644 --- a/coworker/providers/registry.py +++ b/coworker/providers/registry.py @@ -668,6 +668,14 @@ def _responses_compat( recommended_model="z-ai/glm-5.2", env_key="OPENROUTER_API_KEY", ), + _compat( + "deepinfra", + "DeepInfra", + base_url="https://api.deepinfra.com/v1/openai", + recommended_model="deepseek-ai/DeepSeek-V4-Flash", + env_key="DEEPINFRA_API_KEY", + endpoint_help="Prefilled with DeepInfra's official OpenAI-compatible endpoint.", + ), ProviderDescriptor( name="ollama", title="Ollama (local models)", diff --git a/tests/test_provider_router.py b/tests/test_provider_router.py index b47bc3aaf5..a2bf2d7ade 100644 --- a/tests/test_provider_router.py +++ b/tests/test_provider_router.py @@ -74,6 +74,22 @@ def __init__(self, **kwargs): assert captured["api_key"] == "ollama" # placeholder, Ollama ignores it +def test_build_deepinfra_client_uses_default_base_url(monkeypatch): + captured: dict = {} + + class FakeOpenAI: + def __init__(self, **kwargs): + captured.update(kwargs) + + monkeypatch.setattr("openai.OpenAI", FakeOpenAI) + client = build_provider_client( + "deepinfra", {"api_key": "di-test"}, secrets=None + ) + client._ensure_client() # type: ignore[attr-defined] + assert captured["base_url"] == "https://api.deepinfra.com/v1/openai" + assert captured["api_key"] == "di-test" + + # -- router routing ------------------------------------------------------------- class _Recorder(ProviderClient): def __init__(self, name: str): @@ -115,6 +131,12 @@ def test_router_routes_and_strips_prefix(monkeypatch): "llama3.3" ] # prefix stripped before delegating + turn = router.complete( + model="deepinfra:deepseek-ai/DeepSeek-V4-Flash", messages=[] + ) + assert turn.text == "deepinfra" + assert state["latest"]["deepinfra"].models == ["deepseek-ai/DeepSeek-V4-Flash"] + router.complete(model="gpt-5.5", messages=[]) # bare → default openai assert state["latest"]["openai"].models == ["gpt-5.5"] diff --git a/tests/test_provider_verify.py b/tests/test_provider_verify.py index a6e553afa3..1a1dbc6863 100644 --- a/tests/test_provider_verify.py +++ b/tests/test_provider_verify.py @@ -161,3 +161,13 @@ def test_verify_unexpected_status(monkeypatch): res = verify_provider_key("anthropic", api_key="sk-ant-x") assert res["ok"] is False assert "500" in res["error"] + + +def test_verify_deepinfra_default_endpoint(monkeypatch): + cap: dict = {} + _patch_get(monkeypatch, status=200, capture=cap) + + assert verify_provider_key("deepinfra", api_key="di-key") == {"ok": True} + assert cap["url"] == "https://api.deepinfra.com/v1/openai/models" + assert cap["headers"]["Authorization"] == "Bearer di-key" + diff --git a/tests/test_providers.py b/tests/test_providers.py index 99df73c3d2..a1f6f4b2fc 100644 --- a/tests/test_providers.py +++ b/tests/test_providers.py @@ -498,10 +498,15 @@ def test_matrix_answers_capabilities_for_reseller_ids(): "fireworks:accounts/fireworks/models/kimi-k2p6", "openrouter:z-ai/glm-5.2", "openrouter:meta-llama/llama-4-maverick", + "deepinfra:deepseek-ai/DeepSeek-V4-Flash", + "deepinfra:zai-org/GLM-5.3-Flash", ): caps = capabilities_for(mid) assert caps.tools and caps.parallel_tool_calls and caps.streaming + assert capabilities_for("deepinfra:zai-org/GLM-5.3-Flash").vision is True + assert capabilities_for("deepinfra:deepseek-ai/DeepSeek-V4-Flash").vision is False + def test_matrix_labels_and_custom_model_fallback(): from coworker.providers.matrix import MATRIX, model_labels @@ -509,10 +514,14 @@ def test_matrix_labels_and_custom_model_fallback(): labels = model_labels() assert labels["together:zai-org/GLM-5.2"] == "GLM-5.2 · via Together" assert labels["zai:glm-5.2"] == "GLM-5.2 · Z AI" + assert ( + labels["deepinfra:deepseek-ai/DeepSeek-V4-Flash"] + == "DeepSeek V4 Flash · via DeepInfra" + ) # Deliberately small: agent-capable current models only (owner call, 2026-07-04). - # 60→65 (2026-08-24): the stealth ox-alpha preview slug tipped it; reclaim slack by - # pruning retired entries before raising this again. - assert len(MATRIX) < 65 + # 60→65 (2026-08-24): the stealth ox-alpha preview slug tipped it; + # 65→75 (2026-09-04): added DeepInfra curated catalog (DeepSeek V4, GLM 5.3, Kimi K3). + assert len(MATRIX) < 75 assert all(e.caps.tools for e in MATRIX.values()) # A custom (unlisted) reseller model falls back to the conservative default — usable, # but at the user's own risk (no parallel tool calls assumed). @@ -526,7 +535,7 @@ def test_reseller_descriptors_and_matrix_stay_in_lockstep(): from coworker.providers.matrix import models_for_provider from coworker.providers.registry import get_descriptor - for name in ("together", "fireworks", "openrouter"): + for name in ("together", "fireworks", "openrouter", "deepinfra"): d = get_descriptor(name) assert d is not None and d.needs_key curated = models_for_provider(name) @@ -536,6 +545,16 @@ def test_reseller_descriptors_and_matrix_stay_in_lockstep(): assert base.default.startswith("https://") +def test_deepinfra_never_leaks_the_openai_key(monkeypatch): + import pytest + from coworker.providers.registry import build_provider_client + + monkeypatch.setenv("OPENAI_API_KEY", "sk-openai-real") + monkeypatch.delenv("DEEPINFRA_API_KEY", raising=False) + with pytest.raises(RuntimeError, match="DeepInfra"): + build_provider_client("deepinfra", {}, None) + + def test_foreign_sidecars_stripped_from_outbound_messages(): """Provider-private sidecars (`_gemini` thought signatures et al) must never reach the OpenAI wire — it and its compat servers reject unknown message fields.""" diff --git a/tests/test_token_usage.py b/tests/test_token_usage.py index 663bf7f11e..bb74a3b322 100644 --- a/tests/test_token_usage.py +++ b/tests/test_token_usage.py @@ -359,4 +359,12 @@ def test_model_context_windows_covers_verified_entries_only(): windows = model_context_windows() assert windows["anthropic:claude-fable-5"] == 1_000_000 assert "together:thinkingmachines/Inkling" not in windows # unverified stays absent + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash"] == 128_000 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731"] == 128_000 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro"] == 128_000 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro-0731"] == 128_000 + assert windows["deepinfra:zai-org/GLM-5.3-Flash"] == 1_000_000 + assert windows["deepinfra:zai-org/GLM-5.3"] == 1_000_000 + assert windows["deepinfra:moonshotai/Kimi-K3"] == 1_000_000 + assert windows["deepinfra:moonshotai/Kimi-K2.7-Code"] == 256_000 assert all(isinstance(v, int) and v > 0 for v in windows.values()) From b814be8383f3a754da083a5c474c0e1140e8aa8e Mon Sep 17 00:00:00 2001 From: cyurekli Date: Tue, 8 Sep 2026 21:40:49 +0200 Subject: [PATCH 2/3] fix(providers): correct DeepInfra DeepSeek V4 Pro snapshot to 0813 deepseek-ai/DeepSeek-V4-Pro-0731 does not exist on DeepInfra; the valid snapshot is deepseek-ai/DeepSeek-V4-Pro-0813. Verified against the live DeepInfra model catalog. Also updates the pinned-snapshot comment which referenced 0731 for both Flash and Pro. --- coworker/providers/matrix.py | 6 +++--- tests/test_token_usage.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/coworker/providers/matrix.py b/coworker/providers/matrix.py index 5d65ad154a..58b2405b28 100644 --- a/coworker/providers/matrix.py +++ b/coworker/providers/matrix.py @@ -229,7 +229,7 @@ class ModelEntry: "Ox Alpha · via OpenRouter", _AGENTIC, 1_048_576 ), # DeepInfra curated models (OpenAI-compatible inference). Latest generation: - # DeepSeek V4, GLM 5.3, Kimi K3. Pinned snapshots (0731) and canonical slugs. + # DeepSeek V4, GLM 5.3, Kimi K3. Pinned snapshots (Flash 0731, Pro 0813) and canonical slugs. "deepinfra:deepseek-ai/DeepSeek-V4-Flash": ModelEntry( "DeepSeek V4 Flash · via DeepInfra", _AGENTIC, 128_000 ), @@ -239,8 +239,8 @@ class ModelEntry: "deepinfra:deepseek-ai/DeepSeek-V4-Pro": ModelEntry( "DeepSeek V4 Pro · via DeepInfra", _AGENTIC, 128_000 ), - "deepinfra:deepseek-ai/DeepSeek-V4-Pro-0731": ModelEntry( - "DeepSeek V4 Pro 0731 · via DeepInfra", _AGENTIC, 128_000 + "deepinfra:deepseek-ai/DeepSeek-V4-Pro-0813": ModelEntry( + "DeepSeek V4 Pro 0813 · via DeepInfra", _AGENTIC, 128_000 ), "deepinfra:zai-org/GLM-5.3-Flash": ModelEntry( "GLM-5.3 Flash · via DeepInfra", _AGENTIC_VISION, 1_000_000 diff --git a/tests/test_token_usage.py b/tests/test_token_usage.py index bb74a3b322..1175117882 100644 --- a/tests/test_token_usage.py +++ b/tests/test_token_usage.py @@ -362,7 +362,7 @@ def test_model_context_windows_covers_verified_entries_only(): assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash"] == 128_000 assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731"] == 128_000 assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro"] == 128_000 - assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro-0731"] == 128_000 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro-0813"] == 128_000 assert windows["deepinfra:zai-org/GLM-5.3-Flash"] == 1_000_000 assert windows["deepinfra:zai-org/GLM-5.3"] == 1_000_000 assert windows["deepinfra:moonshotai/Kimi-K3"] == 1_000_000 From 07b9364b96e9370e1ebf3e1097bdfee779cae917 Mon Sep 17 00:00:00 2001 From: cyurekli Date: Tue, 15 Sep 2026 21:21:37 +0200 Subject: [PATCH 3/3] fix: align DeepInfra model metadata with hosted specifications --- coworker/providers/matrix.py | 17 +++++++++-------- tests/test_providers.py | 1 + tests/test_token_usage.py | 16 ++++++++-------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/coworker/providers/matrix.py b/coworker/providers/matrix.py index 58b2405b28..55bfb62da5 100644 --- a/coworker/providers/matrix.py +++ b/coworker/providers/matrix.py @@ -228,31 +228,32 @@ class ModelEntry: "openrouter:stealth/ox-alpha": ModelEntry( "Ox Alpha · via OpenRouter", _AGENTIC, 1_048_576 ), + # Hosted context limits and vision verified 2026-09-15 on deepinfra.com/. # DeepInfra curated models (OpenAI-compatible inference). Latest generation: # DeepSeek V4, GLM 5.3, Kimi K3. Pinned snapshots (Flash 0731, Pro 0813) and canonical slugs. "deepinfra:deepseek-ai/DeepSeek-V4-Flash": ModelEntry( - "DeepSeek V4 Flash · via DeepInfra", _AGENTIC, 128_000 + "DeepSeek V4 Flash · via DeepInfra", _AGENTIC, 1_048_576 ), "deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731": ModelEntry( - "DeepSeek V4 Flash 0731 · via DeepInfra", _AGENTIC, 128_000 + "DeepSeek V4 Flash 0731 · via DeepInfra", _AGENTIC, 1_048_576 ), "deepinfra:deepseek-ai/DeepSeek-V4-Pro": ModelEntry( - "DeepSeek V4 Pro · via DeepInfra", _AGENTIC, 128_000 + "DeepSeek V4 Pro · via DeepInfra", _AGENTIC, 1_048_576 ), "deepinfra:deepseek-ai/DeepSeek-V4-Pro-0813": ModelEntry( - "DeepSeek V4 Pro 0813 · via DeepInfra", _AGENTIC, 128_000 + "DeepSeek V4 Pro 0813 · via DeepInfra", _AGENTIC, 1_048_576 ), "deepinfra:zai-org/GLM-5.3-Flash": ModelEntry( - "GLM-5.3 Flash · via DeepInfra", _AGENTIC_VISION, 1_000_000 + "GLM-5.3 Flash · via DeepInfra", _AGENTIC_VISION, 1_048_576 ), "deepinfra:zai-org/GLM-5.3": ModelEntry( - "GLM-5.3 · via DeepInfra", _AGENTIC, 1_000_000 + "GLM-5.3 · via DeepInfra", _AGENTIC, 1_048_576 ), "deepinfra:moonshotai/Kimi-K3": ModelEntry( - "Kimi K3 · via DeepInfra", _AGENTIC_VISION, 1_000_000 + "Kimi K3 · via DeepInfra", _AGENTIC_VISION, 1_048_576 ), "deepinfra:moonshotai/Kimi-K2.7-Code": ModelEntry( - "Kimi K2.7 Code · via DeepInfra", _AGENTIC, 256_000 + "Kimi K2.7 Code · via DeepInfra", _AGENTIC_VISION, 262_144 ), # -- cloud accounts (models running in the user's own AWS/GCP) ---------------- # Bedrock ids carry a family segment (claude/ → native Anthropic path, other/ → diff --git a/tests/test_providers.py b/tests/test_providers.py index a1f6f4b2fc..2d68e36db4 100644 --- a/tests/test_providers.py +++ b/tests/test_providers.py @@ -506,6 +506,7 @@ def test_matrix_answers_capabilities_for_reseller_ids(): assert capabilities_for("deepinfra:zai-org/GLM-5.3-Flash").vision is True assert capabilities_for("deepinfra:deepseek-ai/DeepSeek-V4-Flash").vision is False + assert capabilities_for("deepinfra:moonshotai/Kimi-K2.7-Code").vision is True def test_matrix_labels_and_custom_model_fallback(): diff --git a/tests/test_token_usage.py b/tests/test_token_usage.py index 1175117882..44da6984cb 100644 --- a/tests/test_token_usage.py +++ b/tests/test_token_usage.py @@ -359,12 +359,12 @@ def test_model_context_windows_covers_verified_entries_only(): windows = model_context_windows() assert windows["anthropic:claude-fable-5"] == 1_000_000 assert "together:thinkingmachines/Inkling" not in windows # unverified stays absent - assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash"] == 128_000 - assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731"] == 128_000 - assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro"] == 128_000 - assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro-0813"] == 128_000 - assert windows["deepinfra:zai-org/GLM-5.3-Flash"] == 1_000_000 - assert windows["deepinfra:zai-org/GLM-5.3"] == 1_000_000 - assert windows["deepinfra:moonshotai/Kimi-K3"] == 1_000_000 - assert windows["deepinfra:moonshotai/Kimi-K2.7-Code"] == 256_000 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash"] == 1_048_576 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Flash-0731"] == 1_048_576 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro"] == 1_048_576 + assert windows["deepinfra:deepseek-ai/DeepSeek-V4-Pro-0813"] == 1_048_576 + assert windows["deepinfra:zai-org/GLM-5.3-Flash"] == 1_048_576 + assert windows["deepinfra:zai-org/GLM-5.3"] == 1_048_576 + assert windows["deepinfra:moonshotai/Kimi-K3"] == 1_048_576 + assert windows["deepinfra:moonshotai/Kimi-K2.7-Code"] == 262_144 assert all(isinstance(v, int) and v > 0 for v in windows.values())