mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
fix(runner): refuse to reopen a session whose run failed its turn-end restart
open_session did not check the saved turn-end restart failure, so session.open or a same-run run.attach reopened the provider and later turns ran. Refuse there while the marker names the current run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f5d5d35d90
commit
7fe9345030
2 files changed
+31
-1
No files matched your search
@@ -1788,6 +1788,17 @@ impl AcpxCommandExecutor {
|
||||
"ACPX provider lifetime cleanup is not yet proven",
|
||||
));
|
||||
}
|
||||
// No path (session.open, a same-run run.attach) reopens a session whose
|
||||
// run failed closed at its turn-end provider restart.
|
||||
if self.session.is_none()
|
||||
&& self.state.as_ref().is_some_and(|state| {
|
||||
state.turn_end_restart_failed_run.as_deref() == Some(self.context.run_id.as_str())
|
||||
})
|
||||
{
|
||||
return Err(DurableRunnerError::invalid(
|
||||
"ACPX session failed closed after this run's turn-end provider restart failed",
|
||||
));
|
||||
}
|
||||
if self.session.is_none() {
|
||||
let recovering = self
|
||||
.state
|
||||
|
||||
+20
-1
@@ -441,11 +441,30 @@ fn a_runner_restart_in_the_same_run_keeps_the_failed_turn_end_restart_closed() {
|
||||
.to_string();
|
||||
assert_eq!(failed, "ACPX session is not open");
|
||||
assert_eq!(harness.fixture.process_starts().len(), starts);
|
||||
// Neither session.open nor a same-run attach reopens it.
|
||||
let reopened = harness
|
||||
.executor
|
||||
.execute(&command(91, "session.open", json!({})))
|
||||
.unwrap_err()
|
||||
.to_string();
|
||||
assert!(reopened.contains("failed closed"), "{reopened}");
|
||||
let same_run_attach = json!({"provider": harness.descriptor.clone()});
|
||||
let attach_error = harness
|
||||
.executor
|
||||
.execute(&command(92, "run.attach", same_run_attach))
|
||||
.unwrap_err()
|
||||
.to_string();
|
||||
assert!(attach_error.contains("failed closed"), "{attach_error}");
|
||||
assert_eq!(harness.fixture.process_starts().len(), starts);
|
||||
assert_eq!(
|
||||
harness.fixture.state()["turnEndRestartFailedRun"],
|
||||
harness.config.run_id
|
||||
);
|
||||
assert_eq!(live_providers(&harness), Vec::<Value>::new());
|
||||
assert_eq!(harness.fixture.state()["lifecycle"], "suspended");
|
||||
// The next run still resumes the conversation and clears the restriction.
|
||||
harness.executor.shutdown().unwrap();
|
||||
harness.sequence = 90;
|
||||
harness.sequence = 92;
|
||||
harness.config.run_id = "run-2".to_owned();
|
||||
harness.executor =
|
||||
NativeProviderCommandExecutor::with_runner_config(&harness.fixture.0, &harness.config);
|
||||
|
||||
Reference in new issue
Block a user