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 {...@@ -11,6 +11,7 @@ import {
11 ProjectId,11 ProjectId,
12 ProviderSessionId,12 ProviderSessionId,
13 ProviderThreadId,13 ProviderThreadId,
14 ProviderTurnId,
14 ThreadId,15 ThreadId,
15 TurnId,16 TurnId,
16} from "@t3tools/contracts";17} from "@t3tools/contracts";
...@@ -40,6 +41,7 @@ import { checkpointRefForThreadTurn } from "../../checkpointing/Utils.ts";...@@ -40,6 +41,7 @@ import { checkpointRefForThreadTurn } from "../../checkpointing/Utils.ts";
40const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value);41const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value);
41const asSessionId = (value: string): ProviderSessionId => ProviderSessionId.makeUnsafe(value);42const asSessionId = (value: string): ProviderSessionId => ProviderSessionId.makeUnsafe(value);
42const asProviderThreadId = (value: string): ProviderThreadId => ProviderThreadId.makeUnsafe(value);43const asProviderThreadId = (value: string): ProviderThreadId => ProviderThreadId.makeUnsafe(value);
44const asProviderTurnId = (value: string): ProviderTurnId => ProviderTurnId.makeUnsafe(value);
43const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value);45const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value);
4446
45function createProviderServiceHarness(cwd: string, hasSession = true, sessionCwd = cwd) {47function createProviderServiceHarness(cwd: string, hasSession = true, sessionCwd = cwd) {
...@@ -334,7 +336,7 @@ describe("CheckpointReactor", () => {...@@ -334,7 +336,7 @@ describe("CheckpointReactor", () => {
334 sessionId: asSessionId("sess-1"),336 sessionId: asSessionId("sess-1"),
335 createdAt: new Date().toISOString(),337 createdAt: new Date().toISOString(),
336 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),338 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
337 turnId: asTurnId("turn-1"),339 turnId: asProviderTurnId("turn-1"),
338 });340 });
339 await waitForGitRefExists(341 await waitForGitRefExists(
340 harness.cwd,342 harness.cwd,
...@@ -349,7 +351,7 @@ describe("CheckpointReactor", () => {...@@ -349,7 +351,7 @@ describe("CheckpointReactor", () => {
349 sessionId: asSessionId("sess-1"),351 sessionId: asSessionId("sess-1"),
350 createdAt: new Date().toISOString(),352 createdAt: new Date().toISOString(),
351 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),353 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
352 turnId: asTurnId("turn-1"),354 turnId: asProviderTurnId("turn-1"),
353 status: "completed",355 status: "completed",
354 });356 });
355357
...@@ -413,7 +415,7 @@ describe("CheckpointReactor", () => {...@@ -413,7 +415,7 @@ describe("CheckpointReactor", () => {
413 sessionId: asSessionId("sess-1"),415 sessionId: asSessionId("sess-1"),
414 createdAt: new Date().toISOString(),416 createdAt: new Date().toISOString(),
415 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),417 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
416 turnId: asTurnId("turn-main"),418 turnId: asProviderTurnId("turn-main"),
417 });419 });
418 await waitForGitRefExists(420 await waitForGitRefExists(
419 harness.cwd,421 harness.cwd,
...@@ -429,7 +431,7 @@ describe("CheckpointReactor", () => {...@@ -429,7 +431,7 @@ describe("CheckpointReactor", () => {
429 sessionId: asSessionId("sess-1"),431 sessionId: asSessionId("sess-1"),
430 createdAt: new Date().toISOString(),432 createdAt: new Date().toISOString(),
431 threadId: ProviderThreadId.makeUnsafe("provider-thread-aux"),433 threadId: ProviderThreadId.makeUnsafe("provider-thread-aux"),
432 turnId: asTurnId("turn-aux"),434 turnId: asProviderTurnId("turn-aux"),
433 status: "completed",435 status: "completed",
434 });436 });
435437
...@@ -445,7 +447,7 @@ describe("CheckpointReactor", () => {...@@ -445,7 +447,7 @@ describe("CheckpointReactor", () => {
445 sessionId: asSessionId("sess-1"),447 sessionId: asSessionId("sess-1"),
446 createdAt: new Date().toISOString(),448 createdAt: new Date().toISOString(),
447 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),449 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
448 turnId: asTurnId("turn-main"),450 turnId: asProviderTurnId("turn-main"),
449 status: "completed",451 status: "completed",
450 });452 });
451453
...@@ -488,7 +490,7 @@ describe("CheckpointReactor", () => {...@@ -488,7 +490,7 @@ describe("CheckpointReactor", () => {
488 sessionId: asSessionId("sess-1"),490 sessionId: asSessionId("sess-1"),
489 createdAt: new Date().toISOString(),491 createdAt: new Date().toISOString(),
490 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),492 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
491 turnId: asTurnId("turn-missing-baseline"),493 turnId: asProviderTurnId("turn-missing-baseline"),
492 status: "completed",494 status: "completed",
493 });495 });
494496
...@@ -580,7 +582,7 @@ describe("CheckpointReactor", () => {...@@ -580,7 +582,7 @@ describe("CheckpointReactor", () => {
580 sessionId: asSessionId("sess-missing"),582 sessionId: asSessionId("sess-missing"),
581 createdAt: new Date().toISOString(),583 createdAt: new Date().toISOString(),
582 threadId: ProviderThreadId.makeUnsafe("provider-thread-missing"),584 threadId: ProviderThreadId.makeUnsafe("provider-thread-missing"),
583 turnId: asTurnId("turn-missing-cwd"),585 turnId: asProviderTurnId("turn-missing-cwd"),
584 status: "completed",586 status: "completed",
585 });587 });
586588
...@@ -629,7 +631,7 @@ describe("CheckpointReactor", () => {...@@ -629,7 +631,7 @@ describe("CheckpointReactor", () => {
629 sessionId: asSessionId("sess-1"),631 sessionId: asSessionId("sess-1"),
630 createdAt: new Date().toISOString(),632 createdAt: new Date().toISOString(),
631 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),633 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
632 turnId: asTurnId("turn-3"),634 turnId: asProviderTurnId("turn-3"),
633 turnCount: 3,635 turnCount: 3,
634 status: "completed",636 status: "completed",
635 });637 });
...@@ -682,7 +684,7 @@ describe("CheckpointReactor", () => {...@@ -682,7 +684,7 @@ describe("CheckpointReactor", () => {
682 sessionId: asSessionId("sess-1"),684 sessionId: asSessionId("sess-1"),
683 createdAt: new Date().toISOString(),685 createdAt: new Date().toISOString(),
684 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),686 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
685 turnId: asTurnId("turn-runtime-failure"),687 turnId: asProviderTurnId("turn-runtime-failure"),
686 turnCount: 1,688 turnCount: 1,
687 status: "completed",689 status: "completed",
688 });690 });
...@@ -694,7 +696,7 @@ describe("CheckpointReactor", () => {...@@ -694,7 +696,7 @@ describe("CheckpointReactor", () => {
694 sessionId: asSessionId("sess-1"),696 sessionId: asSessionId("sess-1"),
695 createdAt: new Date().toISOString(),697 createdAt: new Date().toISOString(),
696 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),698 threadId: ProviderThreadId.makeUnsafe("provider-thread-1"),
697 turnId: asTurnId("turn-after-runtime-failure"),699 turnId: asProviderTurnId("turn-after-runtime-failure"),
698 });700 });
699701
700 await waitForGitRefExists(702 await waitForGitRefExists(
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts+1-1
...@@ -346,7 +346,7 @@ const make = Effect.gen(function* () {...@@ -346,7 +346,7 @@ const make = Effect.gen(function* () {
346 const now = event.createdAt;346 const now = event.createdAt;
347 const sessionProviderThreadId = thread.session?.providerThreadId ?? null;347 const sessionProviderThreadId = thread.session?.providerThreadId ?? null;
348 const eventProviderThreadId = toProviderThreadId(event.threadId);348 const eventProviderThreadId = toProviderThreadId(event.threadId);
349 const eventTurnId = toTurnId(event.turnId);349 const eventTurnId = toTurnId("turnId" in event ? event.turnId : undefined);
350 const activeTurnId = thread.session?.activeTurnId ?? null;350 const activeTurnId = thread.session?.activeTurnId ?? null;
351351
352 const matchesThreadScope =352 const matchesThreadScope =