Seunghyeon Kim akseljoonas commited on
Commit
ae86333
·
unverified ·
1 Parent(s): 7a76ad1

Honor interactive model override after current CLI changes (#111)

Browse files

The interactive CLI accepted --model but did not pass it into main(), so the REPL used the configured default while headless mode honored the flag. Reapply the override on top of the current token/session plumbing by changing only the interactive main signature, config override, and CLI dispatch.

Constraint: Current main already passes user_id into submission_loop and uses shared HF token resolution; this fix must preserve both paths.

Rejected: Reuse the old PR diff verbatim | it drops newer user_id/session identity changes and conflicts with current main.

Confidence: high

Scope-risk: narrow

Directive: Keep --model behavior identical for interactive and headless paths; banner should render the resolved model.

Tested: python -m py_compile agent/main.py tests/unit/test_cli_rendering.py

Tested: UV_CACHE_DIR=/tmp/uv-cache uv run --extra dev pytest tests/unit/test_cli_rendering.py -q

Tested: UV_CACHE_DIR=/tmp/uv-cache uv run --extra dev pytest tests/unit/test_llm_params.py tests/unit/test_hf_access.py tests/unit/test_user_quotas.py -q

Co-authored-by: akseljoonas <aksel.reedi@gmail.com>

Files changed (2) hide show
  1. agent/main.py +4 -2
  2. tests/unit/test_cli_rendering.py +46 -0
agent/main.py CHANGED
@@ -807,7 +807,7 @@ async def _handle_slash_command(
807
  return None
808
 
809
 
810
- async def main():
811
  """Interactive chat with the agent"""
812
 
813
  # Clear screen
@@ -822,6 +822,8 @@ async def main():
822
  hf_token = await _prompt_and_save_hf_token(prompt_session)
823
 
824
  config = load_config(CLI_CONFIG_PATH)
 
 
825
 
826
  # Resolve username for banner
827
  hf_user = _get_hf_user(hf_token)
@@ -1240,7 +1242,7 @@ def cli():
1240
  max_iter = 10_000 # effectively unlimited
1241
  asyncio.run(headless_main(args.prompt, model=args.model, max_iterations=max_iter, stream=not args.no_stream))
1242
  else:
1243
- asyncio.run(main())
1244
  except KeyboardInterrupt:
1245
  print("\n\nGoodbye!")
1246
 
 
807
  return None
808
 
809
 
810
+ async def main(model: str | None = None):
811
  """Interactive chat with the agent"""
812
 
813
  # Clear screen
 
822
  hf_token = await _prompt_and_save_hf_token(prompt_session)
823
 
824
  config = load_config(CLI_CONFIG_PATH)
825
+ if model:
826
+ config.model_name = model
827
 
828
  # Resolve username for banner
829
  hf_user = _get_hf_user(hf_token)
 
1242
  max_iter = 10_000 # effectively unlimited
1243
  asyncio.run(headless_main(args.prompt, model=args.model, max_iterations=max_iter, stream=not args.no_stream))
1244
  else:
1245
+ asyncio.run(main(model=args.model))
1246
  except KeyboardInterrupt:
1247
  print("\n\nGoodbye!")
1248
 
tests/unit/test_cli_rendering.py CHANGED
@@ -1,8 +1,12 @@
1
  """Regression tests for interactive CLI rendering and research model routing."""
2
 
 
3
  from io import StringIO
4
  from types import SimpleNamespace
5
 
 
 
 
6
  from agent.tools.research_tool import _get_research_model
7
  from agent.utils import terminal_display
8
 
@@ -42,3 +46,45 @@ def test_subagent_display_does_not_spawn_background_redraw(monkeypatch):
42
  mgr.clear("agent-1")
43
 
44
  assert calls == []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """Regression tests for interactive CLI rendering and research model routing."""
2
 
3
+ import sys
4
  from io import StringIO
5
  from types import SimpleNamespace
6
 
7
+ import pytest
8
+
9
+ import agent.main as main_mod
10
  from agent.tools.research_tool import _get_research_model
11
  from agent.utils import terminal_display
12
 
 
46
  mgr.clear("agent-1")
47
 
48
  assert calls == []
49
+
50
+
51
+ def test_cli_forwards_model_flag_to_interactive_main(monkeypatch):
52
+ seen: dict[str, str | None] = {}
53
+
54
+ async def fake_main(*, model=None):
55
+ seen["model"] = model
56
+
57
+ monkeypatch.setattr(sys, "argv", ["ml-intern", "--model", "openai/gpt-5.5"])
58
+ monkeypatch.setattr(main_mod, "main", fake_main)
59
+
60
+ main_mod.cli()
61
+
62
+ assert seen["model"] == "openai/gpt-5.5"
63
+
64
+
65
+ @pytest.mark.asyncio
66
+ async def test_interactive_main_applies_model_override_before_banner(monkeypatch):
67
+ class StopAfterBanner(Exception):
68
+ pass
69
+
70
+ def fake_banner(*, model=None, hf_user=None):
71
+ assert model == "openai/gpt-5.5"
72
+ assert hf_user == "tester"
73
+ raise StopAfterBanner
74
+
75
+ monkeypatch.setattr(main_mod.os, "system", lambda *_args, **_kwargs: 0)
76
+ monkeypatch.setattr(main_mod, "PromptSession", lambda: object())
77
+ monkeypatch.setattr(main_mod, "resolve_hf_token", lambda: "hf-token")
78
+ monkeypatch.setattr(main_mod, "_get_hf_user", lambda _token: "tester")
79
+ monkeypatch.setattr(
80
+ main_mod,
81
+ "load_config",
82
+ lambda _path: SimpleNamespace(
83
+ model_name="moonshotai/Kimi-K2.6",
84
+ mcpServers={},
85
+ ),
86
+ )
87
+ monkeypatch.setattr(main_mod, "print_banner", fake_banner)
88
+
89
+ with pytest.raises(StopAfterBanner):
90
+ await main_mod.main(model="openai/gpt-5.5")