export type BatchStrategyKind = | 'identifier_batch' | 'query_share' | 'async_dataset_job'; export type BatchCompileItem = { // Preserved for diagnostics and job bookkeeping only. // Batch fanout is positional: compiled.items[index] maps to splitResult[index]. itemKey: string; payload: TSingle; }; export type BatchCompileResult< TBatch extends object, TSingle extends object, > = { batchOperation: string; batchPayload: TBatch; items: Array>; }; export type BatchExecutionDataEnvelope = { data: TBatchResult; }; export type BatchExecutionResultPayload = | TBatchResult | BatchExecutionDataEnvelope; export type BatchSplitItemResult = { // Preserved as metadata only. The runtime does not use itemKey to match rows. itemKey: string; result: TResult; rawResult?: TRawResult; }; export type BatchOperationStrategy< TSingle extends Record = Record, TBatch extends Record = Record, TBatchResult extends object = Record, TResult = unknown, TRawResult = unknown, > = { sourceOperation: string; batchOperation: string; kind: BatchStrategyKind; maxBatchSize: number; /** * Payload field names that can change the batch bucket. Static map planning * may treat a tool call as one bucket only when these fields are absent from * the static params/source text; otherwise it must assume worst-case bucket * fanout because the field may vary per row. */ bucketKeyPayloadFields?: string[]; canBatchWith(left: TSingle, right: TSingle): boolean; toBucketKey(payload: TSingle): string; toItemKey(payload: TSingle): string; compile(payloads: TSingle[]): BatchCompileResult; splitResult( fullResult: TBatchResult, compiled: BatchCompileResult, // Implementations must return results in the same order as compiled.items. ): BatchSplitItemResult[]; }; export type AnyBatchOperationStrategy = { sourceOperation: string; batchOperation: string; kind: BatchStrategyKind; maxBatchSize: number; bucketKeyPayloadFields?: string[]; canBatchWith( left: Record, right: Record, ): boolean; toBucketKey(payload: Record): string; toItemKey(payload: Record): string; compile(payloads: Record[]): { batchOperation: string; batchPayload: Record; items: Array<{ itemKey: string; payload: Record; }>; }; splitResult( fullResult: unknown, compiled: { batchOperation: string; batchPayload: Record; items: Array<{ itemKey: string; payload: Record }>; }, ): BatchSplitItemResult[]; }; export type BatchStrategyMap = Record; type StrictBatchOperationStrategy = BatchOperationStrategy< Record, Record, object, unknown, unknown >; export function defineBatchStrategyMap< TStrategies extends Record, >(strategies: TStrategies): BatchStrategyMap { return strategies as BatchStrategyMap; }