Conversation
feat(dashboard): continue a finished run as a conversation - Resume a terminal run in place, reusing its round ledger - Claim operator messages at round start so a stop never delays them - Order the transcript by time, not by round - Drop the round copy of a discarded reply - Add `--reasoning-effort` per run and per role - Offer a force stop only after SIGTERM is ignored
There was a problem hiding this comment.
Pull request overview
This PR extends the harness + dashboard lifecycle so a terminal run can be resumed “in place” (continuing on its existing round ledger), improves lifecycle idempotency across resume generations, and adds a unified --reasoning-effort surface (global + per-role) that is forwarded to supporting backends and reflected in Web metadata.
Changes:
- Add in-place resume (“continue”) with a resume generation counter (
resume_epoch) and generation-scoped lifecycle command IDs. - Claim queued operator instructions at round start and order the conversation transcript strictly by time.
- Add
reasoning_effortacross CLI/config/supervisor/adapters and expose richer agent availability + reasoning metadata via the model catalog.
Reviewed changes
Copilot reviewed 38 out of 39 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/webapi/test_resume_routes.py | Adds HTTP tests for /resume, idempotency behavior, snapshot fields, and extra-round validation. |
| tests/test_resume.py | Adds unit tests for ledger restore, resume epoch merging, supervisor resume modes, and CLI --resume guard. |
| tests/test_resume_manager_loop.py | Adds async tests validating manager-loop resume semantics (round numbering, prompt history, events, budget). |
| tests/test_reasoning_effort_chain.py | Verifies reasoning-effort propagation/validation across adapters, CLI resolution, config, and supervisor role configs. |
| tests/test_opencode_adapter.py | Updates OpenCode availability probing expectations and asserts tri-state availability. |
| tests/test_model_catalog.py | Updates CLI stubs to return --version output consistent with availability probing. |
| tests/test_manager_hardening.py | Ensures reopening a run withdraws published final responses the dashboard reads. |
| tests/test_guard_exclude_paths.py | Adds tests ensuring repeatable CLI flags override (not extend) project-config lists. |
| tests/test_deepseek_harness_adapter.py | Updates DeepSeek CLI probing expectations and asserts version/availability fields. |
| tests/test_codex_adapter.py | Updates Codex CLI stub to emit a version string so probing marks it usable. |
| tests/test_agent_registry.py | Adds tests for the new agent registry, probing tri-state availability, and effort discovery/validation. |
| src/lh_harness/webapi/snapshot.py | Sanitizes reasoning_effort in role configs surfaced to the browser. |
| src/lh_harness/webapi/server.py | Adds optional extra_rounds parsing, resume mode selection, and projects resume/lifecycle fields into snapshots. |
| src/lh_harness/utils/agent_cli.py | Allows probing a caller-provided binary path to keep Web responses self-consistent. |
| src/lh_harness/supervisor/service.py | Implements resume modes, generation-scoped lifecycle command IDs, unified worker launch transaction, and reasoning-effort forwarding. |
| src/lh_harness/supervisor/lifecycle.py | Introduces resume_epoch helpers/constants and treats creating as an active lifecycle state. |
| src/lh_harness/model_catalog.py | Refactors agent metadata to use agent_registry probes and exposes richer reasoning/availability payloads. |
| src/lh_harness/manager.py | Implements ledger replay on resume, claims operator messages at round start, updates budget semantics, and withdraws discarded replies. |
| src/lh_harness/dashboard/state.py | Adds approval support for optional extra_rounds with safe normalization and persistence. |
| src/lh_harness/dashboard/gate.py | Enables budget-related approvals to collect and forward an operator extra-round grant. |
| src/lh_harness/config.py | Adds project-config support for global + per-role reasoning_effort. |
| src/lh_harness/cli.py | Adds CLI flags for reasoning effort, adds supervised-only --resume, and fixes repeatable defaults semantics. |
| src/lh_harness/agent_registry.py | Adds a single declarative agent backend registry with probing, tri-state availability, and effort validation/discovery. |
| src/lh_harness/adapters/opencode.py | Normalizes/validates reasoning-effort input via shared validator and supports new reasoning_effort param. |
| src/lh_harness/adapters/deepseek_harness.py | Rejects reasoning effort explicitly for backends without an effort switch. |
| src/lh_harness/adapters/codex.py | Forwards reasoning effort as a Codex config override (no CLI flag available). |
| src/lh_harness/adapters/claude_code.py | Forwards reasoning effort via --effort and records it in episode metadata. |
| README.zh-CN.md | Documents v0.1.7 resume-as-conversation + reasoning-effort and transcript/stop behavior changes. |
| README.md | Documents v0.1.7 resume-as-conversation + reasoning-effort and transcript/stop behavior changes. |
| pyproject.toml | Bumps version to 0.1.7. |
| frontend/web/src/style.css | Adds styling for approval extra-round input and transcript expansion/clamping helpers. |
| frontend/web/src/api.ts | Extends Web API types and adds payload support for approvals extra rounds and resume mode/options. |
| frontend/core/test/runFeed.test.ts | Adds core projection tests for resume generation behavior, transcript ordering, approvals extra rounds, and abort command availability. |
| frontend/core/src/types.ts | Extends snapshot/approval shared types with resume epoch + stop fields + extra rounds. |
| frontend/core/src/statusView.ts | Adds “awaiting handoff” projection to avoid UI dead-air after approving while worker still reports waiting_approval. |
| frontend/core/src/runView.ts | Adds sortTranscript to order the conversation strictly by time while keeping untimed entries anchored. |
| frontend/core/src/runFeed.ts | Adds resume-epoch-aware snapshot preference/merging rules and preserves approval extra-round grants under stale frames. |
| frontend/core/src/commands.ts | Updates command gating to keep /abort available while stopping and adds /new --effort parsing/validation. |
Files not reviewed (1)
- frontend/web/src/style.css: Generated file
Suppressed comments (1)
src/lh_harness/manager.py:1182
- The budget extension can exceed
MAX_ROUNDS: whenround_index == MAX_ROUNDS,max(round_index + 1, min(round_index + extra, MAX_ROUNDS))evaluates toMAX_ROUNDS + 1. That breaks the global round ceiling and can also discard the just-written terminal reply even though the run cannot be extended safely. Consider ensuringctx.round_budgetnever exceedsMAX_ROUNDSand handling the edge case (already at the ceiling) by rejecting/overriding acontinuedecision instead of synthesizing an out-of-range budget.
extra = _extra_rounds(decision.get("extra_rounds")) or max(1, ctx.config.max_total_episodes or 1)
# Always grant at least one more round: clamping to MAX_ROUNDS must not
# produce a budget below the current round, which would end the run
# immediately after the operator asked to continue.
ctx.round_budget = max(round_index + 1, min(round_index + extra, MAX_ROUNDS))
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # After a resume ``max_total_episodes`` is the *additional* budget, so the | ||
| # effective ceiling continues from the restored rounds. | ||
| round_budget = round_index + max(1, config.max_total_episodes) |
|
@lerogo Following your note in #54 — here is a test report for the v0.1.7 reasoning-effort feature ( What works
Two observations1. An explicit role effort on a backend without a reasoning switch disappears silently. 2. A claude_code typo runs the whole task at default depth. Offer: dsh reasoning depthDeepSeek Harness does document a reasoning dial: the PS: Neither English nor Chinese is my first language, so I've been posting in both to make reading easier for the team — both halves are translations anyway. Tell me which you prefer for future messages, English-only or bilingual, and I'll stick to that. @lerogo 根据你在 #54 的留言,这是 v0.1.7 思考强度功能( 正常工作的部分
两个观察1. 在没有思考强度开关的后端上,显式指定的角色强度会无声消失。 2. claude_code 的强度拼写错误会让整个任务以默认深度运行。 提议:dsh 的思考深度DeepSeek Harness 其实有文档化的强度开关: 另注:英语和中文都不是我的母语,此前双语发帖只是为了方便团队阅读——反正两个版本都是翻译。今后的消息您希望只用英文还是继续双语?我会照此执行。 |
feat(dashboard): continue a finished run as a conversation
--reasoning-effortper run and per role