fix(engine): dispose completed spawned child sessions

This commit is contained in:
gsxdsm
2026-06-23 09:12:28 -07:00
parent b599b6ab41
commit 466cf9ca8d
3 changed files with 22 additions and 3 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Dispose completed spawned child agent sessions so execution memory is released promptly after `fn_spawn_agent` children finish.

View File

@@ -709,7 +709,8 @@ describe("Agent Spawning - runSpawnedChild", () => {
// Should transition: running → active
expect(agentStore.updateAgentState).toHaveBeenCalledWith("agent-test", "running");
expect(agentStore.updateAgentState).toHaveBeenCalledWith("agent-test", "active");
// Should clean up
// Should clean up and release session resources
expect(mockSession.dispose).toHaveBeenCalledOnce();
expect(internals.childSessions.has("agent-test")).toBe(false);
expect(internals.totalSpawnedCount).toBe(0);
});
@@ -732,7 +733,8 @@ describe("Agent Spawning - runSpawnedChild", () => {
expect(agentStore.updateAgentState).toHaveBeenCalledWith("agent-test", "running");
expect(agentStore.updateAgentState).toHaveBeenCalledWith("agent-test", "error");
// Should still clean up
// Should still clean up and release session resources
expect(mockSession.dispose).toHaveBeenCalledOnce();
expect(internals.childSessions.has("agent-test")).toBe(false);
expect(internals.totalSpawnedCount).toBe(0);
});
@@ -751,6 +753,7 @@ describe("Agent Spawning - runSpawnedChild", () => {
// Should not throw even when state updates fail
await internals.runSpawnedChild("agent-test", mockSession, "Do the research");
expect(mockSession.dispose).toHaveBeenCalledOnce();
expect(internals.childSessions.has("agent-test")).toBe(false);
expect(internals.totalSpawnedCount).toBe(0);
});

View File

@@ -15607,7 +15607,18 @@ You have access to the file system to review changes.${verdictBlock}`;
const errorMessage = err instanceof Error ? err.message : String(err);
executorLog.warn(`Child agent ${agentId} failed: ${errorMessage}`);
} finally {
this.childSessions.delete(agentId);
/*
FNXC:AgentSpawning 2026-06-23-12:25:
Server memory must return to baseline after spawned child execution. A normally completed child session owns provider/runtime state until disposed; deleting it from childSessions first makes later parent cleanup unable to reach it.
*/
if (this.childSessions.get(agentId) === childSession) {
try {
childSession.dispose();
} catch (disposeErr) {
executorLog.warn(`Child agent ${agentId} session dispose failed: ${disposeErr instanceof Error ? disposeErr.message : String(disposeErr)}`);
}
this.childSessions.delete(agentId);
}
this.totalSpawnedCount = Math.max(0, this.totalSpawnedCount - 1);
}
}