fix(host): daemon 循环把显式全局 flag 透传给 recover/run-due 子进程
上一轨 #266 只修了 --state,本轨补其余项:--codex-home、 --codex-bin、--model、--model-provider、--effort、--sandbox、 --approval-policy、--approval、--turn-timeout、--progress-interval。 旧循环只传 --config,子进程重解析回落到配置/默认值,与 daemon 本体跑 turn 时的 CLI 覆盖值不是同一套(run-due 的 Server 与 dispatch/run_task_turn 全读这些值)。 修法:配置解析覆盖 args 之前先快照显式 CLI 值,循环里只把显式 值原样放进子进程 argv;数值 flag 用 is not None 判定(0 是合法 显式值:turn-timeout 0 不限时、progress-interval 0 关进度); 相对路径原样透传(daemonize 不 chdir,子进程 cwd 一致)。 有意不传:--config(已传解析后 config_path)、daemon 专属 --interval/--foreground(子命令不接受)、--ignore-host-budget (定给云端 worker 路径,且 recover/run-due 都不查预算,传了 无行为差异、只留将来预算门继承口)。 --state 透传沿用 #266 语义原样(显式 is not None 才传),未改动。 回归:tests/test_host_daemon_passthrough.py 4 项。
This commit is contained in:
1 parent
2f68bb103d
commit
1462195872
2 files changed
+277
-1
No files matched your search
@@ -2532,6 +2532,25 @@ def main():
|
||||
# 本进程内所有 budget_exceeded(state, cfg) 检查随之失效,
|
||||
# dispatch 前置门、重试前检查、goal 循环顶检查一并放行。
|
||||
cfg = _effective_cfg(cfg, getattr(args, "ignore_host_budget", False))
|
||||
# daemon 循环透传用的显式 CLI 快照:必须在下面这组解析之前记,
|
||||
# 解析完就分不清“CLI 给的”还是“配置/默认解析出的”了(#266 的
|
||||
# --state 同款问题,只是这里覆盖全部全局 flag)。只有显式给出的
|
||||
# 才进子进程 argv;未显式给时不加,子进程按原规则自行解析,
|
||||
# 结果与 daemon 本体一致(且配置文件在 daemon 启动后被改时,
|
||||
# 子进程能拿到新配置,而不是 daemon 启动时冻结的旧解析值)。
|
||||
# --config 不在这里:循环里本来就传解析后的 config_path。
|
||||
# --ignore-host-budget 不在这里:见 daemon 循环里的说明。
|
||||
explicit_codex_home = args.codex_home
|
||||
explicit_codex_bin = args.codex_bin
|
||||
explicit_state = args.state
|
||||
explicit_model = args.model
|
||||
explicit_model_provider = args.model_provider
|
||||
explicit_effort = args.effort
|
||||
explicit_sandbox = args.sandbox
|
||||
explicit_approval_policy = args.approval_policy
|
||||
explicit_approval = args.approval
|
||||
explicit_turn_timeout = args.turn_timeout
|
||||
explicit_progress_interval = args.progress_interval
|
||||
args.model = args.model or cfg.get("model") or "gpt-5.6-terra"
|
||||
args.effort = args.effort or cfg.get("effort") or "low"
|
||||
args.sandbox = args.sandbox or cfg.get("sandbox")
|
||||
@@ -2790,13 +2809,59 @@ def main():
|
||||
while not stop["flag"]:
|
||||
ts = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
print(f"{ts} daemon tick: recover + run-due", flush=True)
|
||||
# 子进程只带显式 CLI flag(原值原样透传,不传解析后的值):
|
||||
# --state 是 #266 已定语义(显式才传),这里原样保留;
|
||||
# 其余全局 flag 同理——daemon 本体跑 turn 时用的就是这些
|
||||
# CLI 覆盖值,不传则子进程回落到配置/默认值,与 daemon
|
||||
# 本体不是同一套有效配置(codex_bin/home、model、
|
||||
# model_provider、sandbox、审批、超时、进度间隔全受影响;
|
||||
# run-due 的 Server 与 dispatch/run_task_turn 都读它们,
|
||||
# recover 读 state/codex 相关配置)。数值 flag 用
|
||||
# is not None 判定:--turn-timeout 0(不限时)、
|
||||
# --progress-interval 0(关闭进度)都是合法显式值,
|
||||
# 用真值判定会把 0 吞掉。相对路径原样透传即可:
|
||||
# daemonize 不 chdir,子进程 cwd 与 daemon 一致,
|
||||
# 且子进程对 CLI 值同样原样使用(不经 _resolve_path)。
|
||||
# 有意不传的:--config(已传解析后的 config_path,
|
||||
# 再传一次是重复);daemon 专属的 --interval、
|
||||
# --foreground(recover/run-due 不接受,传了会 argparse
|
||||
# 报错致整轮空转);--ignore-host-budget(见下)。
|
||||
# --ignore-host-budget 不传:它的 help 本就定给云端
|
||||
# worker 路径,standalone 预算照常;且 recover 与
|
||||
# run-due 两条子命令路径都不查 budget_exceeded
|
||||
#(run-due 调 run_task_turn,不走带预算门的分支),
|
||||
# 传了当下也无行为差异,只会给将来某天子命令加预算门
|
||||
# 时埋一个“daemon 悄悄替自动化关预算”的继承口——
|
||||
# 预算关口应由真正跑 turn 的那次调用显式决定。
|
||||
child_base = [sys.executable, os.path.join(HERE, "host.py"),
|
||||
"--config", config_path]
|
||||
if explicit_state is not None:
|
||||
child_base += ["--state", explicit_state]
|
||||
if explicit_codex_home is not None:
|
||||
child_base += ["--codex-home", explicit_codex_home]
|
||||
if explicit_codex_bin is not None:
|
||||
child_base += ["--codex-bin", explicit_codex_bin]
|
||||
if explicit_model is not None:
|
||||
child_base += ["--model", explicit_model]
|
||||
if explicit_model_provider is not None:
|
||||
child_base += ["--model-provider", explicit_model_provider]
|
||||
if explicit_effort is not None:
|
||||
child_base += ["--effort", explicit_effort]
|
||||
if explicit_sandbox is not None:
|
||||
child_base += ["--sandbox", explicit_sandbox]
|
||||
if explicit_approval_policy is not None:
|
||||
child_base += ["--approval-policy", explicit_approval_policy]
|
||||
if explicit_approval is not None:
|
||||
child_base += ["--approval", explicit_approval]
|
||||
if explicit_turn_timeout is not None:
|
||||
child_base += ["--turn-timeout", str(explicit_turn_timeout)]
|
||||
if explicit_progress_interval is not None:
|
||||
child_base += ["--progress-interval",
|
||||
str(explicit_progress_interval)]
|
||||
for subcmd in (["recover", "--older-than", "3600"], ["run-due"]):
|
||||
try:
|
||||
subprocess.run(child_base + subcmd, timeout=3600)
|
||||
subprocess.run(child_base + subcmd,
|
||||
timeout=3600)
|
||||
except Exception as e:
|
||||
print(f"{ts} daemon subcommand {subcmd} 失败:{e}", flush=True)
|
||||
for _ in range(args.interval):
|
||||
|
||||
Reference in new issue
Block a user