From ab6b53fa8b8063a1c517ec874c888ccae5c66842 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 11 Jun 2026 01:30:38 -0400 Subject: [PATCH] feat(qwen): add qwen to PROVIDERS; add 7 Qwen pricing entries to cost_tracker Side concerns for Phase 2: 1. PROVIDERS: src/models.py:56 now includes 'qwen' alongside the existing 5 vendors. The other 4 references to PROVIDERS in src/gui_2.py and src/app_controller.py import from this centralized list, so this one edit propagates everywhere. State task t2.8 was scoped to 'gui_2.py and app_controller.py' but the actual change is at the centralized registry, per the project's single-source-of-truth pattern (per src/models.py module docstring and the Phase 5 audit script audit_no_models_config_io.py which enforces that PROVIDERS lives in models.py). 2. cost_tracker.py: added 7 regex pricing entries for the Qwen models shipped in Phase 1's vendor_capabilities.py: - qwen-turbo: 0.05 / 0.10 - qwen-plus: 0.40 / 1.20 - qwen-max: 2.00 / 6.00 - qwen-long: 0.07 / 0.28 - qwen-vl-plus: 0.21 / 0.63 - qwen-vl-max: 0.50 / 1.50 - qwen-audio: 0.10 / 0.30 (all per 1M tokens, USD; matches the structure of existing entries) Spot check: estimate_cost('qwen-max', 1000, 500) = 0.005 (= 0.002 + 0.003) 3. SKIPPED t2.7 (credentials template): no credentials_template.toml exists in the project. The only credentials file is the active credentials.toml which the user maintains directly with their own API keys. The plan's assumption of a template file does not match the project's actual structure. Documented in the commit log rather than modifying the user's actual credentials.toml with a placeholder key (which would be inconsistent with the rest of that file's pattern of real keys). When the user obtains a DashScope API key, they can add a [qwen] section directly. 4. t2.9 (Qwen models in capability registry) was completed in Phase 1's initial population of 22 entries (commit 6be04bc). The 8 qwen entries (1 wildcard + 7 specific models) are in src/vendor_capabilities.py. Verification: 30/30 tests pass in batch (test_qwen_provider, test_minimax_provider, test_ai_client_no_top_level_sdk_imports, test_vendor_capabilities, test_openai_compatible, test_cost_tracker) --- src/cost_tracker.py | 7 +++++++ src/models.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cost_tracker.py b/src/cost_tracker.py index 60b9b15f..3b59720b 100644 --- a/src/cost_tracker.py +++ b/src/cost_tracker.py @@ -43,6 +43,13 @@ MODEL_PRICING = [ (r"claude-.*-sonnet", {"input_per_mtok": 3.0, "output_per_mtok": 15.0}), (r"claude-.*-opus", {"input_per_mtok": 15.0, "output_per_mtok": 75.0}), (r"deepseek-v3", {"input_per_mtok": 0.27, "output_per_mtok": 1.10}), + (r"qwen-turbo", {"input_per_mtok": 0.05, "output_per_mtok": 0.10}), + (r"qwen-plus", {"input_per_mtok": 0.40, "output_per_mtok": 1.20}), + (r"qwen-max", {"input_per_mtok": 2.00, "output_per_mtok": 6.00}), + (r"qwen-long", {"input_per_mtok": 0.07, "output_per_mtok": 0.28}), + (r"qwen-vl-plus", {"input_per_mtok": 0.21, "output_per_mtok": 0.63}), + (r"qwen-vl-max", {"input_per_mtok": 0.50, "output_per_mtok": 1.50}), + (r"qwen-audio", {"input_per_mtok": 0.10, "output_per_mtok": 0.30}), ] def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float: diff --git a/src/models.py b/src/models.py index ad96ddd2..0db0795f 100644 --- a/src/models.py +++ b/src/models.py @@ -53,7 +53,7 @@ from src.paths import get_config_path #region: Constants -PROVIDERS: List[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax"] +PROVIDERS: List[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax", "qwen"] AGENT_TOOL_NAMES: List[str] = [ "run_powershell",