| ... | ... | @@ -448,6 +448,51 @@ describe("ProviderRuntimeIngestion", () => { |
| 448 | 448 | expect(thread.session?.lastError).toBeNull(); |
| 449 | 449 | }); |
| 450 | 450 | |
| 451 | it("clears active turn when provider session becomes ready", async () => { |
| 452 | const harness = await createHarness(); |
| 453 | const now = "2026-01-01T00:00:00.000Z"; |
| 454 | |
| 455 | harness.emit({ |
| 456 | type: "turn.started", |
| 457 | eventId: asEventId("evt-turn-started-session-ready"), |
| 458 | provider: ProviderDriverKind.make("codex"), |
| 459 | createdAt: now, |
| 460 | threadId: asThreadId("thread-1"), |
| 461 | turnId: asTurnId("turn-session-ready"), |
| 462 | }); |
| 463 | |
| 464 | await waitForThread( |
| 465 | harness.readModel, |
| 466 | (thread) => |
| 467 | thread.session?.status === "running" && |
| 468 | thread.session?.activeTurnId === "turn-session-ready", |
| 469 | 10_000, |
| 470 | ); |
| 471 | |
| 472 | harness.emit({ |
| 473 | type: "session.state.changed", |
| 474 | eventId: asEventId("evt-session-state-ready-with-active-turn"), |
| 475 | provider: ProviderDriverKind.make("codex"), |
| 476 | threadId: asThreadId("thread-1"), |
| 477 | createdAt: "2026-01-01T00:00:01.000Z", |
| 478 | payload: { |
| 479 | state: "ready", |
| 480 | }, |
| 481 | }); |
| 482 | |
| 483 | const thread = await waitForThread( |
| 484 | harness.readModel, |
| 485 | (entry) => |
| 486 | entry.session?.status === "ready" && |
| 487 | entry.session?.activeTurnId === null && |
| 488 | entry.session?.lastError === null, |
| 489 | 10_000, |
| 490 | ); |
| 491 | expect(thread.session?.status).toBe("ready"); |
| 492 | expect(thread.session?.activeTurnId).toBeNull(); |
| 493 | expect(thread.session?.lastError).toBeNull(); |
| 494 | }); |
| 495 | |
| 451 | 496 | it("does not clear active turn when session/thread started arrives mid-turn", async () => { |
| 452 | 497 | const harness = await createHarness(); |
| 453 | 498 | const now = "2026-01-01T00:00:00.000Z"; |
| ... | ... | @@ -466,6 +511,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 466 | 511 | (thread) => |
| 467 | 512 | thread.session?.status === "running" && |
| 468 | 513 | thread.session?.activeTurnId === "turn-midturn-lifecycle", |
| 514 | 10_000, |
| 469 | 515 | ); |
| 470 | 516 | |
| 471 | 517 | harness.emit({ |
| ... | ... | @@ -502,6 +548,7 @@ describe("ProviderRuntimeIngestion", () => { |
| 502 | 548 | await waitForThread( |
| 503 | 549 | harness.readModel, |
| 504 | 550 | (thread) => thread.session?.status === "ready" && thread.session?.activeTurnId === null, |
| 551 | 10_000, |
| 505 | 552 | ); |
| 506 | 553 | }); |
| 507 | 554 | |