fix(codex): hardcode exec flags (#75)
This commit is contained in:
@@ -68,6 +68,8 @@ voice_transcription = true
|
||||
[codex]
|
||||
# optional: profile from ~/.codex/config.toml
|
||||
profile = "takopi"
|
||||
# optional: extra codex CLI args (exec flags are managed by Takopi)
|
||||
# extra_args = ["-c", "notify=[]"]
|
||||
|
||||
[claude]
|
||||
model = "sonnet"
|
||||
|
||||
+34
-11
@@ -25,18 +25,29 @@ _RECONNECTING_RE = re.compile(
|
||||
r"^Reconnecting\.{3}\s*(?P<attempt>\d+)/(?P<max>\d+)\s*$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
_EXEC_ONLY_FLAGS = {"--skip-git-repo-check"}
|
||||
_EXEC_ONLY_FLAGS = {
|
||||
"--skip-git-repo-check",
|
||||
"--json",
|
||||
"--output-schema",
|
||||
"--output-last-message",
|
||||
"--color",
|
||||
"-o",
|
||||
}
|
||||
_EXEC_ONLY_PREFIXES = (
|
||||
"--output-schema=",
|
||||
"--output-last-message=",
|
||||
"--color=",
|
||||
)
|
||||
|
||||
|
||||
def _split_exec_flags(extra_args: list[str]) -> tuple[list[str], list[str]]:
|
||||
base_args: list[str] = []
|
||||
exec_args: list[str] = []
|
||||
def _find_exec_only_flag(extra_args: list[str]) -> str | None:
|
||||
for arg in extra_args:
|
||||
if arg in _EXEC_ONLY_FLAGS:
|
||||
exec_args.append(arg)
|
||||
else:
|
||||
base_args.append(arg)
|
||||
return base_args, exec_args
|
||||
return arg
|
||||
for prefix in _EXEC_ONLY_PREFIXES:
|
||||
if arg.startswith(prefix):
|
||||
return arg
|
||||
return None
|
||||
|
||||
|
||||
def _parse_reconnect_message(message: str) -> tuple[int, int] | None:
|
||||
@@ -409,8 +420,13 @@ class CodexRunner(ResumeTokenMixin, JsonlSubprocessRunner):
|
||||
state: Any,
|
||||
) -> list[str]:
|
||||
_ = prompt, state
|
||||
base_args, exec_args = _split_exec_flags(self.extra_args)
|
||||
args = [*base_args, "exec", *exec_args, "--json"]
|
||||
args = [
|
||||
*self.extra_args,
|
||||
"exec",
|
||||
"--json",
|
||||
"--skip-git-repo-check",
|
||||
"--color=never",
|
||||
]
|
||||
if resume:
|
||||
args.extend(["resume", resume.value, "-"])
|
||||
else:
|
||||
@@ -585,7 +601,7 @@ def build_runner(config: EngineConfig, config_path: Path) -> Runner:
|
||||
|
||||
extra_args_value = config.get("extra_args")
|
||||
if extra_args_value is None:
|
||||
extra_args = ["-c", "notify=[]", "--skip-git-repo-check"]
|
||||
extra_args = ["-c", "notify=[]"]
|
||||
elif isinstance(extra_args_value, list) and all(
|
||||
isinstance(item, str) for item in extra_args_value
|
||||
):
|
||||
@@ -595,6 +611,13 @@ def build_runner(config: EngineConfig, config_path: Path) -> Runner:
|
||||
f"Invalid `codex.extra_args` in {config_path}; expected a list of strings."
|
||||
)
|
||||
|
||||
exec_only_flag = _find_exec_only_flag(extra_args)
|
||||
if exec_only_flag:
|
||||
raise ConfigError(
|
||||
f"Invalid `codex.extra_args` in {config_path}; exec-only flag "
|
||||
f"{exec_only_flag!r} is managed by Takopi."
|
||||
)
|
||||
|
||||
title = "Codex"
|
||||
profile_value = config.get("profile")
|
||||
if profile_value:
|
||||
|
||||
@@ -12,7 +12,7 @@ from takopi.model import (
|
||||
StartedEvent,
|
||||
TakopiEvent,
|
||||
)
|
||||
from takopi.runners.codex import CodexRunner
|
||||
from takopi.runners.codex import CodexRunner, _find_exec_only_flag
|
||||
|
||||
CODEX_ENGINE = EngineId("codex")
|
||||
|
||||
@@ -131,7 +131,7 @@ async def test_run_allows_parallel_different_sessions() -> None:
|
||||
def test_codex_exec_flags_after_exec() -> None:
|
||||
runner = CodexRunner(
|
||||
codex_cmd="codex",
|
||||
extra_args=["-c", "notify=[]", "--skip-git-repo-check"],
|
||||
extra_args=["-c", "notify=[]"],
|
||||
)
|
||||
state = runner.new_state("hi", None)
|
||||
args = runner.build_args("hi", None, state=state)
|
||||
@@ -139,12 +139,29 @@ def test_codex_exec_flags_after_exec() -> None:
|
||||
"-c",
|
||||
"notify=[]",
|
||||
"exec",
|
||||
"--skip-git-repo-check",
|
||||
"--json",
|
||||
"--skip-git-repo-check",
|
||||
"--color=never",
|
||||
"-",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("extra_args", "expected"),
|
||||
[
|
||||
([], None),
|
||||
(["-c", "notify=[]"], None),
|
||||
(["--skip-git-repo-check"], "--skip-git-repo-check"),
|
||||
(["--color=never"], "--color=never"),
|
||||
(["--output-schema", "schema.json"], "--output-schema"),
|
||||
(["--output-last-message=out.txt"], "--output-last-message=out.txt"),
|
||||
(["-o", "out.txt"], "-o"),
|
||||
],
|
||||
)
|
||||
def test_find_exec_only_flag(extra_args: list[str], expected: str | None) -> None:
|
||||
assert _find_exec_only_flag(extra_args) == expected
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_run_serializes_new_session_after_session_is_known(
|
||||
tmp_path, monkeypatch
|
||||
|
||||
Reference in New Issue
Block a user