import { cloneToolExecuteResultWithExecution, isToolExecuteResult, type ToolExecuteResult, type ToolResultExecutionMetadata, } from './tool-result'; type OptionalKey = string | null | undefined; type BaseToolExecutionOutcome = { cacheKey?: OptionalKey; }; export type ToolExecutionOutcome = | (BaseToolExecutionOutcome & { kind: 'live'; receiptKey?: OptionalKey; }) | (BaseToolExecutionOutcome & { kind: 'checkpoint'; }) | (BaseToolExecutionOutcome & { kind: 'cache'; receiptKey: string; attachedToReceiptKey?: OptionalKey; }) | (BaseToolExecutionOutcome & { kind: 'in_flight'; receiptKey: string; attachedToReceiptKey?: OptionalKey; }); export type DurableReceiptRecoverySource = 'cache' | 'in_flight' | 'owner'; function trimmed(value: OptionalKey): string | null { const normalized = value?.trim(); return normalized ? normalized : null; } function optionalCacheKey(value: OptionalKey): Pick< ToolResultExecutionMetadata, 'cacheKey' > { const cacheKey = trimmed(value); return cacheKey ? { cacheKey } : {}; } function followerAttachment(input: { receiptKey: string; attachedToReceiptKey?: OptionalKey; }): Pick { return { attachedToReceiptKey: trimmed(input.attachedToReceiptKey) ?? input.receiptKey, }; } export function toolExecutionMetadataForOutcome( outcome: ToolExecutionOutcome, ): ToolResultExecutionMetadata { switch (outcome.kind) { case 'live': { const receiptKey = trimmed(outcome.receiptKey); return { idempotent: true, cached: false, source: 'live', ...optionalCacheKey(outcome.cacheKey), ...(receiptKey ? { receiptRole: 'owner' as const, receiptKey } : {}), }; } case 'checkpoint': return { idempotent: true, cached: true, source: 'checkpoint', ...optionalCacheKey(outcome.cacheKey), }; case 'cache': { const receiptKey = trimmed(outcome.receiptKey); if (!receiptKey) { throw new Error('Cached durable tool results require a receipt key.'); } return { idempotent: true, cached: true, source: 'cache', ...optionalCacheKey(outcome.cacheKey), receiptRole: 'follower', receiptKey, ...followerAttachment({ receiptKey, attachedToReceiptKey: outcome.attachedToReceiptKey, }), }; } case 'in_flight': { const receiptKey = trimmed(outcome.receiptKey); if (!receiptKey) { throw new Error('In-flight durable tool results require a receipt key.'); } return { idempotent: true, cached: false, source: 'in_flight', ...optionalCacheKey(outcome.cacheKey), receiptRole: 'follower', receiptKey, ...followerAttachment({ receiptKey, attachedToReceiptKey: outcome.attachedToReceiptKey, }), }; } default: { const exhaustive: never = outcome; return exhaustive; } } } export function toolExecutionOutcomeForDurableReceipt(input: { source: DurableReceiptRecoverySource; receiptKey: string; cacheKey?: OptionalKey; }): ToolExecutionOutcome { return input.source === 'owner' ? { kind: 'live', receiptKey: input.receiptKey, cacheKey: input.cacheKey, } : { kind: input.source, receiptKey: input.receiptKey, attachedToReceiptKey: input.receiptKey, cacheKey: input.cacheKey, }; } export function cloneToolExecuteResultWithOutcome( value: ToolExecuteResult, outcome: ToolExecutionOutcome, ): ToolExecuteResult { return cloneToolExecuteResultWithExecution( value, toolExecutionMetadataForOutcome(outcome), ); } export function markToolExecuteResultExecutionOutcome( value: unknown, outcome: ToolExecutionOutcome, ): unknown { if (!isToolExecuteResult(value)) { return value; } return cloneToolExecuteResultWithOutcome(value, outcome); }