duet-cli 0.2.3__tar.gz → 0.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {duet_cli-0.2.3/duet_cli.egg-info → duet_cli-0.2.5}/PKG-INFO +1 -1
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet.py +15 -2
- {duet_cli-0.2.3 → duet_cli-0.2.5/duet_cli.egg-info}/PKG-INFO +1 -1
- {duet_cli-0.2.3 → duet_cli-0.2.5}/pyproject.toml +1 -1
- {duet_cli-0.2.3 → duet_cli-0.2.5}/tests/test_duet.py +65 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/LICENSE +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/README.md +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet_cli.egg-info/SOURCES.txt +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet_cli.egg-info/dependency_links.txt +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet_cli.egg-info/entry_points.txt +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet_cli.egg-info/requires.txt +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/duet_cli.egg-info/top_level.txt +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/setup.cfg +0 -0
- {duet_cli-0.2.3 → duet_cli-0.2.5}/tests/test_bump_release_version.py +0 -0
|
@@ -3371,6 +3371,10 @@ def _build_arg_parser() -> argparse.ArgumentParser:
|
|
|
3371
3371
|
help="partner agent spec, e.g. codex:coder, claude:reviewer, gemini:coder, copilot:coder (default codex:coder)")
|
|
3372
3372
|
ap.add_argument("--lead", default="claude:planner",
|
|
3373
3373
|
help="lead agent spec, e.g. claude:planner, gemini:reviewer, copilot:planner (default; ignored if --resume-claude given)")
|
|
3374
|
+
ap.add_argument("--lead-model", metavar="MODEL", default=None,
|
|
3375
|
+
help="model name to pass to the lead agent's backend via --model")
|
|
3376
|
+
ap.add_argument("--partner-model", metavar="MODEL", default=None,
|
|
3377
|
+
help="model name to pass to the partner agent's backend via --model")
|
|
3374
3378
|
ap.add_argument("--cwd", default=".", help="working dir for both agents")
|
|
3375
3379
|
ap.add_argument("--turns", type=int, default=DEFAULT_TURNS, help=f"max turns (default {DEFAULT_TURNS})")
|
|
3376
3380
|
ap.add_argument("--sentinel", default=DEFAULT_SENTINEL,
|
|
@@ -3542,9 +3546,18 @@ def _build_cfg_from_cli(args: argparse.Namespace, ap: argparse.ArgumentParser,
|
|
|
3542
3546
|
parser=ap,
|
|
3543
3547
|
stdin_cache=stdin_cache,
|
|
3544
3548
|
)
|
|
3549
|
+
agents = [
|
|
3550
|
+
dataclasses.replace(
|
|
3551
|
+
parse_partner(args.lead, default_role="planner"),
|
|
3552
|
+
model=args.lead_model or None,
|
|
3553
|
+
),
|
|
3554
|
+
dataclasses.replace(
|
|
3555
|
+
parse_partner(args.partner, default_role="coder"),
|
|
3556
|
+
model=args.partner_model or None,
|
|
3557
|
+
),
|
|
3558
|
+
]
|
|
3545
3559
|
agents = apply_resume_overrides(
|
|
3546
|
-
|
|
3547
|
-
parse_partner(args.partner, default_role="coder")],
|
|
3560
|
+
agents,
|
|
3548
3561
|
resume_claude=args.resume_claude,
|
|
3549
3562
|
resume_codex=args.resume_codex,
|
|
3550
3563
|
rename_slots=True,
|
|
@@ -825,6 +825,45 @@ class TestParsePartner(unittest.TestCase):
|
|
|
825
825
|
self.assertEqual(agent.name, "copilot-coder")
|
|
826
826
|
|
|
827
827
|
|
|
828
|
+
# ---------- _build_cfg_from_cli ----------
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
class TestBuildCfgFromCli(unittest.TestCase):
|
|
832
|
+
def _parse(self, *argv: str):
|
|
833
|
+
parser = duet._build_arg_parser()
|
|
834
|
+
return parser, parser.parse_args(list(argv))
|
|
835
|
+
|
|
836
|
+
def test_lead_and_partner_models_attach_to_cli_agents(self) -> None:
|
|
837
|
+
parser, args = self._parse(
|
|
838
|
+
"--task", "x",
|
|
839
|
+
"--lead", "claude:reviewer",
|
|
840
|
+
"--partner", "codex:coder",
|
|
841
|
+
"--lead-model", "claude-opus-4-5",
|
|
842
|
+
"--partner-model", "gpt-5",
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
cfg = duet._build_cfg_from_cli(args, parser, {})
|
|
846
|
+
|
|
847
|
+
self.assertEqual(cfg.agents[0].backend, "claude")
|
|
848
|
+
self.assertEqual(cfg.agents[0].role, "reviewer")
|
|
849
|
+
self.assertEqual(cfg.agents[0].model, "claude-opus-4-5")
|
|
850
|
+
self.assertEqual(cfg.agents[1].backend, "codex")
|
|
851
|
+
self.assertEqual(cfg.agents[1].role, "coder")
|
|
852
|
+
self.assertEqual(cfg.agents[1].model, "gpt-5")
|
|
853
|
+
|
|
854
|
+
def test_empty_cli_model_flags_normalize_to_none(self) -> None:
|
|
855
|
+
parser, args = self._parse(
|
|
856
|
+
"--task", "x",
|
|
857
|
+
"--lead-model", "",
|
|
858
|
+
"--partner-model", "",
|
|
859
|
+
)
|
|
860
|
+
|
|
861
|
+
cfg = duet._build_cfg_from_cli(args, parser, {})
|
|
862
|
+
|
|
863
|
+
self.assertIsNone(cfg.agents[0].model)
|
|
864
|
+
self.assertIsNone(cfg.agents[1].model)
|
|
865
|
+
|
|
866
|
+
|
|
828
867
|
# ---------- apply_resume_overrides ----------
|
|
829
868
|
|
|
830
869
|
|
|
@@ -878,6 +917,32 @@ class TestApplyResumeOverrides(unittest.TestCase):
|
|
|
878
917
|
self.assertEqual(agents[1].role, "coder")
|
|
879
918
|
self.assertEqual(agents[1].session_id, "codex-sid")
|
|
880
919
|
|
|
920
|
+
def test_resume_codex_move_preserves_model(self) -> None:
|
|
921
|
+
agents = duet.apply_resume_overrides(
|
|
922
|
+
[
|
|
923
|
+
duet.Agent(
|
|
924
|
+
name="codex-planner",
|
|
925
|
+
backend="codex",
|
|
926
|
+
role="planner",
|
|
927
|
+
model="gpt-5",
|
|
928
|
+
),
|
|
929
|
+
duet.Agent(
|
|
930
|
+
name="claude-coder",
|
|
931
|
+
backend="claude",
|
|
932
|
+
role="coder",
|
|
933
|
+
model="claude-sonnet-4-6",
|
|
934
|
+
),
|
|
935
|
+
],
|
|
936
|
+
resume_codex="codex-sid",
|
|
937
|
+
rename_slots=True,
|
|
938
|
+
)
|
|
939
|
+
|
|
940
|
+
self.assertEqual(agents[0].backend, "claude")
|
|
941
|
+
self.assertEqual(agents[0].model, "claude-sonnet-4-6")
|
|
942
|
+
self.assertEqual(agents[1].backend, "codex")
|
|
943
|
+
self.assertEqual(agents[1].session_id, "codex-sid")
|
|
944
|
+
self.assertEqual(agents[1].model, "gpt-5")
|
|
945
|
+
|
|
881
946
|
def test_resume_claude_partner_moves_to_lead(self) -> None:
|
|
882
947
|
agents = duet.apply_resume_overrides(
|
|
883
948
|
[
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|