feat(config): align tier defaults to cost-conscious models + qwen3-235b on tier C

- Tier S → google/gemini-3-flash-preview ($0.50/$3.00)
- Tier A/B → deepseek/deepseek-v4-flash ($0.14/$0.28)
- Tier C → qwen/qwen3-235b-a22b-2507 ($0.071/$0.10) — Phase 2 target
- Tier D → openai/gpt-oss-20b ($0.03/$0.14)

Aggiornato cost_tracker con prezzi reali per tier. Defaults config.py
ora rispecchiano .env corrente per evitare divergenze dead-code.

Tier S/A/B/D restano cablati ma non ancora invocati nel loop Phase 2
(solo Hypothesis tier C attivo).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-11 22:13:49 +02:00
parent 68637d1102
commit 9c53995f23
8 changed files with 39 additions and 39 deletions
+5 -5
View File
@@ -11,11 +11,11 @@ OPENROUTER_API_KEY=
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1 OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
# Models per tier (override Phase 1 defaults if needed) # Models per tier (override Phase 1 defaults if needed)
LLM_MODEL_TIER_S=anthropic/claude-opus-4-7 LLM_MODEL_TIER_S=google/gemini-3-flash-preview
LLM_MODEL_TIER_A=anthropic/claude-sonnet-4-6 LLM_MODEL_TIER_A=deepseek/deepseek-v4-flash
LLM_MODEL_TIER_B=anthropic/claude-sonnet-4-6 LLM_MODEL_TIER_B=deepseek/deepseek-v4-flash
LLM_MODEL_TIER_C=qwen/qwen-2.5-72b-instruct LLM_MODEL_TIER_C=qwen/qwen3-235b-a22b-2507
LLM_MODEL_TIER_D=meta-llama/llama-3.3-70b-instruct LLM_MODEL_TIER_D=openai/gpt-oss-20b
# Run config # Run config
RUN_NAME=phase1-spike-001 RUN_NAME=phase1-spike-001
+1 -1
View File
@@ -112,7 +112,7 @@ OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
LLM_MODEL_TIER_S=anthropic/claude-opus-4-7 LLM_MODEL_TIER_S=anthropic/claude-opus-4-7
LLM_MODEL_TIER_A=anthropic/claude-sonnet-4-6 LLM_MODEL_TIER_A=anthropic/claude-sonnet-4-6
LLM_MODEL_TIER_B=anthropic/claude-sonnet-4-6 LLM_MODEL_TIER_B=anthropic/claude-sonnet-4-6
LLM_MODEL_TIER_C=qwen/qwen-2.5-72b-instruct LLM_MODEL_TIER_C=qwen/qwen3-235b-a22b-2507
LLM_MODEL_TIER_D=meta-llama/llama-3.3-70b-instruct LLM_MODEL_TIER_D=meta-llama/llama-3.3-70b-instruct
``` ```
+5 -5
View File
@@ -25,11 +25,11 @@ class Settings(BaseSettings):
openrouter_api_key: SecretStr openrouter_api_key: SecretStr
llm_model_tier_s: str = "anthropic/claude-opus-4-7" llm_model_tier_s: str = "google/gemini-3-flash-preview"
llm_model_tier_a: str = "anthropic/claude-sonnet-4-6" llm_model_tier_a: str = "deepseek/deepseek-v4-flash"
llm_model_tier_b: str = "anthropic/claude-sonnet-4-6" llm_model_tier_b: str = "deepseek/deepseek-v4-flash"
llm_model_tier_c: str = "qwen/qwen-2.5-72b-instruct" llm_model_tier_c: str = "qwen/qwen3-235b-a22b-2507"
llm_model_tier_d: str = "meta-llama/llama-3.3-70b-instruct" llm_model_tier_d: str = "openai/gpt-oss-20b"
openrouter_base_url: str = "https://openrouter.ai/api/v1" openrouter_base_url: str = "https://openrouter.ai/api/v1"
run_name: str = "phase1-spike-001" run_name: str = "phase1-spike-001"
+5 -5
View File
@@ -14,11 +14,11 @@ from tenacity import (
from ..genome.hypothesis import HypothesisAgentGenome, ModelTier from ..genome.hypothesis import HypothesisAgentGenome, ModelTier
# Modelli configurati per Phase 1 — tutti via OpenRouter # Modelli configurati per Phase 1 — tutti via OpenRouter
MODEL_TIER_S = "anthropic/claude-opus-4-7" MODEL_TIER_S = "google/gemini-3-flash-preview"
MODEL_TIER_A = "anthropic/claude-sonnet-4-6" MODEL_TIER_A = "deepseek/deepseek-v4-flash"
MODEL_TIER_B = "anthropic/claude-sonnet-4-6" MODEL_TIER_B = "deepseek/deepseek-v4-flash"
MODEL_TIER_C = "qwen/qwen-2.5-72b-instruct" MODEL_TIER_C = "qwen/qwen3-235b-a22b-2507"
MODEL_TIER_D = "meta-llama/llama-3.3-70b-instruct" MODEL_TIER_D = "openai/gpt-oss-20b"
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1" OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
class EmptyCompletionError(RuntimeError): class EmptyCompletionError(RuntimeError):
+5 -5
View File
@@ -8,11 +8,11 @@ from typing import Any
from ..genome.hypothesis import ModelTier from ..genome.hypothesis import ModelTier
PRICE_PER_M_TOKENS: dict[ModelTier, dict[str, float]] = { PRICE_PER_M_TOKENS: dict[ModelTier, dict[str, float]] = {
ModelTier.S: {"input": 15.00, "output": 75.00}, ModelTier.S: {"input": 0.50, "output": 3.00},
ModelTier.A: {"input": 3.00, "output": 15.00}, ModelTier.A: {"input": 0.14, "output": 0.28},
ModelTier.B: {"input": 3.00, "output": 15.00}, ModelTier.B: {"input": 0.14, "output": 0.28},
ModelTier.C: {"input": 0.40, "output": 0.40}, ModelTier.C: {"input": 0.071, "output": 0.10},
ModelTier.D: {"input": 0.10, "output": 0.30}, ModelTier.D: {"input": 0.03, "output": 0.14},
} }
+5 -5
View File
@@ -73,9 +73,9 @@ def test_settings_llm_model_defaults(monkeypatch: pytest.MonkeyPatch) -> None:
s = Settings(_env_file=None) # type: ignore[call-arg] s = Settings(_env_file=None) # type: ignore[call-arg]
assert s.llm_model_tier_s == "anthropic/claude-opus-4-7" assert s.llm_model_tier_s == "google/gemini-3-flash-preview"
assert s.llm_model_tier_a == "anthropic/claude-sonnet-4-6" assert s.llm_model_tier_a == "deepseek/deepseek-v4-flash"
assert s.llm_model_tier_b == "anthropic/claude-sonnet-4-6" assert s.llm_model_tier_b == "deepseek/deepseek-v4-flash"
assert s.llm_model_tier_c == "qwen/qwen-2.5-72b-instruct" assert s.llm_model_tier_c == "qwen/qwen3-235b-a22b-2507"
assert s.llm_model_tier_d == "meta-llama/llama-3.3-70b-instruct" assert s.llm_model_tier_d == "openai/gpt-oss-20b"
assert s.openrouter_base_url == "https://openrouter.ai/api/v1" assert s.openrouter_base_url == "https://openrouter.ai/api/v1"
+5 -5
View File
@@ -4,12 +4,12 @@ from multi_swarm.llm.cost_tracker import CostTracker, estimate_cost
def test_estimate_cost_tier_c(): def test_estimate_cost_tier_c():
cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.C) cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.C)
assert cost == 0.40 + 0.40 assert cost == 0.071 + 0.10
def test_estimate_cost_tier_b(): def test_estimate_cost_tier_b():
cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.B) cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.B)
assert cost == 3.00 + 15.00 assert cost == 0.14 + 0.28
def test_tracker_accumulates(): def test_tracker_accumulates():
@@ -34,17 +34,17 @@ def test_tracker_per_tier_breakdown():
def test_estimate_cost_tier_s(): def test_estimate_cost_tier_s():
cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.S) cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.S)
assert cost == 15.00 + 75.00 assert cost == 0.50 + 3.00
def test_estimate_cost_tier_a(): def test_estimate_cost_tier_a():
cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.A) cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.A)
assert cost == 3.00 + 15.00 assert cost == 0.14 + 0.28
def test_estimate_cost_tier_d(): def test_estimate_cost_tier_d():
cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.D) cost = estimate_cost(input_tokens=1_000_000, output_tokens=1_000_000, tier=ModelTier.D)
assert cost == 0.10 + 0.30 assert cost == 0.03 + 0.14
def test_tracker_summary_contains_all_five_tiers(): def test_tracker_summary_contains_all_five_tiers():
+8 -8
View File
@@ -54,8 +54,8 @@ def test_completion_tier_b_uses_openrouter_with_anthropic_model(mocker):
assert out.output_tokens == 150 assert out.output_tokens == 150
assert out.tier == ModelTier.B assert out.tier == ModelTier.B
call_kwargs = fake_openai.chat.completions.create.call_args.kwargs call_kwargs = fake_openai.chat.completions.create.call_args.kwargs
assert call_kwargs["model"] == "anthropic/claude-sonnet-4-6" assert call_kwargs["model"] == "deepseek/deepseek-v4-flash"
assert out.model == "anthropic/claude-sonnet-4-6" assert out.model == "deepseek/deepseek-v4-flash"
@pytest.mark.slow @pytest.mark.slow
@@ -138,9 +138,9 @@ def test_completion_tier_s_uses_openrouter_with_anthropic_model(mocker):
fake_openai.chat.completions.create.assert_called_once() fake_openai.chat.completions.create.assert_called_once()
call_kwargs = fake_openai.chat.completions.create.call_args.kwargs call_kwargs = fake_openai.chat.completions.create.call_args.kwargs
assert call_kwargs["model"] == "anthropic/claude-opus-4-7" assert call_kwargs["model"] == "google/gemini-3-flash-preview"
assert out.tier == ModelTier.S assert out.tier == ModelTier.S
assert out.model == "anthropic/claude-opus-4-7" assert out.model == "google/gemini-3-flash-preview"
def test_completion_tier_a_uses_openrouter_with_anthropic_model(mocker): def test_completion_tier_a_uses_openrouter_with_anthropic_model(mocker):
@@ -157,9 +157,9 @@ def test_completion_tier_a_uses_openrouter_with_anthropic_model(mocker):
fake_openai.chat.completions.create.assert_called_once() fake_openai.chat.completions.create.assert_called_once()
call_kwargs = fake_openai.chat.completions.create.call_args.kwargs call_kwargs = fake_openai.chat.completions.create.call_args.kwargs
assert call_kwargs["model"] == "anthropic/claude-sonnet-4-6" assert call_kwargs["model"] == "deepseek/deepseek-v4-flash"
assert out.tier == ModelTier.A assert out.tier == ModelTier.A
assert out.model == "anthropic/claude-sonnet-4-6" assert out.model == "deepseek/deepseek-v4-flash"
def test_completion_tier_d_uses_openrouter_with_llama(mocker): def test_completion_tier_d_uses_openrouter_with_llama(mocker):
@@ -178,9 +178,9 @@ def test_completion_tier_d_uses_openrouter_with_llama(mocker):
fake_openai.chat.completions.create.assert_called_once() fake_openai.chat.completions.create.assert_called_once()
call_kwargs = fake_openai.chat.completions.create.call_args.kwargs call_kwargs = fake_openai.chat.completions.create.call_args.kwargs
assert call_kwargs["model"] == "meta-llama/llama-3.3-70b-instruct" assert call_kwargs["model"] == "openai/gpt-oss-20b"
assert out.tier == ModelTier.D assert out.tier == ModelTier.D
assert out.model == "meta-llama/llama-3.3-70b-instruct" assert out.model == "openai/gpt-oss-20b"
def test_completion_uses_custom_model_tier_s(mocker): def test_completion_uses_custom_model_tier_s(mocker):