sync: 167 file da Baida98/AI@a58fbf7e (2026-08-22 09:03 UTC)

#54
by Baida07 - opened
api/exec.py CHANGED
@@ -568,15 +568,14 @@ async def llm_fix_code(
568
  _FIX_CHAIN = []
569
  groq_key = os.getenv('GROQ_API_KEY', '')
570
  if groq_key:
571
- _FIX_CHAIN.append(('https://api.groq.com/openai/v1', groq_key, 'openai/gpt-oss-120b'))
572
- _FIX_CHAIN.append(('https://api.groq.com/openai/v1', groq_key, 'openai/gpt-oss-20b'))
573
 
574
  or_key = os.getenv('OPENROUTER_API_KEY', '')
575
  if or_key:
576
  for m in [
577
- 'openai/gpt-oss-20b:free',
578
- 'meta-llama/llama-3.1-8b-instruct:free',
579
- 'qwen/qwen-2.5-coder-7b-instruct:free',
580
  ]:
581
  _FIX_CHAIN.append(('https://openrouter.ai/api/v1', or_key, m))
582
 
 
568
  _FIX_CHAIN = []
569
  groq_key = os.getenv('GROQ_API_KEY', '')
570
  if groq_key:
571
+ _FIX_CHAIN.append(('https://api.groq.com/openai/v1', groq_key, 'qwen/qwen3.6-27b'))
 
572
 
573
  or_key = os.getenv('OPENROUTER_API_KEY', '')
574
  if or_key:
575
  for m in [
576
+ 'openrouter/free',
577
+ 'qwen/qwen3-coder:free',
578
+ 'meta-llama/llama-3.3-70b-instruct:free',
579
  ]:
580
  _FIX_CHAIN.append(('https://openrouter.ai/api/v1', or_key, m))
581
 
api/providers.py CHANGED
@@ -930,14 +930,14 @@ async def update_provider_models(role: AuthRole = Depends(require_role(AuthRole.
930
  # filtrare per `name` evita di applicare un formato incompatibile alla riga sbagliata.
931
  # GPT-OSS 120B non compare come vecchio valore perché è già un modello supportato.
932
  MODEL_FIXES = [
933
- ("groq", "llama-3.1-70b-versatile", "openai/gpt-oss-120b"),
934
  ("cerebras", "llama3.1-70b", "gpt-oss-120b"),
935
  ("nvidia", "llama-3.1-405b-instruct", "meta/llama-3.3-70b-instruct"),
936
- ("openrouter", "llama-3.1-405b", "openai/gpt-oss-20b:free"),
937
  ("sambanova", "llama3-70b", "DeepSeek-V3.2"),
938
  ("gemini", "gemini-1.5-flash", "gemini-3.5-flash-lite"),
939
  ("gemini", "gemini-1.5-pro", "gemini-3.6-flash"),
940
- ("openrouter", "claude-3.5-sonnet", "openai/gpt-oss-20b:free"),
941
  ]
942
 
943
  import asyncio as _aio
 
930
  # filtrare per `name` evita di applicare un formato incompatibile alla riga sbagliata.
931
  # GPT-OSS 120B non compare come vecchio valore perché è già un modello supportato.
932
  MODEL_FIXES = [
933
+ ("groq", "llama-3.1-70b-versatile", "qwen/qwen3.6-27b"),
934
  ("cerebras", "llama3.1-70b", "gpt-oss-120b"),
935
  ("nvidia", "llama-3.1-405b-instruct", "meta/llama-3.3-70b-instruct"),
936
+ ("openrouter", "llama-3.1-405b", "openrouter/free"),
937
  ("sambanova", "llama3-70b", "DeepSeek-V3.2"),
938
  ("gemini", "gemini-1.5-flash", "gemini-3.5-flash-lite"),
939
  ("gemini", "gemini-1.5-pro", "gemini-3.6-flash"),
940
+ ("openrouter", "claude-3.5-sonnet", "openrouter/free"),
941
  ]
942
 
943
  import asyncio as _aio
models/ai_client.py CHANGED
@@ -61,11 +61,11 @@ class ProviderConfig:
61
  # (nessun proxy CF Worker qui: questo client gira lato backend Python, non browser).
62
  _PROVIDER_DEFS = [
63
  # tier 0 — free tier veloce e affidabile
64
- {"name": "groq", "env_key": "GROQ_API_KEY", "base_url": "https://api.groq.com/openai/v1", "model_env": "GROQ_MODEL", "default_model": "openai/gpt-oss-120b", "tier": 0, "purpose": "reasoning"},
65
  {"name": "cerebras", "env_key": "CEREBRAS_API_KEY", "base_url": "https://api.cerebras.ai/v1", "model_env": "CEREBRAS_MODEL", "default_model": "gpt-oss-120b", "tier": 0, "purpose": "reasoning"},
66
  {"name": "sambanova", "env_key": "SAMBANOVA_API_KEY", "base_url": "https://api.sambanova.ai/v1", "model_env": "SAMBANOVA_MODEL", "default_model": "DeepSeek-V3.1", "tier": 0, "purpose": "reasoning"},
67
  # tier 1 — free tier con rate limit più stretti
68
- {"name": "openrouter", "env_key": "OPENROUTER_API_KEY", "base_url": "https://openrouter.ai/api/v1", "model_env": "OPENROUTER_MODEL","default_model": "openai/gpt-oss-20b:free", "tier": 1, "purpose": "coding"},
69
  {"name": "hf_router", "env_key": "HF_TOKEN", "base_url": "https://router.huggingface.co/v1", "model_env": "HF_MODEL", "default_model": "Qwen/Qwen2.5-Coder-32B-Instruct", "tier": 1, "purpose": "coding"},
70
  {"name": "gemini", "env_key": "GEMINI_API_KEY", "base_url": "https://generativelanguage.googleapis.com/v1beta/openai/", "model_env": "GEMINI_MODEL", "default_model": "gemini-3.6-flash", "tier": 1, "purpose": "memory"},
71
  # tier 2 — fallback opzionale (spesso a pagamento o quota limitata)
 
61
  # (nessun proxy CF Worker qui: questo client gira lato backend Python, non browser).
62
  _PROVIDER_DEFS = [
63
  # tier 0 — free tier veloce e affidabile
64
+ {"name": "groq", "env_key": "GROQ_API_KEY", "base_url": "https://api.groq.com/openai/v1", "model_env": "GROQ_MODEL", "default_model": "qwen/qwen3.6-27b", "tier": 0, "purpose": "reasoning"},
65
  {"name": "cerebras", "env_key": "CEREBRAS_API_KEY", "base_url": "https://api.cerebras.ai/v1", "model_env": "CEREBRAS_MODEL", "default_model": "gpt-oss-120b", "tier": 0, "purpose": "reasoning"},
66
  {"name": "sambanova", "env_key": "SAMBANOVA_API_KEY", "base_url": "https://api.sambanova.ai/v1", "model_env": "SAMBANOVA_MODEL", "default_model": "DeepSeek-V3.1", "tier": 0, "purpose": "reasoning"},
67
  # tier 1 — free tier con rate limit più stretti
68
+ {"name": "openrouter", "env_key": "OPENROUTER_API_KEY", "base_url": "https://openrouter.ai/api/v1", "model_env": "OPENROUTER_MODEL","default_model": "openrouter/free", "tier": 1, "purpose": "coding"},
69
  {"name": "hf_router", "env_key": "HF_TOKEN", "base_url": "https://router.huggingface.co/v1", "model_env": "HF_MODEL", "default_model": "Qwen/Qwen2.5-Coder-32B-Instruct", "tier": 1, "purpose": "coding"},
70
  {"name": "gemini", "env_key": "GEMINI_API_KEY", "base_url": "https://generativelanguage.googleapis.com/v1beta/openai/", "model_env": "GEMINI_MODEL", "default_model": "gemini-3.6-flash", "tier": 1, "purpose": "memory"},
71
  # tier 2 — fallback opzionale (spesso a pagamento o quota limitata)
models/role_router.py CHANGED
@@ -3,27 +3,27 @@ role_router.py — Multi-model role routing (S362, aggiornato 2026-06-14 benchma
3
 
4
  BENCHMARK RESULTS 2026-06-14 FINALE (14 modelli × 3 test, max_tokens corretti):
5
  100% qualità (ordinati per TTFT):
6
- #1 Groq / openai/gpt-oss-20b — 170ms 100% ← FASTEST
7
  #2 Cerebras / gpt-oss-120b — 207ms 100% ← REASONING (max_tokens≥500)
8
- #3 Groq / openai/gpt-oss-120b — 235ms 100%
9
  #4 Cerebras / zai-glm-4.7 — 254ms 100%
10
  #5 Groq / compound-mini — 341ms 100%
11
  #6 SambaNova / DeepSeek-V3.1 — 482ms 100%
12
  #7 SambaNova / gemma-4-31B — 2132ms 100%
13
- #8 OpenRouter / gpt-oss-120b:free — 2160ms 100%
14
 
15
  Role assignments 2026-06-14 FINALE:
16
- FAST → Groq openai/gpt-oss-20b (170ms, 100%) ← #1 assoluto
17
  ARCHITECT → Groq llama-4-scout-17b 10M ctx (244ms, 67% — best per contesto lungo)
18
- CODER → Groq openai/gpt-oss-120b (235ms, 100%) ← #3 qualità
19
- TESTER → Groq openai/gpt-oss-20b
20
- CONTEXT → Groq openai/gpt-oss-20b
21
  RESEARCHER → Gemini 2.5-flash (599ms, 67% — math prompt-sensitive)
22
  REASONER → Cerebras gpt-oss-120b (207ms, 100%, reasoning model → max_tokens≥500)
23
  SAMBANOVA → SambaNova DeepSeek-V3.1 (482ms, 100%)
24
- DEFAULT → AIClient() primary (openai/gpt-oss-120b o primo disponibile)
25
 
26
- OpenRouter tenuto come fallback secondario (gpt-oss-120b:free = 1645ms ma 100% qualità).
27
  """
28
  from __future__ import annotations
29
 
@@ -36,11 +36,11 @@ _logger = logging.getLogger("models.role_router")
36
 
37
 
38
  class Role(str, Enum):
39
- FAST = "fast" # greetings, math semplice, identity — openai/gpt-oss-20b
40
  ARCHITECT = "architect" # planning, ragionamento complesso — GPT-OSS 120B
41
- CODER = "coder" # coding, debug — openai/gpt-oss-120b
42
- TESTER = "tester" # test gen, debug hints — openai/gpt-oss-120b
43
- CONTEXT = "context" # summarization, context compression — openai/gpt-oss-120b
44
  DEFAULT = "default" # AIClient() primary
45
  RESEARCHER = "researcher" # web research + document synthesis — GPT-OSS 120B
46
  REASONER = "reasoner" # throughput massimo — Cerebras GPT-OSS 120B
@@ -122,7 +122,7 @@ class RoleRouter:
122
  name="groq-fast",
123
  api_key=groq_key,
124
  base_url="https://api.groq.com/openai/v1",
125
- default_model=os.getenv("GROQ_FAST_MODEL", "openai/gpt-oss-20b"),
126
  )
127
  rest = [p for p in client.providers if p.name not in ("groq", "groq-fast", "groq-tester")]
128
  client.providers = [fast, *rest]
@@ -163,7 +163,7 @@ class RoleRouter:
163
  name="groq-architect",
164
  api_key=groq_key,
165
  base_url="https://api.groq.com/openai/v1",
166
- default_model=os.getenv("ARCHITECT_MODEL", "openai/gpt-oss-120b"),
167
  )
168
  rest = [p for p in client.providers if p.name not in ("groq", "groq-architect")]
169
  client.providers = [architect, *rest]
@@ -179,7 +179,7 @@ class RoleRouter:
179
  profiles = [ProviderConfig(
180
  name="openrouter", api_key=os.getenv("OPENROUTER_API_KEY", ""),
181
  base_url="https://openrouter.ai/api/v1",
182
- default_model=os.getenv("OPENROUTER_MODEL", "openai/gpt-oss-20b:free"),
183
  profile="legacy",
184
  )]
185
  if profiles:
@@ -201,7 +201,7 @@ class RoleRouter:
201
  return profiled
202
  groq_key = os.getenv("GROQ_API_KEY")
203
  nvidia_key = os.getenv("NVIDIA_API_KEY")
204
- model = os.getenv("CODER_MODEL", "openai/gpt-oss-120b")
205
  if groq_key:
206
  client = AIClient()
207
  coder = ProviderConfig(
@@ -241,7 +241,7 @@ class RoleRouter:
241
  profiles = [ProviderConfig(
242
  name="openrouter", api_key=os.getenv("OPENROUTER_API_KEY", ""),
243
  base_url="https://openrouter.ai/api/v1",
244
- default_model=os.getenv("OPENROUTER_MODEL", "openai/gpt-oss-20b:free"),
245
  profile="legacy",
246
  )]
247
  if profiles:
@@ -273,7 +273,7 @@ class RoleRouter:
273
  base_url="https://api.groq.com/openai/v1",
274
  default_model=os.getenv(
275
  "GROQ_RESEARCH_MODEL",
276
- os.getenv("GROQ_MODEL", "openai/gpt-oss-120b"),
277
  ),
278
  )
279
  rest = [
@@ -307,7 +307,7 @@ class RoleRouter:
307
  base_url="https://api.groq.com/openai/v1",
308
  default_model=os.getenv(
309
  "GROQ_REASONER_MODEL",
310
- os.getenv("GROQ_MODEL", "openai/gpt-oss-120b"),
311
  ),
312
  )
313
  rest = [
@@ -406,7 +406,7 @@ class RoleRouter:
406
  name="groq-tester",
407
  api_key=groq_key,
408
  base_url="https://api.groq.com/openai/v1",
409
- default_model=os.getenv("GROQ_FAST_MODEL", "openai/gpt-oss-20b"),
410
  purpose="coding",
411
  )
412
  rest = [p for p in client.providers if p.name not in ("groq", "groq-tester")]
 
3
 
4
  BENCHMARK RESULTS 2026-06-14 FINALE (14 modelli × 3 test, max_tokens corretti):
5
  100% qualità (ordinati per TTFT):
6
+ #1 Groq / qwen/qwen3.6-27b — 170ms 100% ← FASTEST
7
  #2 Cerebras / gpt-oss-120b — 207ms 100% ← REASONING (max_tokens≥500)
8
+ #3 Groq / qwen/qwen3.6-27b — 235ms 100%
9
  #4 Cerebras / zai-glm-4.7 — 254ms 100%
10
  #5 Groq / compound-mini — 341ms 100%
11
  #6 SambaNova / DeepSeek-V3.1 — 482ms 100%
12
  #7 SambaNova / gemma-4-31B — 2132ms 100%
13
+ #8 OpenRouter / openrouter/free — 2160ms 100%
14
 
15
  Role assignments 2026-06-14 FINALE:
16
+ FAST → Groq qwen/qwen3.6-27b (170ms, 100%) ← #1 assoluto
17
  ARCHITECT → Groq llama-4-scout-17b 10M ctx (244ms, 67% — best per contesto lungo)
18
+ CODER → Groq qwen/qwen3.6-27b (235ms, 100%) ← #3 qualità
19
+ TESTER → Groq qwen/qwen3.6-27b
20
+ CONTEXT → Groq qwen/qwen3.6-27b
21
  RESEARCHER → Gemini 2.5-flash (599ms, 67% — math prompt-sensitive)
22
  REASONER → Cerebras gpt-oss-120b (207ms, 100%, reasoning model → max_tokens≥500)
23
  SAMBANOVA → SambaNova DeepSeek-V3.1 (482ms, 100%)
24
+ DEFAULT → AIClient() primary (qwen/qwen3.6-27b o primo disponibile)
25
 
26
+ OpenRouter tenuto come fallback secondario (openrouter/free = 1645ms ma 100% qualità).
27
  """
28
  from __future__ import annotations
29
 
 
36
 
37
 
38
  class Role(str, Enum):
39
+ FAST = "fast" # greetings, math semplice, identity — qwen/qwen3.6-27b
40
  ARCHITECT = "architect" # planning, ragionamento complesso — GPT-OSS 120B
41
+ CODER = "coder" # coding, debug — qwen/qwen3.6-27b
42
+ TESTER = "tester" # test gen, debug hints — qwen/qwen3.6-27b
43
+ CONTEXT = "context" # summarization, context compression — qwen/qwen3.6-27b
44
  DEFAULT = "default" # AIClient() primary
45
  RESEARCHER = "researcher" # web research + document synthesis — GPT-OSS 120B
46
  REASONER = "reasoner" # throughput massimo — Cerebras GPT-OSS 120B
 
122
  name="groq-fast",
123
  api_key=groq_key,
124
  base_url="https://api.groq.com/openai/v1",
125
+ default_model=os.getenv("GROQ_FAST_MODEL", "qwen/qwen3.6-27b"),
126
  )
127
  rest = [p for p in client.providers if p.name not in ("groq", "groq-fast", "groq-tester")]
128
  client.providers = [fast, *rest]
 
163
  name="groq-architect",
164
  api_key=groq_key,
165
  base_url="https://api.groq.com/openai/v1",
166
+ default_model=os.getenv("ARCHITECT_MODEL", "qwen/qwen3.6-27b"),
167
  )
168
  rest = [p for p in client.providers if p.name not in ("groq", "groq-architect")]
169
  client.providers = [architect, *rest]
 
179
  profiles = [ProviderConfig(
180
  name="openrouter", api_key=os.getenv("OPENROUTER_API_KEY", ""),
181
  base_url="https://openrouter.ai/api/v1",
182
+ default_model=os.getenv("OPENROUTER_MODEL", "openrouter/free"),
183
  profile="legacy",
184
  )]
185
  if profiles:
 
201
  return profiled
202
  groq_key = os.getenv("GROQ_API_KEY")
203
  nvidia_key = os.getenv("NVIDIA_API_KEY")
204
+ model = os.getenv("CODER_MODEL", "qwen/qwen3.6-27b")
205
  if groq_key:
206
  client = AIClient()
207
  coder = ProviderConfig(
 
241
  profiles = [ProviderConfig(
242
  name="openrouter", api_key=os.getenv("OPENROUTER_API_KEY", ""),
243
  base_url="https://openrouter.ai/api/v1",
244
+ default_model=os.getenv("OPENROUTER_MODEL", "openrouter/free"),
245
  profile="legacy",
246
  )]
247
  if profiles:
 
273
  base_url="https://api.groq.com/openai/v1",
274
  default_model=os.getenv(
275
  "GROQ_RESEARCH_MODEL",
276
+ os.getenv("GROQ_MODEL", "qwen/qwen3.6-27b"),
277
  ),
278
  )
279
  rest = [
 
307
  base_url="https://api.groq.com/openai/v1",
308
  default_model=os.getenv(
309
  "GROQ_REASONER_MODEL",
310
+ os.getenv("GROQ_MODEL", "qwen/qwen3.6-27b"),
311
  ),
312
  )
313
  rest = [
 
406
  name="groq-tester",
407
  api_key=groq_key,
408
  base_url="https://api.groq.com/openai/v1",
409
+ default_model=os.getenv("GROQ_FAST_MODEL", "qwen/qwen3.6-27b"),
410
  purpose="coding",
411
  )
412
  rest = [p for p in client.providers if p.name not in ("groq", "groq-tester")]
tests/test_provider_model_migrations.py CHANGED
@@ -47,7 +47,7 @@ class RoleRouterModelMigrationTests(unittest.TestCase):
47
  client = RoleRouter.get_client(Role.ARCHITECT)
48
 
49
  self.assertEqual(client.provider_name, "groq-architect")
50
- self.assertEqual(client.default_model, "openai/gpt-oss-120b")
51
 
52
  @patch.object(AIClient, "_load_providers", return_value=[])
53
  @patch.dict(
@@ -59,8 +59,8 @@ class RoleRouterModelMigrationTests(unittest.TestCase):
59
  architect = RoleRouter.get_client(Role.ARCHITECT)
60
  coder = RoleRouter.get_client(Role.CODER)
61
 
62
- self.assertEqual(architect.default_model, "openai/gpt-oss-20b:free")
63
- self.assertEqual(coder.default_model, "openai/gpt-oss-20b:free")
64
 
65
  @patch.object(AIClient, "_load_providers", return_value=[])
66
  @patch.dict(
@@ -90,14 +90,14 @@ class ProviderTableMigrationTests(unittest.IsolatedAsyncioTestCase):
90
  self.assertEqual(len(fake_supabase.table_ref.calls), 8)
91
 
92
  expected = {
93
- ("groq", "llama-3.1-70b-versatile", "openai/gpt-oss-120b"),
94
  ("cerebras", "llama3.1-70b", "gpt-oss-120b"),
95
  ("nvidia", "llama-3.1-405b-instruct", "meta/llama-3.3-70b-instruct"),
96
- ("openrouter", "llama-3.1-405b", "openai/gpt-oss-20b:free"),
97
  ("sambanova", "llama3-70b", "DeepSeek-V3.2"),
98
  ("gemini", "gemini-1.5-flash", "gemini-3.5-flash-lite"),
99
  ("gemini", "gemini-1.5-pro", "gemini-3.6-flash"),
100
- ("openrouter", "claude-3.5-sonnet", "openai/gpt-oss-20b:free"),
101
  }
102
  actual = {
103
  (
 
47
  client = RoleRouter.get_client(Role.ARCHITECT)
48
 
49
  self.assertEqual(client.provider_name, "groq-architect")
50
+ self.assertEqual(client.default_model, "qwen/qwen3.6-27b")
51
 
52
  @patch.object(AIClient, "_load_providers", return_value=[])
53
  @patch.dict(
 
59
  architect = RoleRouter.get_client(Role.ARCHITECT)
60
  coder = RoleRouter.get_client(Role.CODER)
61
 
62
+ self.assertEqual(architect.default_model, "openrouter/free")
63
+ self.assertEqual(coder.default_model, "openrouter/free")
64
 
65
  @patch.object(AIClient, "_load_providers", return_value=[])
66
  @patch.dict(
 
90
  self.assertEqual(len(fake_supabase.table_ref.calls), 8)
91
 
92
  expected = {
93
+ ("groq", "llama-3.1-70b-versatile", "qwen/qwen3.6-27b"),
94
  ("cerebras", "llama3.1-70b", "gpt-oss-120b"),
95
  ("nvidia", "llama-3.1-405b-instruct", "meta/llama-3.3-70b-instruct"),
96
+ ("openrouter", "llama-3.1-405b", "openrouter/free"),
97
  ("sambanova", "llama3-70b", "DeepSeek-V3.2"),
98
  ("gemini", "gemini-1.5-flash", "gemini-3.5-flash-lite"),
99
  ("gemini", "gemini-1.5-pro", "gemini-3.6-flash"),
100
+ ("openrouter", "claude-3.5-sonnet", "openrouter/free"),
101
  }
102
  actual = {
103
  (