UNPKG

@tanstack/ai

Version:

Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.

80 lines (79 loc) 4.11 kB
import { readUnopenedInterruptBinding } from "./interrupt-resume.js"; import { INTERRUPT_PAYLOAD_METADATA_KEY } from "./interrupt-definition.js"; //#region src/generic-interrupt-continuation.ts /** * `ResumeEntry.metadata` key for a first-party generic request. * * AG-UI `resume` only carries the answer (`interruptId`, `status`, `payload`). * The original request rides here so an ephemeral server can rebuild it. */ var INTERRUPT_CONTINUATION_METADATA_KEY = "tanstack:interruptContinuation"; var INTERRUPT_CONTINUATION_VERSION = 1; function isRecord(value) { return value !== null && typeof value === "object" && !Array.isArray(value); } function invalid(message) { return { status: "invalid", message }; } /** * Read one generic request from `resume[].metadata`. * * Missing key means this resume item is not a first-party generic continuation. * A present key that fails the shape is a protocol error. */ function readGenericInterruptContinuation(metadata) { if (metadata === void 0) return { status: "absent" }; if (!isRecord(metadata)) return invalid("Generic interrupt resume metadata must be an object."); if (!Object.prototype.hasOwnProperty.call(metadata, "tanstack:interruptContinuation")) return { status: "absent" }; const raw = metadata[INTERRUPT_CONTINUATION_METADATA_KEY]; if (!isRecord(raw)) return invalid("Generic interrupt continuation is invalid."); if (raw.v !== 1 || typeof raw.definitionId !== "string" || typeof raw.key !== "string" || typeof raw.reason !== "string" || typeof raw.message !== "string" || typeof raw.batchIndex !== "number" || !Number.isInteger(raw.batchIndex) || raw.batchIndex < 0 || raw.responseSchemaHash !== void 0 && typeof raw.responseSchemaHash !== "string" || raw.expiresAt !== void 0 && typeof raw.expiresAt !== "string" || raw.payloadSchemaHash !== void 0 && typeof raw.payloadSchemaHash !== "string") return invalid("Generic interrupt continuation contains invalid fields."); return { status: "ok", value: { v: 1, definitionId: raw.definitionId, key: raw.key, batchIndex: raw.batchIndex, reason: raw.reason, message: raw.message, ...typeof raw.expiresAt === "string" ? { expiresAt: raw.expiresAt } : {}, ...typeof raw.responseSchemaHash === "string" ? { responseSchemaHash: raw.responseSchemaHash } : {}, ...typeof raw.payloadSchemaHash === "string" ? { payloadSchemaHash: raw.payloadSchemaHash } : {}, ...Object.prototype.hasOwnProperty.call(raw, "payload") ? { payload: raw.payload } : {} } }; } /** Put a parsed continuation on `ResumeEntry.metadata`. */ function wrapGenericInterruptContinuation(continuation) { return { [INTERRUPT_CONTINUATION_METADATA_KEY]: continuation }; } /** * Build the resume-metadata continuation from an outbound AG-UI interrupt. * * Returns `undefined` when the descriptor is not a first-party generic item. */ function genericInterruptContinuationFromDescriptor(interrupt) { const binding = readUnopenedInterruptBinding(interrupt); if (binding?.kind !== "generic" || binding.definitionId === void 0 || binding.key === void 0 || binding.batchIndex === void 0) return; const metadata = isRecord(interrupt.metadata) ? interrupt.metadata : void 0; const hasPayload = metadata !== void 0 && Object.prototype.hasOwnProperty.call(metadata, "tanstack:interruptPayload"); return { v: 1, definitionId: binding.definitionId, key: binding.key, batchIndex: binding.batchIndex, reason: interrupt.reason, message: interrupt.message ?? "", ...interrupt.expiresAt !== void 0 ? { expiresAt: interrupt.expiresAt } : {}, ...binding.responseSchemaHash !== void 0 ? { responseSchemaHash: binding.responseSchemaHash } : {}, ...binding.payloadSchemaHash !== void 0 ? { payloadSchemaHash: binding.payloadSchemaHash } : {}, ...hasPayload ? { payload: metadata[INTERRUPT_PAYLOAD_METADATA_KEY] } : {} }; } //#endregion export { INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, genericInterruptContinuationFromDescriptor, readGenericInterruptContinuation, wrapGenericInterruptContinuation }; //# sourceMappingURL=generic-interrupt-continuation.js.map