1import {
2 latestProviderTurnForAttempt,
3 type MessageId,
4 type OrchestrationV2ConversationMessage,
5 type OrchestrationV2ThreadProjection,
6} from "@t3tools/contracts";
7
8export function isBufferedProviderNotification(
9 message: Pick<
10 OrchestrationV2ConversationMessage,
11 "createdBy" | "creationSource" | "notification" | "delegatedCompletion"
12 >,
13): boolean {
14 return (
15 message.createdBy === "agent" &&
16 message.creationSource === "provider" &&
17 message.notification !== undefined &&
18 message.delegatedCompletion === undefined
19 );
20}
21
22/** Acceptance and receipts cannot commit atomically; reuse message ids for at-least-once delivery. */
23export function isUndeliveredMailboxSteer(
24 projection: Pick<OrchestrationV2ThreadProjection, "messages" | "runs" | "providerTurns">,
25 messageId: MessageId,
26): boolean {
27 const message = projection.messages.find((candidate) => candidate.id === messageId);
28 if (message?.delegatedCompletion === undefined) return false;
29 const run = projection.runs.find((candidate) => candidate.id === message.runId);
30 return (
31 run !== undefined &&
32 run.userMessageId !== message.id &&
33 (["completed", "failed", "interrupted", "cancelled", "rolled_back"].includes(run.status) ||
34 latestProviderTurnForAttempt(projection.providerTurns, run.activeAttemptId)?.status ===
35 "completed")
36 );
37}