* Track every request a session can park on until its settlement ack lands, * so a surface that was not mounted when the request streamed by can still * read it back and render the prompt (#2072).
(
sessionId: string,
backend: AgentBackend,
event: SessionEvent,
)
| 2565 | * read it back and render the prompt (#2072). |
| 2566 | */ |
| 2567 | private observeInteractionEvent( |
| 2568 | sessionId: string, |
| 2569 | backend: AgentBackend, |
| 2570 | event: SessionEvent, |
| 2571 | ): void { |
| 2572 | if ( |
| 2573 | event.type !== 'sandbox_boundary_request' && |
| 2574 | event.type !== 'user_question_request' && |
| 2575 | event.type !== 'sandbox_boundary_decision_ack' && |
| 2576 | event.type !== 'user_question_answer_ack' |
| 2577 | ) { |
| 2578 | return; |
| 2579 | } |
| 2580 | const key = interactionOwnerKey(sessionId, event.requestId); |
| 2581 | if ( |
| 2582 | event.type === 'sandbox_boundary_decision_ack' || |
| 2583 | event.type === 'user_question_answer_ack' |
| 2584 | ) { |
| 2585 | this.interactionRequestOwners.delete(key); |
| 2586 | return; |
| 2587 | } |
| 2588 | const generation = [...this.backendGenerations.values()].find( |
| 2589 | (candidate) => |
| 2590 | candidate.sessionId === sessionId && |
| 2591 | candidate.backend === backend && |
| 2592 | candidate.phase !== 'terminated', |
| 2593 | ); |
| 2594 | if (!generation) { |
| 2595 | throw new RuntimeInteractionInvariantError( |
| 2596 | `Interaction request ${event.requestId} has no active backend owner`, |
| 2597 | ); |
| 2598 | } |
| 2599 | const existing = this.interactionRequestOwners.get(key); |
| 2600 | if ( |
| 2601 | existing && |
| 2602 | (existing.generation !== generation.generation || existing.turnId !== event.turnId) |
| 2603 | ) { |
| 2604 | throw new RuntimeInteractionInvariantError( |
| 2605 | `Interaction request ${event.requestId} has conflicting owners`, |
| 2606 | ); |
| 2607 | } |
| 2608 | this.interactionRequestOwners.set(key, { |
| 2609 | sessionId, |
| 2610 | turnId: event.turnId, |
| 2611 | generation: generation.generation, |
| 2612 | request: event, |
| 2613 | }); |
| 2614 | } |
| 2615 | |
| 2616 | private clearInteractionRequestOwners(sessionId: string, turnId: string): void { |
| 2617 | for (const [key, owner] of this.interactionRequestOwners) { |
no test coverage detected