TradingAgents/tradingagents/llm_clients/codex_binary.py

70 lines
2.0 KiB
Python

from __future__ import annotations
import os
import shutil
from pathlib import Path
def resolve_codex_binary(codex_binary: str | None) -> str | None:
explicit = _normalize_explicit_binary(codex_binary)
if explicit:
return explicit
env_value = _normalize_explicit_binary(os.getenv("CODEX_BINARY"))
if env_value:
return env_value
path_binary = shutil.which("codex")
if path_binary:
return path_binary
for candidate in _windows_codex_candidates():
if candidate.is_file():
return str(candidate)
return None
def codex_binary_error_message(codex_binary: str | None) -> str:
requested = codex_binary or os.getenv("CODEX_BINARY") or "codex"
message = (
f"Could not find Codex binary '{requested}'. Install Codex, ensure it is on PATH, "
"set the `CODEX_BINARY` environment variable, or configure `codex_binary` with the full executable path."
)
discovered = [str(path) for path in _windows_codex_candidates() if path.is_file()]
if discovered:
message += f" Detected candidate: {discovered[0]}"
return message
def _normalize_explicit_binary(value: str | None) -> str | None:
if not value:
return None
expanded = str(Path(value).expanduser())
has_separator = any(sep and sep in expanded for sep in (os.path.sep, os.path.altsep))
if has_separator:
return expanded if Path(expanded).is_file() else None
found = shutil.which(expanded)
return found or None
def _windows_codex_candidates() -> list[Path]:
if os.name != "nt":
return []
home = Path.home()
candidates = sorted(
home.glob(r".vscode/extensions/openai.chatgpt-*/bin/windows-x86_64/codex.exe"),
key=lambda path: path.stat().st_mtime if path.exists() else 0,
reverse=True,
)
candidates.extend(
[
home / ".codex" / "bin" / "codex.exe",
home / "AppData" / "Local" / "Programs" / "Codex" / "codex.exe",
]
)
return candidates