Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens streaming retry/fallback and workflow durability in orbcode’s core execution paths, aiming to prevent duplicated side effects (post-tool “effect barrier”) and to make workflow resume/journaling resilient to corruption and concurrent resumes.
Changes:
- Add an explicit “attempt discard disposition” so the retry layer can suppress cross-provider fallback once streamed tool execution has begun.
- Introduce cancellable streamed tool interruption/drain behavior and add regression tests covering pre-effect fallback vs. post-effect suppression.
- Serialize workflow journal appends and make workflow resume fail fast on corrupt journals or duplicate (already-active) run IDs.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tools/src/web_cache.rs | Small clippy-driven refactor using ? in Option flow for cache lookup. |
| public-api-allow-list.txt | Allow-list the newly exported AttemptDiscardDisposition API. |
| model-provider/src/model.rs | Introduce AttemptDiscardDisposition and change ProviderStreamSink::discard_attempt to return it. |
| model-provider/src/lib.rs | Re-export AttemptDiscardDisposition from the crate’s public surface. |
| core/src/tool_flow.rs | Extend streamed tool execution tracking to support cooperative cancellation during interruption. |
| core/src/session_manager/tests/support.rs | Add/adjust test HTTP servers to simulate “thinking” errors vs. post-tool errors and to record fallback contact. |
| core/src/session_manager/tests/provider_streaming_retry.rs | Add deterministic regression tests for fallback suppression after tool side effects and for tool draining behavior. |
| core/src/session_manager/session_workflows.rs | Add a serialized journal writer and an in-process active-run reservation to prevent concurrent/duplicate workflow resumes. |
| core/src/session_manager/session_turn_loop.rs | Await streamed tool interruption to ensure tools are drained before proceeding. |
| core/src/session_manager/session_stream.rs | Plumb discard disposition from streamed-tool presence and await tool interruption during attempt discard. |
| core/src/session_manager/session_response.rs | Make streamed tool interruption async and introduce a dedicated cancellation flag for streamed tool execution. |
| core/src/retry.rs | Enforce “no fallback after tool execution started” based on AttemptDiscardDisposition. |
| core/src/lib.rs | Add new CoreError variants for active workflow runs and corrupt workflow journals. |
| core/src/compaction.rs | Update sink implementation to the new discard-attempt return type. |
Suppressed comments (2)
core/src/session_manager/session_workflows.rs:278
Dropshould avoid panicking because it can lead to aborts during unwinding and makes shutdown paths fragile. Prefer recovering from a poisoned mutex (into_inner()) here instead of.expect(...).
active_workflow_runs()
.lock()
.expect("active workflow registry mutex")
.remove(&self.run_id);
core/src/session_manager/session_workflows.rs:269
Mutex::lock().expect(...)can panic on a poisoned mutex. Since this is just a read check for whether a workflow is already active, it’s safer to recover the guard (into_inner()) and continue rather than crashing the process.
active_workflow_runs()
.lock()
.expect("active workflow registry mutex")
.contains(run_id)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+254
to
+256
| let mut active = active_workflow_runs() | ||
| .lock() | ||
| .expect("active workflow registry mutex"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root cause
Provider retries treated any discardable partial stream as safe even after tool execution began. Workflow children opened
journal.jsonlindependently, while resume silently skipped malformed records. Together, these behaviors could duplicate externally visible tool effects or replay workflow steps after journal corruption.Verification
cargo fmt --all --checkcargo clippy --workspace --all-targets -- -D warningscargo check --workspacecargo test --workspacegit diff --checkNotes
Includes a behavior-preserving
?rewrite intools/src/web_cache.rsrequired by the strict Clippy gate.