From bd817c6ab0ce240c671a7e9ca64a696a1b731cb4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 17 Jul 2026 09:25:25 +0000 Subject: [PATCH] Modify the Codex model --- README.md | 22 ++++++++++-------- SKILL.md | 2 +- scripts/run_review.py | 39 +++++++++++++++++++++++-------- tests/test_init_codex.py | 50 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6a31b52..a72135c 100644 --- a/README.md +++ b/README.md @@ -83,11 +83,14 @@ python3 scripts/run_review.py --context ./workspace/review_context.json --gemini # Use Codex's internal sandbox instead of the default bypass mode python3 scripts/run_review.py --context ./workspace/review_context.json --codex-use-sandbox -o ./review-output -# Specify consolidation model (default: codex-spark) +# Specify a non-default consolidation provider (default: codex-spark) python3 scripts/run_review.py --context ./workspace/review_context.json --gemini --consolidation-model gemini -o ./review-output -# Explicitly pin the default Codex Spark consolidation settings -python3 scripts/run_review.py --context ./workspace/review_context.json --gemini --consolidation-model codex-spark --codex-reasoning-effort xhigh -o ./review-output +# Explicitly pin the default GPT-5.3-Codex-Spark consolidation settings +python3 scripts/run_review.py --context ./workspace/review_context.json --consolidation-model codex-spark --codex-reasoning-effort xhigh -o ./review-output + +# Use GPT-5.6-Sol for consolidation instead +python3 scripts/run_review.py --context ./workspace/review_context.json --gemini --consolidation-model codex --codex-reasoning-effort xhigh -o ./review-output ``` ### GitCode One-Click Review @@ -125,7 +128,7 @@ Default layout for `openHiTLS/hitls4j` PR `35`: | `--codex-reasoning-effort` | Override Codex reasoning effort: low, medium, high, or xhigh (default: xhigh) | | `--init`, `-i` | Initialize AI tools before review | | `--no-consolidate` | Skip consolidation phase | -| `--consolidation-model` | AI model for consolidation phase: claude, gemini, codex, codex-spark, or opencode (default: codex-spark) | +| `--consolidation-model` | AI provider/model for consolidation phase: claude, gemini, codex, codex-spark, or opencode (default: codex-spark using `gpt-5.3-codex-spark`; codex uses `gpt-5.6-sol`) | | `--base-ref` | Base ref for diff (default: origin/main) | | `--head-ref` | Head ref for diff (default: HEAD) | | `--custom-rules` | Custom review rules text to inject into the review prompt | @@ -175,10 +178,9 @@ PR URL --> fetch_pr.py --clone --> cloned repo + context.json +----------------+----------------+----------------+----------------+ | Consolidation Phase - (Codex Spark validates by default - with xhigh reasoning effort, - use --consolidation-model to change, - including codex-spark and opencode) + (Codex GPT-5.6-Sol validates by default + with xhigh reasoning effort; use + --consolidation-model to change provider) | final_report.md/html/json ``` @@ -309,10 +311,10 @@ FIX: |------|---------------|----------------| | Claude | `claude -p --output-format text --dangerously-skip-permissions ""` | `--dangerously-skip-permissions` | | Gemini | `gemini -p "" -y` | `-y` (YOLO mode) | -| Codex | `codex exec --dangerously-bypass-approvals-and-sandbox -` | `--dangerously-bypass-approvals-and-sandbox` | +| Codex | `codex exec --model gpt-5.6-sol --dangerously-bypass-approvals-and-sandbox -` | `--dangerously-bypass-approvals-and-sandbox` | | OpenCode | `opencode run --dangerously-skip-permissions ""` | `--dangerously-skip-permissions` | -**Note**: Codex reads the prompt from stdin via `-`. Gemini, Claude, and OpenCode run headlessly by receiving the prompt as a CLI argument. Codex now bypasses its internal sandbox by default; pass `--codex-use-sandbox` to restore the older `--full-auto` mode. `run_review.py` now defaults `--codex-reasoning-effort` to `xhigh`, and consolidation defaults to `--consolidation-model codex-spark`, which maps to `gpt-5.3-codex-spark`. The review flow is constrained to the local checkout and should not need remote PR pages or web search. +**Note**: Codex reads the prompt from stdin via `-`. Gemini, Claude, and OpenCode run headlessly by receiving the prompt as a CLI argument. Regular Codex phases use `gpt-5.6-sol` with `--codex-reasoning-effort xhigh` by default, while consolidation defaults to `gpt-5.3-codex-spark`; pass `--consolidation-model codex` to use `gpt-5.6-sol` for consolidation. Codex bypasses its internal sandbox by default; pass `--codex-use-sandbox` to restore the older `--full-auto` mode. The review flow is constrained to the local checkout and should not need remote PR pages or web search. ## Timeouts diff --git a/SKILL.md b/SKILL.md index c21cc6f..367a866 100644 --- a/SKILL.md +++ b/SKILL.md @@ -172,7 +172,7 @@ npm install -g @openai/codex |------|---------|-----------| | Claude | `claude -p --output-format text --dangerously-skip-permissions` | `--dangerously-skip-permissions` | | Gemini | `gemini -y` | `-y` | -| Codex | `codex exec --dangerously-bypass-approvals-and-sandbox -` | `--dangerously-bypass-approvals-and-sandbox` | +| Codex | `codex exec --model gpt-5.6-sol --dangerously-bypass-approvals-and-sandbox -` | `--dangerously-bypass-approvals-and-sandbox` | - Initialization runs in **parallel** for all enabled tools - Init timeout: 10 min, Review timeout: 30 min diff --git a/scripts/run_review.py b/scripts/run_review.py index 661a64b..56755aa 100644 --- a/scripts/run_review.py +++ b/scripts/run_review.py @@ -25,10 +25,13 @@ import pr_comments as pr_comments_module +DEFAULT_CODEX_MODEL = "gpt-5.6-sol" CODEX_SPARK_MODEL = "gpt-5.3-codex-spark" CODEX_REASONING_EFFORT_CHOICES = ["low", "medium", "high", "xhigh"] DEFAULT_CONSOLIDATION_MODEL = "codex-spark" DEFAULT_CODEX_REASONING_EFFORT = "xhigh" +CODEX_INIT_REASONING_EFFORT = "low" +CODEX_INIT_TIMEOUT_SECONDS = 180 @dataclass @@ -225,12 +228,15 @@ def build_codex_command( repo_dir: Path, *, use_sandbox: bool = False, - model: Optional[str] = None, + model: Optional[str] = DEFAULT_CODEX_MODEL, reasoning_effort: Optional[str] = DEFAULT_CODEX_REASONING_EFFORT, + ignore_user_config: bool = False, ) -> list[str]: """Build a Codex CLI command for this repository.""" command = ['codex', 'exec'] + if ignore_user_config: + command.append('--ignore-user-config') if model: command.extend(['--model', model]) if reasoning_effort: @@ -528,8 +534,8 @@ def init_claude(repo_dir: Path) -> bool: def init_codex( repo_dir: Path, use_sandbox: bool = False, - model: Optional[str] = None, - reasoning_effort: Optional[str] = DEFAULT_CODEX_REASONING_EFFORT, + model: Optional[str] = DEFAULT_CODEX_MODEL, + reasoning_effort: Optional[str] = CODEX_INIT_REASONING_EFFORT, ) -> bool: """Initialize Codex context by generating AGENTS.md if not exists. @@ -555,6 +561,7 @@ def init_codex( use_sandbox=use_sandbox, model=model, reasoning_effort=reasoning_effort, + ignore_user_config=True, ) command[-1:-1] = ['--output-last-message', str(agents_md)] proc = subprocess.run( @@ -563,7 +570,7 @@ def init_codex( capture_output=True, text=True, cwd=repo_dir, - timeout=600 + timeout=CODEX_INIT_TIMEOUT_SECONDS, ) if agents_md.exists() and agents_md.stat().st_size > 0: print_success("AGENTS.md generated") @@ -575,6 +582,14 @@ def init_codex( if proc.stderr: print_warning(f"stderr: {proc.stderr[:500]}") return False + except subprocess.TimeoutExpired: + if agents_md.exists() and agents_md.stat().st_size > 0: + print_success("AGENTS.md generated before Codex init timed out") + return True + print_warning( + f"Codex init timed out after {CODEX_INIT_TIMEOUT_SECONDS} seconds" + ) + return False except Exception as e: print_warning(f"Codex init failed: {e}") return False @@ -717,7 +732,7 @@ def init_agents_md( if use_codex and init_codex( repo_dir, use_sandbox=codex_use_sandbox, - reasoning_effort=codex_reasoning_effort, + reasoning_effort=CODEX_INIT_REASONING_EFFORT, ): return True @@ -974,7 +989,7 @@ def run_codex_agent( prompt: str, output_file: Path, use_sandbox: bool = False, - model: Optional[str] = None, + model: Optional[str] = DEFAULT_CODEX_MODEL, reasoning_effort: Optional[str] = DEFAULT_CODEX_REASONING_EFFORT, ) -> tuple[Path, list[str]]: """Run generic Codex CLI agent with real-time output streaming.""" @@ -1001,7 +1016,7 @@ def run_codex_review_agent( prompt: str, output_file: Path, use_sandbox: bool = False, - model: Optional[str] = None, + model: Optional[str] = DEFAULT_CODEX_MODEL, reasoning_effort: Optional[str] = DEFAULT_CODEX_REASONING_EFFORT, ) -> tuple[Path, list[str]]: """Run Codex CLI for review using the project-specific stdin prompt.""" @@ -1399,11 +1414,12 @@ def run_consolidation( agent_map = { 'claude': ('Claude Code', lambda repo_dir, prompt, output_file: run_claude_agent(repo_dir, prompt, output_file)), 'gemini': ('Gemini CLI', lambda repo_dir, prompt, output_file: run_gemini_agent(repo_dir, prompt, output_file)), - 'codex': ('Codex CLI', lambda repo_dir, prompt, output_file: run_codex_agent( + 'codex': ('Codex CLI (GPT-5.6-Sol)', lambda repo_dir, prompt, output_file: run_codex_agent( repo_dir, prompt, output_file, use_sandbox=codex_use_sandbox, + model=DEFAULT_CODEX_MODEL, reasoning_effort=codex_reasoning_effort, )), 'codex-spark': ('Codex CLI (GPT-5.3-Codex-Spark)', lambda repo_dir, prompt, output_file: run_codex_agent( @@ -1879,7 +1895,10 @@ def main(): %(prog)s --context ./workspace/review_context.json --gemini --output ./review-output # Explicitly pin the default Codex Spark consolidation settings - %(prog)s --context ./workspace/review_context.json --gemini --consolidation-model codex-spark --codex-reasoning-effort xhigh --output ./review-output + %(prog)s --context ./workspace/review_context.json --consolidation-model codex-spark --codex-reasoning-effort xhigh --output ./review-output + + # Use GPT-5.6-Sol for consolidation instead + %(prog)s --context ./workspace/review_context.json --gemini --consolidation-model codex --codex-reasoning-effort xhigh --output ./review-output AI Tool Context Files: - Claude Code: CLAUDE.md (project instructions, coding style) @@ -1920,7 +1939,7 @@ def main(): help="Head ref for diff (default: HEAD)") parser.add_argument("--consolidation-model", type=str, default=DEFAULT_CONSOLIDATION_MODEL, choices=['claude', 'gemini', 'codex', 'codex-spark', 'opencode'], - help=f"AI model for consolidation phase (default: {DEFAULT_CONSOLIDATION_MODEL})") + help=f"AI provider for consolidation phase (default: {DEFAULT_CONSOLIDATION_MODEL})") parser.add_argument("--custom-rules", type=str, default=None, help="Custom review rules text to inject into the review prompt") parser.add_argument("--custom-rules-file", type=Path, default=None, diff --git a/tests/test_init_codex.py b/tests/test_init_codex.py index 220f8a3..e82724d 100644 --- a/tests/test_init_codex.py +++ b/tests/test_init_codex.py @@ -25,6 +25,14 @@ def test_init_codex_writes_last_message_to_agents_md(self): def fake_run(cmd, **kwargs): self.assertIn("--output-last-message", cmd) + self.assertIn("--ignore-user-config", cmd) + self.assertIn( + f'model_reasoning_effort="{run_review.CODEX_INIT_REASONING_EFFORT}"', + cmd, + ) + self.assertEqual( + kwargs["timeout"], run_review.CODEX_INIT_TIMEOUT_SECONDS + ) output_path = Path(cmd[cmd.index("--output-last-message") + 1]) output_path.write_text("# Project Overview\nGenerated by test.\n") return subprocess.CompletedProcess(cmd, 0, "", "") @@ -92,6 +100,8 @@ def test_build_codex_command_bypasses_sandbox_by_default(self): ) self.assertIn("-c", cmd) + self.assertIn("--model", cmd) + self.assertIn(run_review.DEFAULT_CODEX_MODEL, cmd) self.assertIn( f'model_reasoning_effort="{run_review.DEFAULT_CODEX_REASONING_EFFORT}"', cmd, @@ -110,15 +120,23 @@ def test_build_codex_command_can_use_sandbox(self): self.assertNotIn("--dangerously-bypass-approvals-and-sandbox", cmd) self.assertEqual(cmd[-1], "-") + def test_build_codex_command_can_ignore_user_config(self): + cmd = run_review.build_codex_command( + Path("/tmp/repo"), + ignore_user_config=True, + ) + + self.assertIn("--ignore-user-config", cmd) + def test_build_codex_command_can_set_model_and_reasoning_effort(self): cmd = run_review.build_codex_command( Path("/tmp/repo"), - model=run_review.CODEX_SPARK_MODEL, + model=run_review.DEFAULT_CODEX_MODEL, reasoning_effort="xhigh", ) self.assertIn("--model", cmd) - self.assertIn(run_review.CODEX_SPARK_MODEL, cmd) + self.assertIn(run_review.DEFAULT_CODEX_MODEL, cmd) self.assertIn("-c", cmd) self.assertIn('model_reasoning_effort="xhigh"', cmd) self.assertEqual(cmd[-1], "-") @@ -360,6 +378,34 @@ def test_run_consolidation_defaults_to_codex_spark_with_xhigh_reasoning_effort(s run_review.DEFAULT_CODEX_REASONING_EFFORT, ) + def test_run_consolidation_supports_explicit_codex_sol(self): + with tempfile.TemporaryDirectory() as tmpdir: + repo_dir = Path(tmpdir) / "repo" + repo_dir.mkdir() + output_dir = Path(tmpdir) / "out" + output_dir.mkdir() + review_report = output_dir / "gemini_review.md" + review_report.write_text("===ISSUE===\nFILE: src/main.py\nLINE: 1\nTITLE: t\n===END===\n") + + with patch( + "scripts.run_review.run_codex_agent", + return_value=(output_dir / "consolidation_output.txt", []), + ) as mock_codex: + run_review.run_consolidation( + repo_dir=repo_dir, + review_reports={"gemini": review_report}, + context={"owner": "owner", "repo": "repo", "pr_id": "123"}, + output_dir=output_dir, + consolidation_model="codex", + ) + + kwargs = mock_codex.call_args.kwargs + self.assertEqual(kwargs["model"], run_review.DEFAULT_CODEX_MODEL) + self.assertEqual( + kwargs["reasoning_effort"], + run_review.DEFAULT_CODEX_REASONING_EFFORT, + ) + def test_run_consolidation_supports_opencode(self): with tempfile.TemporaryDirectory() as tmpdir: repo_dir = Path(tmpdir) / "repo"