authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-08-06 21:43:13-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-06 18:43:13-07:00
log7aad7911f66c2fecba1cfd6601ea783a3fe2bf31
tree3f8b448deb924ebaa3c4dcbe3fc20adfd6c33a7e
parent6da92244cc2a7438703be95a0fcfaca0b73502a7
signature Signed by PGP key B5690EEEBB952194

fix(server): let stopped threads settle immediately (#5553)


2 files changed, 9 insertions(+), 1 deletions(-)

apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts+7
...@@ -1430,6 +1430,13 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => {...@@ -1430,6 +1430,13 @@ it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => {
1430 assert.deepEqual(settledRows, [1430 assert.deepEqual(settledRows, [
1431 { state: "completed", completedAt: "2026-01-01T00:01:00.000Z" },1431 { state: "completed", completedAt: "2026-01-01T00:01:00.000Z" },
1432 ]);1432 ]);
1433
1434 const threadRows = yield* sql<{ readonly latestTurnId: string | null }>`
1435 SELECT latest_turn_id AS "latestTurnId"
1436 FROM projection_threads
1437 WHERE thread_id = ${threadId}
1438 `;
1439 assert.deepEqual(threadRows, [{ latestTurnId: turnId }]);
1433 }),1440 }),
1434 );1441 );
14351442
apps/server/src/orchestration/Layers/ProjectionPipeline.ts+2-1
...@@ -850,7 +850,8 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti...@@ -850,7 +850,8 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
850 }850 }
851 yield* projectionThreadRepository.upsert({851 yield* projectionThreadRepository.upsert({
852 ...existingRow.value,852 ...existingRow.value,
853 latestTurnId: event.payload.session.activeTurnId,853 // activeTurnId describes current work; a terminal session must not erase history.
854 latestTurnId: event.payload.session.activeTurnId ?? existingRow.value.latestTurnId,
854 updatedAt: event.occurredAt,855 updatedAt: event.occurredAt,
855 });856 });
856 yield* refreshThreadShellSummary(event.payload.threadId);857 yield* refreshThreadShellSummary(event.payload.threadId);