fix(eval): case 超时后取消底层 run 并为收尾设置有界等待 - #117
Conversation
- runCase 超时/用户取消时对对应 sessionId+runId 幂等取消(复用 RunManager.cancelRun) - 终态持久化与 runtime 收尾从无限轮询改为有界等待(默认 10s,可经 timing.teardownMs 覆盖) - runtime 收尾超限时记录 RUNTIME_TEARDOWN_TIMEOUT 基础设施错误、隔离该 runtime 并将实验置为 failed,不把下一个 case 跑在仍活跃的上下文上 - 超时/abort 竞态只结算一个终态,及时清理 timer 与 abort listener;被取消 case 的 partial 答案与 tool 记录保留入库 - 补充受控 stalled runtime 集成测试:无首输出、partial 后停滞、取消不响应、完成与超时竞态、用户 abort Closes helsome#115
helsome
left a comment
There was a problem hiding this comment.
方向和现有测试报告认可,这是内部生命周期增量,不需要真实模型/API key。当前只剩一个核心收尾边界未被覆盖:runCase 在调用有界 waitForIdle() 之前,无上限 await cancelRun()。主干 RunManager.cancelRun 本身会 await runtime.cancel;若取消 promise 一直 pending,就永远到不了新增的 teardown deadline。
请把“发出取消 + 等待 idle”放在同一个有界收尾窗口内(并处理迟到 rejection),补一个 cancelRun 返回永不 resolve 的 Promise 的用例:实验在短测试预算内结束、partial 产物保存、不删除仍被占用的 session、不启动下一 case。现有 cancelResponds=false fake 会立即 resolve,只模拟“返回了但仍 running”,因此漏掉这条路径。
同时在该测试中断言传给 cancelRun 的准确 sessionId/runId。修复后复跑现有 focused suites + typecheck 即可;不要扩大到新框架或完整真实 E2E。这里是可由代码和受控测试验证的缺陷,与 Nightly 缺 Key 无关。
- runCase 中发出 cancelRun 与等待 idle 合并进同一个有界窗口(settleTeardown): runtime.cancel 永不返回时总耗时仍受 teardownMs 上限约束,随后走既有隔离路径 - cancelRun 的迟到 rejection 在创建处吞掉,不会以 unhandled rejection 逃逸 - 新增 cancelRun 永不 resolve 的集成用例:实验在短预算内结束、partial 产物落库、 不删除仍被占用的 session、不启动下一 case,并断言传入 cancelRun 的准确 sessionId/runId 反馈来自 helsome#117 review
|
感谢 review,已修复。三点对应如下:
验证: |
head d3ee5ba 已把 cancelRun round-trip 纳入同一 teardown 有界窗口,并新增永不 resolve 的取消回归;原 blocker 已解除。
helsome
left a comment
There was a problem hiding this comment.
原收尾 blocker 已解除:当前实现把 cancellation promise 与 isRunning idle wait 放进同一个 teardownMs 窗口;cancelRun 永不 resolve 时也会在窗口结束后隔离 runtime,不删占用中的 session、不启动下一 case,并保留 partial 产物。新增测试还断言了准确的 sessionId/runId。作者补充的当前 head 验证为 bun test src/evaluation src/kernel 222 pass / 0 fail(Bun 1.3.14 / Windows),tsc --noEmit 通过;CI 为首次贡献者 action_required,不视为代码失败。本 PR 是内部生命周期修复,不需要真实模型/API key。
Reconcile the review follow-up with the CLI/effective-config work that landed on main (helsome#114/helsome#116, helsome#115/helsome#117). Conflict resolutions: - core/evaluation.ts: keep both `execution` (helsome#113 validity) and `effectiveConfig` (helsome#114 readback). - experiment-service.ts: keep the helsome#113 evaluation gating, the helsome#116 effective-config readback, and the helsome#117 bounded teardown; the helsome#114 config-apply failure path now stamps `execution: 'not-started'` and returns `runtimeUnusable`, so a config failure stays infra-invalid instead of being measured as a zero score. - experiment-service.test.ts: keep both the relay-header test and the helsome#115 teardown suite; update the helsome#114 CONFIG_APPLY_FAILED expectation to the helsome#113 semantics (validity `invalid`, passRate null). - scripts/eval/run.ts: keep the live preflight (helsome#113) and the effective-config summary (helsome#114); a single normalizeModelSelection import, with thinkingLevel from the CLI. Verification: - bun test --isolate -> 1539 pass / 8 skip / 0 fail - bun run typecheck -> all packages exit 0 UI impact: no layout or interaction changes.
改了什么
packages/shared/src/evaluation/experiment-service.ts的runCase收尾路径:Promise.race判定为timeout或abort后,对准确的sessionId + runId调用内核已有的RunManager.cancelRun(幂等:run 已结算或 id 不匹配时为 no-op)。ExperimentKernel.runs新增可选cancelRun,现有 fake kernel 不受影响。while (kernel.runs.isRunning?.())无截止时间,runtime 不退出时 eval 会无限挂起(无法开始下一 case,也无法结束 nightly)。现改为默认 10s 的有界等待(RUNTIME_TEARDOWN_MS,可经ExperimentServiceOptions.timing.teardownMs覆盖用于测试/运维)。deleteSession(session 文件仍被活跃 run 持有),run 记录补RUNTIME_TEARDOWN_TIMEOUT基础设施错误与runtime_error模式,实验置为failed并停止——不把下一个 case 跑在仍活跃的上下文上;已产生的产物保持可读。timeout/abort竞态只结算一次;race 结束后立即清除等待 timer 与 abort listener。用户 abort 的 case 不再从统计里悄悄消失:partial 答案/tool 记录以cancelledrun 落库。为什么改
Issue #115 指出的挂起路径:case timeout 不等于底层 Agent run 被停止;runtime 无终态事件时,超时分支既不取消 run,又进入无上界的
isRunning轮询。对应 Issue
Closes #115(仅拆出超时收尾缺陷,不替代 #15 父任务)
做了哪些验证
bun test src/evaluation src/kernel:221 pass / 0 fail(14 files,Bun 1.3.14 / Windows 10.0.26200)bun test src/storage:10 pass / 0 fail;shared 其余 20 个测试目录合跑 exit 0(无回归)tsc --noEmit(packages/shared):通过failed、不启动下一 case、产物可读、run 带RUNTIME_TEARDOWN_TIMEOUTcancelled落库、剩余 case 跳过已知未完成项 / 后续
timing覆盖仅用于测试与特殊运维场景,默认值与 §79 guardrails 一致。