feat: add workdir flag and trim final output

This commit is contained in:
banteg
2025-12-29 02:08:44 +04:00
parent fbfc4eaa5a
commit 4e6e6e51ca
3 changed files with 19 additions and 3 deletions
+5 -1
View File
@@ -26,7 +26,7 @@ chat_id = 123456789
Optional keys (by mode): Optional keys (by mode):
- common: `bridge_db`, `allowed_chat_ids`, `startup_chat_ids` - common: `bridge_db`, `allowed_chat_ids`, `startup_chat_ids`
- exec/resume: `startup_message`, `codex_cmd`, `codex_workspace`, `codex_exec_args`, `max_workers` - exec/resume: `startup_message`, `codex_cmd`, `codex_workspace`, `codex_exec_args`, `max_workers`, `codex_io_mode`, `codex_command_timeout_s`, `codex_no_child_timeout_s`
- MCP server: `codex_mcp_cmd`, `codex_workspace`, `codex_sandbox`, `codex_approval_policy` - MCP server: `codex_mcp_cmd`, `codex_workspace`, `codex_sandbox`, `codex_approval_policy`
## Option 1: exec/resume ## Option 1: exec/resume
@@ -43,6 +43,10 @@ Optional flags:
- `--progress-silent/--no-progress-silent` (default silent) - `--progress-silent/--no-progress-silent` (default silent)
- `--final-notify/--no-final-notify` (default notify via new message) - `--final-notify/--no-final-notify` (default notify via new message)
- `--ignore-backlog/--process-backlog` (default ignore pending updates) - `--ignore-backlog/--process-backlog` (default ignore pending updates)
- `--codex-io-mode [threads|selectors|asyncio]` (default `threads`)
- `--codex-command-timeout FLOAT` (default: disabled, debug defaults to 60s)
- `--codex-no-child-timeout FLOAT` (default `15.0`, set `0` to disable)
- `--workdir PATH` (override `codex_workspace`)
## Option 2: MCP server ## Option 2: MCP server
@@ -329,6 +329,11 @@ def run(
"--log-file", "--log-file",
help="Write detailed debug logs to this file (set to empty to disable).", help="Write detailed debug logs to this file (set to empty to disable).",
), ),
workdir: Optional[str] = typer.Option(
None,
"--workdir",
help="Override codex workspace (--cd) for this exec-bridge run.",
),
) -> None: ) -> None:
setup_file_logger(log_file if log_file else None) setup_file_logger(log_file if log_file else None)
config = load_telegram_config() config = load_telegram_config()
@@ -342,7 +347,7 @@ def run(
startup_msg = f"{startup_msg}\nPWD: {startup_pwd}" startup_msg = f"{startup_msg}\nPWD: {startup_pwd}"
codex_cmd = config_get(config, "codex_cmd") or "codex" codex_cmd = config_get(config, "codex_cmd") or "codex"
workspace = config_get(config, "codex_workspace") workspace = workdir if workdir is not None else config_get(config, "codex_workspace")
raw_exec_args = config_get(config, "codex_exec_args") or "" raw_exec_args = config_get(config, "codex_exec_args") or ""
if isinstance(raw_exec_args, list): if isinstance(raw_exec_args, list):
extra_args = [str(v) for v in raw_exec_args] extra_args = [str(v) for v in raw_exec_args]
@@ -93,6 +93,10 @@ def _format_tool_call(server: str, tool: str) -> str:
name = ".".join(part for part in (server, tool) if part) name = ".".join(part for part in (server, tool) if part)
return name or "tool" return name or "tool"
def _is_command_log_line(line: str) -> bool:
return f"{STATUS_DONE} ran:" in line
def _extract_numeric_id(item_id: Optional[object], fallback: Optional[int] = None) -> Optional[int]: def _extract_numeric_id(item_id: Optional[object], fallback: Optional[int] = None) -> Optional[int]:
if isinstance(item_id, int): if isinstance(item_id, int):
return item_id return item_id
@@ -351,7 +355,10 @@ class ExecProgressRenderer:
def render_final(self, elapsed_s: float, answer: str, status: str = "done") -> str: def render_final(self, elapsed_s: float, answer: str, status: str = "done") -> str:
header = _format_header(elapsed_s, self.state.last_turn, label=status) header = _format_header(elapsed_s, self.state.last_turn, label=status)
body = self._assemble(header, list(self.state.recent_actions)) lines = list(self.state.recent_actions)
if status == "done":
lines = [line for line in lines if not _is_command_log_line(line)]
body = self._assemble(header, lines)
answer = (answer or "").strip() answer = (answer or "").strip()
if answer: if answer:
body = body + "\n\n" + answer body = body + "\n\n" + answer