fix: preserve report shape on interrupted research turns - #808
Conversation
Pass research turn settings through the hook boundary and apply product guidance to budget-exhaustion synthesis. Buffer and validate the reply before delivery, allow one format repair, and keep a structured fallback when synthesis fails.
gloryfromca
left a comment
There was a problem hiding this comment.
No blockers; this can merge as far as I am concerned.
Reviewed the complete github/main...HEAD diff and the surrounding hook, participant, turn-loop, report-shape, and persistence paths. I also checked the commit history, project rules and canonical terminology, backward compatibility for callers without a synthesis policy, architecture boundaries, and that the tests were extended rather than weakened. The policy is carried in the existing per-turn metadata boundary, the product-specific shaping remains outside the generic loop, buffered synthesis keeps streamed and persisted output identical, and the legacy path is unchanged when no policy is present.
Verification:
uv sync --extra devuv run pytest tests/test_agent_loop_max_iter_synthesis.py tests/test_agent_loop_dead_end_retry.py tests/test_agents_research_flow_report_shape.py -x(101 passed)uv run ruff check raven/agent/loop/__init__.py raven/agent/loop/_shared.py raven/agent/loop/turn_path.py agents/raven-research/plugins/research-flow/research_flow/flow.py agents/raven-research/plugins/research-flow/research_flow/gates/report_shape.py tests/test_agent_loop_dead_end_retry.py tests/test_agent_loop_max_iter_synthesis.py tests/test_agents_research_flow_report_shape.py(passed)git diff --check github/main...HEAD(passed)
The first pytest attempt used the default environment and stopped during global fixture setup because the raven_everos dev plugin was absent; after syncing the repository's declared dev extra, the same unmodified test command passed.
Keep the product synthesis helper on its declared string return path when the provider content is empty.
gloryfromca
left a comment
There was a problem hiding this comment.
No blockers; this can merge as far as I am concerned.
Reviewed the new commit and rechecked the complete github/main...HEAD diff. The only delta since the prior revision normalizes _strip_think()'s allowed None result to the empty-string sentinel, ensuring the existing structured fallback path runs for empty provider content. It does not alter successful synthesis or callers without a synthesis policy.
I rechecked the project rules and canonical terminology, changed callers and history, backward compatibility, test changes, and the generic-loop/product-policy architecture boundary. No tests were weakened.
Verification:
uv run pytest tests/test_agent_loop_max_iter_synthesis.py tests/test_agent_loop_dead_end_retry.py tests/test_agents_research_flow_report_shape.py -x(101 passed)- focused
uv run ruff check ...over all changed Python and test files (passed) git diff --check github/main...HEAD(passed)
## Summary Bump the package version from 0.2.2 to 0.2.3 for the next release. Only pyproject.toml and uv.lock change. Since v0.2.2, main merged 13 PRs: three features (#802 an experimental Curator that cultivates harness-of-harnesses workers, #805 one header per desk pane, #806 upgrade from the page with progress), four fixes (#792 and #799 name grok and copilot connection failures, #807 records the questions an unattended turn could not ask, #808 keeps the report shape on interrupted research turns) and six docs PRs. None carries a BREAKING CHANGE footer, so this is a patch bump, the way v0.2.1 and v0.2.2 were for their features. The tag and release notes follow once this lands. ## Type - [ ] Fix - [ ] Feature - [ ] Docs - [ ] CI / tooling - [ ] Refactor - [x] Other ## Verification - `uv lock` on a clean worktree cut from origin/main: Resolved 251 packages, Updated raven v0.2.2 -> v0.2.3 - `git diff --stat origin/main..HEAD`: pyproject.toml and uv.lock, 2 insertions, 2 deletions - `PYTHONPATH=. python scripts/check_commit_messages.py origin/main..HEAD`: exit 0 - `npx commitlint --from origin/main --to HEAD --config commitlint.config.cjs`: exit 0 - `uv version` in the worktree: raven 0.2.3 - No test run: the change is version metadata only. - [ ] Relevant tests pass locally - [x] Relevant lint / type checks pass locally - [ ] User-facing docs or screenshots are updated when needed ## Risk No code change. Rollback is reverting this commit before any v0.2.3 tag is pushed. - [ ] Security impact considered - [x] Backward compatibility considered - [x] Rollback path is clear for risky changes ## Related Issues N/A Co-authored-by: Claude (claude-fable-5-1) <noreply@anthropic.com>
Summary
Type
Verification
uv run pytest tests/test_agent_loop_max_iter_synthesis.py tests/test_agent_loop_dead_end_retry.py tests/test_agent_loop_run_emit.py tests/test_agents_research_flow_report_shape.py tests/test_agents_research_flow_finalize.py tests/test_agents_research_mode_tiers.py tests/test_agents_research_launcher.py -q -n 0 -m 'not slow' --tb=short(243 passed after syncing main).uv run ruff check raven/agent/loop/_shared.py raven/agent/loop/__init__.py raven/agent/loop/turn_path.py agents/raven-research/plugins/research-flow/research_flow/flow.py agents/raven-research/plugins/research-flow/research_flow/gates/report_shape.py tests/test_agent_loop_max_iter_synthesis.py tests/test_agent_loop_dead_end_retry.py tests/test_agents_research_flow_report_shape.py;uv run ruff format --check raven/agent/loop/_shared.py raven/agent/loop/__init__.py raven/agent/loop/turn_path.py agents/raven-research/plugins/research-flow/research_flow/flow.py agents/raven-research/plugins/research-flow/research_flow/gates/report_shape.py tests/test_agent_loop_max_iter_synthesis.py tests/test_agent_loop_dead_end_retry.py tests/test_agents_research_flow_report_shape.py;make lint-types;make check-source-language;make check-large-files(all passed).CONTEXT.mddefines the new runtime term.Risk
Related Issues
N/A