authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-27 12:50:59-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-02-27 14:10:34-08:00
logb073fea5fb51b793373aae48647e39e1a2bc1890
tree50bd42c3b85f443310cd50240ec7a72b607fa331
parent834236931e17e4215000d2b3ce8defce295499ac

Handle provider turn IDs correctly in runtime ingestion

- Use `ProviderTurnId` in `CheckpointReactor` tests instead of `TurnId` - Guard `event.turnId` access in provider runtime ingestion when the field is absent

2 files changed, 13 insertions(+), 11 deletions(-)

apps/server/src/orchestration/Layers/CheckpointReactor.test.ts+12-10
......@@ -11,6 +11,7 @@ import {
1111 ProjectId,
1212 ProviderSessionId,
1313 ProviderThreadId,
14 ProviderTurnId,
1415 ThreadId,
1516 TurnId,
1617} from "@t3tools/contracts";
......@@ -40,6 +41,7 @@ import { checkpointRefForThreadTurn } from "../../checkpointing/Utils.ts";
4041const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value);
4142const asSessionId = (value: string): ProviderSessionId => ProviderSessionId.makeUnsafe(value);
4243const asProviderThreadId = (value: string): ProviderThreadId => ProviderThreadId.makeUnsafe(value);
44const asProviderTurnId = (value: string): ProviderTurnId => ProviderTurnId.makeUnsafe(value);
4345const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value);
4446
4547function createProviderServiceHarness(cwd: string, hasSession = true, sessionCwd = cwd) {
......@@ -334,7 +336,7 @@ describe("CheckpointReactor", () => {
334336 sessionId: asSessionId("sess-1"),
335337 createdAt: new Date().toISOString(),
336338 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
337 turnId: asTurnId("turn-1"),
339 turnId: asProviderTurnId("turn-1"),
338340 });
339341 await waitForGitRefExists(
340342 harness.cwd,
......@@ -349,7 +351,7 @@ describe("CheckpointReactor", () => {
349351 sessionId: asSessionId("sess-1"),
350352 createdAt: new Date().toISOString(),
351353 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
352 turnId: asTurnId("turn-1"),
354 turnId: asProviderTurnId("turn-1"),
353355 status: "completed",
354356 });
355357
......@@ -413,7 +415,7 @@ describe("CheckpointReactor", () => {
413415 sessionId: asSessionId("sess-1"),
414416 createdAt: new Date().toISOString(),
415417 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
416 turnId: asTurnId("turn-main"),
418 turnId: asProviderTurnId("turn-main"),
417419 });
418420 await waitForGitRefExists(
419421 harness.cwd,
......@@ -429,7 +431,7 @@ describe("CheckpointReactor", () => {
429431 sessionId: asSessionId("sess-1"),
430432 createdAt: new Date().toISOString(),
431433 threadId: ProviderThreadId.makeUnsafe("provider-thread-aux"),
432 turnId: asTurnId("turn-aux"),
434 turnId: asProviderTurnId("turn-aux"),
433435 status: "completed",
434436 });
435437
......@@ -445,7 +447,7 @@ describe("CheckpointReactor", () => {
445447 sessionId: asSessionId("sess-1"),
446448 createdAt: new Date().toISOString(),
447449 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
448 turnId: asTurnId("turn-main"),
450 turnId: asProviderTurnId("turn-main"),
449451 status: "completed",
450452 });
451453
......@@ -488,7 +490,7 @@ describe("CheckpointReactor", () => {
488490 sessionId: asSessionId("sess-1"),
489491 createdAt: new Date().toISOString(),
490492 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
491 turnId: asTurnId("turn-missing-baseline"),
493 turnId: asProviderTurnId("turn-missing-baseline"),
492494 status: "completed",
493495 });
494496
......@@ -580,7 +582,7 @@ describe("CheckpointReactor", () => {
580582 sessionId: asSessionId("sess-missing"),
581583 createdAt: new Date().toISOString(),
582584 threadId: ProviderThreadId.makeUnsafe("provider-thread-missing"),
583 turnId: asTurnId("turn-missing-cwd"),
585 turnId: asProviderTurnId("turn-missing-cwd"),
584586 status: "completed",
585587 });
586588
......@@ -629,7 +631,7 @@ describe("CheckpointReactor", () => {
629631 sessionId: asSessionId("sess-1"),
630632 createdAt: new Date().toISOString(),
631633 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
632 turnId: asTurnId("turn-3"),
634 turnId: asProviderTurnId("turn-3"),
633635 turnCount: 3,
634636 status: "completed",
635637 });
......@@ -682,7 +684,7 @@ describe("CheckpointReactor", () => {
682684 sessionId: asSessionId("sess-1"),
683685 createdAt: new Date().toISOString(),
684686 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
685 turnId: asTurnId("turn-runtime-failure"),
687 turnId: asProviderTurnId("turn-runtime-failure"),
686688 turnCount: 1,
687689 status: "completed",
688690 });
......@@ -694,7 +696,7 @@ describe("CheckpointReactor", () => {
694696 sessionId: asSessionId("sess-1"),
695697 createdAt: new Date().toISOString(),
696698 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
697 turnId: asTurnId("turn-after-runtime-failure"),
699 turnId: asProviderTurnId("turn-after-runtime-failure"),
698700 });
699701
700702 await waitForGitRefExists(
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts+1-1
......@@ -346,7 +346,7 @@ const make = Effect.gen(function* () {
346346 const now = event.createdAt;
347347 const sessionProviderThreadId = thread.session?.providerThreadId ?? null;
348348 const eventProviderThreadId = toProviderThreadId(event.threadId);
349 const eventTurnId = toTurnId(event.turnId);
349 const eventTurnId = toTurnId("turnId" in event ? event.turnId : undefined);
350350 const activeTurnId = thread.session?.activeTurnId ?? null;
351351
352352 const matchesThreadScope =