mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-11 01:51:34 -10:00
fix(runtime): Box::pin start_turn state machine (Windows stack overflow)
The monolithic async start_turn holds two full Config clones plus several
records, the Op::SendMessage, and the inlined ensure_engine_loaded
sub-future (which builds a full EngineConfig), all across ~8 sequential
.awaits. On Windows the runtime thread stack is ~1 MiB (vs ~8 MiB on
Linux/macOS), so this frame overflowed it: start_turn_accepts_dynamic_
tools_and_environment_id aborted the whole test binary (0xc00000fd
STATUS_STACK_OVERFLOW), masking other Windows failures.
Box::pin(async move { ... }).await heap-allocates the whole state machine;
behavior- and Send-preserving, protects every caller. Verified no macOS
regression (start_turn test passes).
This commit is contained in:
1 parent
d2fb791bb8
commit
78afd8d3d4
1 file changed
+12
@@ -4955,6 +4955,16 @@ impl RuntimeThreadManager {
|
||||
}
|
||||
|
||||
pub async fn start_turn(&self, thread_id: &str, req: StartTurnRequest) -> Result<TurnRecord> {
|
||||
// Heap-allocate the turn-start state machine. Its future holds two full
|
||||
// Config clones plus ThreadRecord/EngineHandle/TurnRecord/TurnItemRecord
|
||||
// and the Op::SendMessage, and inlines the large ensure_engine_loaded
|
||||
// sub-future (which builds a full EngineConfig), all across ~8 sequential
|
||||
// .awaits. On Windows the runtime thread stack is ~1 MiB and this
|
||||
// monolithic frame overflowed it (test
|
||||
// start_turn_accepts_dynamic_tools_and_environment_id on windows-latest,
|
||||
// STATUS_STACK_OVERFLOW). Box::pin moves the whole frame to the heap so
|
||||
// no caller's stack carries it; behavior is unchanged.
|
||||
Box::pin(async move {
|
||||
let prompt = req.prompt.trim().to_string();
|
||||
if prompt.is_empty() {
|
||||
bail!("prompt is required");
|
||||
@@ -5228,6 +5238,8 @@ impl RuntimeThreadManager {
|
||||
.await
|
||||
.map_err(|_| anyhow!("Turn lifecycle task ended before acknowledgement"))?
|
||||
.map_err(anyhow::Error::msg)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn interrupt_turn(&self, thread_id: &str, turn_id: &str) -> Result<TurnRecord> {
|
||||
|
||||
Reference in new issue
Block a user