Aksel Joonas Reedi commited on
Commit
1c0de34
Β·
unverified Β·
1 Parent(s): 182ddee

CLI /model: accept any inference-provider model id

Browse files
Files changed (1) hide show
  1. agent/main.py +43 -9
agent/main.py CHANGED
@@ -45,14 +45,38 @@ from agent.utils.terminal_display import (
45
 
46
  litellm.drop_params = True
47
 
48
- # ── Available models (mirrors backend/routes/agent.py) ──────────────────
49
- AVAILABLE_MODELS = [
 
 
 
50
  {"id": "anthropic/claude-opus-4-6", "label": "Claude Opus 4.6"},
51
  {"id": "huggingface/fireworks-ai/MiniMaxAI/MiniMax-M2.5", "label": "MiniMax M2.5"},
52
  {"id": "huggingface/novita/moonshotai/kimi-k2.5", "label": "Kimi K2.5"},
53
  {"id": "huggingface/novita/zai-org/glm-5", "label": "GLM 5"},
54
  ]
55
- VALID_MODEL_IDS = {m["id"] for m in AVAILABLE_MODELS}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
 
58
  def _safe_get_args(arguments: dict) -> dict:
@@ -668,16 +692,26 @@ def _handle_slash_command(
668
 
669
  if command == "/model":
670
  if not arg:
671
- print("Available models:")
672
- session = session_holder[0] if session_holder else None
673
  current = config.model_name if config else ""
674
- for m in AVAILABLE_MODELS:
 
 
 
675
  marker = " <-- current" if m["id"] == current else ""
676
  print(f" {m['id']} ({m['label']}){marker}")
 
 
 
 
677
  return None
678
- if arg not in VALID_MODEL_IDS:
679
- print(f"Unknown model: {arg}")
680
- print(f"Valid: {', '.join(VALID_MODEL_IDS)}")
 
 
 
 
 
681
  return None
682
  session = session_holder[0] if session_holder else None
683
  if session:
 
45
 
46
  litellm.drop_params = True
47
 
48
+ # ── Suggested models shown by `/model` (not a gate) ──────────────────────
49
+ # Any model id accepted by litellm is usable; for the HF router the form is
50
+ # `huggingface/<inference_provider>/<org>/<model>` and users can pick any
51
+ # model supported by any HF inference provider.
52
+ SUGGESTED_MODELS = [
53
  {"id": "anthropic/claude-opus-4-6", "label": "Claude Opus 4.6"},
54
  {"id": "huggingface/fireworks-ai/MiniMaxAI/MiniMax-M2.5", "label": "MiniMax M2.5"},
55
  {"id": "huggingface/novita/moonshotai/kimi-k2.5", "label": "Kimi K2.5"},
56
  {"id": "huggingface/novita/zai-org/glm-5", "label": "GLM 5"},
57
  ]
58
+
59
+
60
+ def _is_valid_model_id(model_id: str) -> bool:
61
+ """Loose format check β€” lets users pick any inference-provider model.
62
+
63
+ Accepts:
64
+ β€’ huggingface/<provider>/<org>/<model> (HF router)
65
+ β€’ anthropic/<model>
66
+ β€’ openai/<model>
67
+ Actual availability is verified by the provider when the first call
68
+ is made; we don't want to maintain a hardcoded allowlist.
69
+ """
70
+ if not model_id or "/" not in model_id:
71
+ return False
72
+ if model_id.startswith("huggingface/"):
73
+ # needs provider + org + model β†’ at least 3 slashes after the prefix
74
+ parts = model_id.split("/")
75
+ return len(parts) >= 4 and all(parts)
76
+ if model_id.startswith(("anthropic/", "openai/")):
77
+ parts = model_id.split("/", 1)
78
+ return len(parts) == 2 and bool(parts[1])
79
+ return False
80
 
81
 
82
  def _safe_get_args(arguments: dict) -> dict:
 
692
 
693
  if command == "/model":
694
  if not arg:
 
 
695
  current = config.model_name if config else ""
696
+ print("Current model:")
697
+ print(f" {current}")
698
+ print("\nSuggested models (any HF inference-provider model works):")
699
+ for m in SUGGESTED_MODELS:
700
  marker = " <-- current" if m["id"] == current else ""
701
  print(f" {m['id']} ({m['label']}){marker}")
702
+ print(
703
+ "\nPass any id, e.g. huggingface/<provider>/<org>/<model>.\n"
704
+ "Availability is verified on first use."
705
+ )
706
  return None
707
+ if not _is_valid_model_id(arg):
708
+ print(f"Invalid model id format: {arg}")
709
+ print(
710
+ "Expected one of:\n"
711
+ " β€’ huggingface/<provider>/<org>/<model>\n"
712
+ " β€’ anthropic/<model>\n"
713
+ " β€’ openai/<model>"
714
+ )
715
  return None
716
  session = session_holder[0] if session_holder else None
717
  if session: