UNPKG

@mastra/core

Version:
1,346 lines (1,339 loc) • 42.6 kB
import { DelayedPromise } from './chunk-ZWZWJC3R.js'; import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from './chunk-HHYICF3X.js'; import { ReadableStream as ReadableStream$1, WritableStream as WritableStream$1 } from 'stream/web'; import EventEmitter from 'events'; var MastraAgentNetworkStream = class extends ReadableStream$1 { #usageCount = { inputTokens: 0, outputTokens: 0, totalTokens: 0, cachedInputTokens: 0, cacheCreationInputTokens: 0, reasoningTokens: 0 }; #streamPromise; #objectPromise; #objectStreamController = null; #objectStream = null; #run; runId; constructor({ createStream, run }) { const deferredPromise = { promise: null, resolve: null, reject: null }; deferredPromise.promise = new Promise((resolve, reject) => { deferredPromise.resolve = resolve; deferredPromise.reject = reject; }); const objectDeferredPromise = { promise: null, resolve: null, reject: null }; objectDeferredPromise.promise = new Promise((resolve, reject) => { objectDeferredPromise.resolve = resolve; objectDeferredPromise.reject = reject; }); let objectStreamController = null; const updateUsageCount = (usage) => { this.#usageCount.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); this.#usageCount.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); this.#usageCount.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); this.#usageCount.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); this.#usageCount.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); this.#usageCount.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); }; super({ start: async (controller) => { try { const writer = new WritableStream({ write: (chunk) => { if (chunk.type === "step-output" && chunk.payload?.output?.from === "AGENT" && chunk.payload?.output?.type === "finish" || chunk.type === "step-output" && chunk.payload?.output?.from === "WORKFLOW" && chunk.payload?.output?.type === "finish") { const output = chunk.payload?.output; if (output && "payload" in output && output.payload) { const finishPayload = output.payload; if ("usage" in finishPayload && finishPayload.usage) { updateUsageCount(finishPayload.usage); } else if ("output" in finishPayload && finishPayload.output) { const outputPayload = finishPayload.output; if ("usage" in outputPayload && outputPayload.usage) { updateUsageCount(outputPayload.usage); } } } } controller.enqueue(chunk); } }); const stream = await createStream(writer); const getInnerChunk = (chunk) => { if (chunk.type === "workflow-step-output") { return getInnerChunk(chunk.payload.output); } return chunk; }; let objectResolved = false; for await (const chunk of stream) { if (chunk.type === "workflow-step-output") { const innerChunk = getInnerChunk(chunk); if (innerChunk.type === "routing-agent-end" || innerChunk.type === "agent-execution-end" || innerChunk.type === "workflow-execution-end") { if (innerChunk.payload?.usage) { updateUsageCount(innerChunk.payload.usage); } } if (innerChunk.type === "network-object") { if (objectStreamController) { objectStreamController.enqueue(innerChunk.payload?.object); } controller.enqueue(innerChunk); } else if (innerChunk.type === "network-object-result") { if (!objectResolved) { objectResolved = true; objectDeferredPromise.resolve(innerChunk.payload?.object); if (objectStreamController) { objectStreamController.close(); } } controller.enqueue(innerChunk); } else if (innerChunk.type === "network-execution-event-finish") { const finishPayload = { ...innerChunk.payload, usage: this.#usageCount }; controller.enqueue({ ...innerChunk, payload: finishPayload }); } else { controller.enqueue(innerChunk); } } } if (!objectResolved) { objectDeferredPromise.resolve(void 0); if (objectStreamController) { objectStreamController.close(); } } controller.close(); deferredPromise.resolve(); } catch (error) { controller.error(error); deferredPromise.reject(error); objectDeferredPromise.reject(error); if (objectStreamController) { objectStreamController.error(error); } } } }); this.#run = run; this.#streamPromise = deferredPromise; this.runId = run.runId; this.#objectPromise = objectDeferredPromise; this.#objectStream = new ReadableStream$1({ start: (ctrl) => { objectStreamController = ctrl; this.#objectStreamController = ctrl; } }); } get status() { return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()).then((res) => res.status); } get result() { return this.#streamPromise.promise.then(() => this.#run._getExecutionResults()); } get usage() { return this.#streamPromise.promise.then(() => this.#usageCount); } /** * Returns a promise that resolves to the structured output object. * Only available when structuredOutput option is provided to network(). * Resolves to undefined if no structuredOutput was requested. */ get object() { return this.#objectPromise.promise; } /** * Returns a ReadableStream of partial objects during structured output generation. * Useful for streaming partial results as they're being generated. */ get objectStream() { return this.#objectStream; } }; // src/stream/aisdk/v5/compat/ui-message.ts function convertFullStreamChunkToUIMessageStream({ part, messageMetadataValue, sendReasoning, sendSources, onError, sendStart, sendFinish, responseMessageId }) { const partType = part.type; switch (partType) { case "text-start": { return { type: "text-start", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } case "text-delta": { return { type: "text-delta", id: part.id, delta: part.text, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } case "text-end": { return { type: "text-end", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } case "reasoning-start": { return { type: "reasoning-start", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } case "reasoning-delta": { if (sendReasoning) { return { type: "reasoning-delta", id: part.id, delta: part.text, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } return; } case "reasoning-end": { return { type: "reasoning-end", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } case "file": { return { type: "file", mediaType: part.file.mediaType, url: `data:${part.file.mediaType};base64,${part.file.base64}` }; } case "source": { if (sendSources && part.sourceType === "url") { return { type: "source-url", sourceId: part.id, url: part.url, title: part.title, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } if (sendSources && part.sourceType === "document") { return { type: "source-document", sourceId: part.id, mediaType: part.mediaType, title: part.title, filename: part.filename, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; } return; } case "tool-input-start": { return { type: "tool-input-start", toolCallId: part.id, toolName: part.toolName, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.dynamic != null ? { dynamic: part.dynamic } : {} }; } case "tool-input-delta": { return { type: "tool-input-delta", toolCallId: part.id, inputTextDelta: part.delta }; } case "tool-call": { return { type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.dynamic != null ? { dynamic: part.dynamic } : {} }; } case "tool-result": { return { type: "tool-output-available", toolCallId: part.toolCallId, output: part.output, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.dynamic != null ? { dynamic: part.dynamic } : {} }; } case "tool-output": { return { ...part.output }; } case "tool-error": { return { type: "tool-output-error", toolCallId: part.toolCallId, errorText: onError(part.error), ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.dynamic != null ? { dynamic: part.dynamic } : {} }; } case "error": { return { type: "error", errorText: onError(part.error) }; } case "start-step": { return { type: "start-step" }; } case "finish-step": { return { type: "finish-step" }; } case "start": { if (sendStart) { return { type: "start", ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}, ...responseMessageId != null ? { messageId: responseMessageId } : {} }; } return; } case "finish": { if (sendFinish) { return { type: "finish", ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {} }; } return; } case "abort": { return part; } case "tool-input-end": { return; } case "raw": { return; } default: { const exhaustiveCheck = partType; throw new Error(`Unknown chunk type: ${exhaustiveCheck}`); } } } // src/stream/base/consume-stream.ts async function consumeStream({ stream, onError }) { const reader = stream.getReader(); try { while (true) { const { done } = await reader.read(); if (done) break; } } catch (error) { onError == null ? void 0 : onError(error); } finally { reader.releaseLock(); } } // src/stream/RunOutput.ts var WorkflowRunOutput = class { #status = "running"; #tripwireData; #usageCount = { inputTokens: 0, outputTokens: 0, totalTokens: 0, cachedInputTokens: 0, cacheCreationInputTokens: 0, reasoningTokens: 0 }; #consumptionStarted = false; #baseStream; #emitter = new EventEmitter(); #bufferedChunks = []; #streamFinished = false; #streamError; #delayedPromises = { usage: new DelayedPromise(), result: new DelayedPromise() }; /** * Unique identifier for this workflow run */ runId; /** * Unique identifier for this workflow */ workflowId; constructor({ runId, workflowId, stream }) { const self = this; this.runId = runId; this.workflowId = workflowId; this.#baseStream = stream; stream.pipeTo( new WritableStream$1({ start() { const chunk = { type: "workflow-start", runId: self.runId, from: "WORKFLOW" /* WORKFLOW */, payload: { workflowId: self.workflowId } }; self.#bufferedChunks.push(chunk); self.#emitter.emit("chunk", chunk); }, write(chunk) { if (chunk.type !== "workflow-step-finish") { self.#bufferedChunks.push(chunk); self.#emitter.emit("chunk", chunk); } if (chunk.type === "workflow-step-output") { if ("output" in chunk.payload && chunk.payload.output) { const output = chunk.payload.output; if (output.type === "finish") { if (output.payload && "usage" in output.payload && output.payload.usage) { self.#updateUsageCount(output.payload.usage); } else if (output.payload && "output" in output.payload && output.payload.output) { const outputPayload = output.payload.output; if ("usage" in outputPayload && outputPayload.usage) { self.#updateUsageCount(outputPayload.usage); } } } } } else if (chunk.type === "workflow-canceled") { self.#status = "canceled"; } else if (chunk.type === "workflow-step-suspended") { self.#status = "suspended"; } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { if (chunk.payload.tripwire) { self.#status = "tripwire"; self.#tripwireData = chunk.payload.tripwire; } else { self.#status = "failed"; } } else if (chunk.type === "workflow-paused") { self.#status = "paused"; } }, close() { if (self.#status === "running") { self.#status = "success"; } self.#emitter.emit("chunk", { type: "workflow-finish", runId: self.runId, from: "WORKFLOW" /* WORKFLOW */, payload: { workflowStatus: self.#status, metadata: self.#streamError ? { error: self.#streamError, errorMessage: self.#streamError?.message } : {}, output: { usage: self.#usageCount }, // Include tripwire data when status is 'tripwire' ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} } }); self.#delayedPromises.usage.resolve(self.#usageCount); Object.entries(self.#delayedPromises).forEach(([key, promise]) => { if (promise.status.type === "pending") { promise.reject(new Error(`promise '${key}' was not resolved or rejected when stream finished`)); } }); self.#streamFinished = true; self.#emitter.emit("finish"); } }) ).catch((reason) => { console.log(" something went wrong", reason); }); } #getDelayedPromise(promise) { if (!this.#consumptionStarted) { void this.consumeStream(); } return promise.promise; } #updateUsageCount(usage) { let totalUsage = { inputTokens: this.#usageCount.inputTokens ?? 0, outputTokens: this.#usageCount.outputTokens ?? 0, totalTokens: this.#usageCount.totalTokens ?? 0, reasoningTokens: this.#usageCount.reasoningTokens ?? 0, cachedInputTokens: this.#usageCount.cachedInputTokens ?? 0, cacheCreationInputTokens: this.#usageCount.cacheCreationInputTokens ?? 0 }; if ("inputTokens" in usage) { totalUsage.inputTokens += parseInt(usage?.inputTokens?.toString() ?? "0", 10); totalUsage.outputTokens += parseInt(usage?.outputTokens?.toString() ?? "0", 10); } else if ("promptTokens" in usage) { totalUsage.inputTokens += parseInt(usage?.promptTokens?.toString() ?? "0", 10); totalUsage.outputTokens += parseInt(usage?.completionTokens?.toString() ?? "0", 10); } totalUsage.totalTokens += parseInt(usage?.totalTokens?.toString() ?? "0", 10); totalUsage.reasoningTokens += parseInt(usage?.reasoningTokens?.toString() ?? "0", 10); totalUsage.cachedInputTokens += parseInt(usage?.cachedInputTokens?.toString() ?? "0", 10); totalUsage.cacheCreationInputTokens += parseInt(usage?.cacheCreationInputTokens?.toString() ?? "0", 10); this.#usageCount = totalUsage; } /** * @internal */ updateResults(results) { this.#delayedPromises.result.resolve(results); } /** * @internal */ rejectResults(error) { this.#delayedPromises.result.reject(error); this.#status = "failed"; this.#streamError = error; } /** * @internal */ resume(stream) { this.#baseStream = stream; this.#streamFinished = false; this.#consumptionStarted = false; this.#status = "running"; this.#delayedPromises = { usage: new DelayedPromise(), result: new DelayedPromise() }; const self = this; stream.pipeTo( new WritableStream$1({ start() { const chunk = { type: "workflow-start", runId: self.runId, from: "WORKFLOW" /* WORKFLOW */, payload: { workflowId: self.workflowId } }; self.#bufferedChunks.push(chunk); self.#emitter.emit("chunk", chunk); }, write(chunk) { if (chunk.type !== "workflow-step-finish") { self.#bufferedChunks.push(chunk); self.#emitter.emit("chunk", chunk); } if (chunk.type === "workflow-step-output") { if ("output" in chunk.payload && chunk.payload.output) { const output = chunk.payload.output; if (output.type === "finish") { if (output.payload && "usage" in output.payload && output.payload.usage) { self.#updateUsageCount(output.payload.usage); } else if (output.payload && "output" in output.payload && output.payload.output) { const outputPayload = output.payload.output; if ("usage" in outputPayload && outputPayload.usage) { self.#updateUsageCount(outputPayload.usage); } } } } } else if (chunk.type === "workflow-canceled") { self.#status = "canceled"; } else if (chunk.type === "workflow-step-suspended") { self.#status = "suspended"; } else if (chunk.type === "workflow-step-result" && chunk.payload.status === "failed") { if (chunk.payload.tripwire) { self.#status = "tripwire"; self.#tripwireData = chunk.payload.tripwire; } else { self.#status = "failed"; } } else if (chunk.type === "workflow-paused") { self.#status = "paused"; } }, close() { if (self.#status === "running") { self.#status = "success"; } self.#emitter.emit("chunk", { type: "workflow-finish", runId: self.runId, from: "WORKFLOW" /* WORKFLOW */, payload: { workflowStatus: self.#status, metadata: self.#streamError ? { error: self.#streamError, errorMessage: self.#streamError?.message } : {}, output: { usage: self.#usageCount }, // Include tripwire data when status is 'tripwire' ...self.#status === "tripwire" && self.#tripwireData ? { tripwire: self.#tripwireData } : {} } }); self.#streamFinished = true; self.#emitter.emit("finish"); } }) ).catch((reason) => { console.log(" something went wrong", reason); }); } async consumeStream(options) { if (this.#consumptionStarted) { return; } this.#consumptionStarted = true; try { await consumeStream({ stream: this.#baseStream, onError: options?.onError }); } catch (error) { options?.onError?.(error); } } get fullStream() { const self = this; return new ReadableStream$1({ start(controller) { self.#bufferedChunks.forEach((chunk) => { controller.enqueue(chunk); }); if (self.#streamFinished) { controller.close(); return; } const chunkHandler = (chunk) => { controller.enqueue(chunk); }; const finishHandler = () => { self.#emitter.off("chunk", chunkHandler); self.#emitter.off("finish", finishHandler); controller.close(); }; self.#emitter.on("chunk", chunkHandler); self.#emitter.on("finish", finishHandler); }, pull(_controller) { if (!self.#consumptionStarted) { void self.consumeStream(); } }, cancel() { self.#emitter.removeAllListeners(); } }); } get status() { return this.#status; } get result() { return this.#getDelayedPromise(this.#delayedPromises.result); } get usage() { return this.#getDelayedPromise(this.#delayedPromises.usage); } /** * @deprecated Use `fullStream.locked` instead */ get locked() { console.warn("WorkflowRunOutput.locked is deprecated. Use fullStream.locked instead."); return this.fullStream.locked; } /** * @deprecated Use `fullStream.cancel()` instead */ cancel(reason) { console.warn("WorkflowRunOutput.cancel() is deprecated. Use fullStream.cancel() instead."); return this.fullStream.cancel(reason); } /** * @deprecated Use `fullStream.getReader()` instead */ getReader(options) { console.warn("WorkflowRunOutput.getReader() is deprecated. Use fullStream.getReader() instead."); return this.fullStream.getReader(options); } /** * @deprecated Use `fullStream.pipeThrough()` instead */ pipeThrough(transform, options) { console.warn("WorkflowRunOutput.pipeThrough() is deprecated. Use fullStream.pipeThrough() instead."); return this.fullStream.pipeThrough(transform, options); } /** * @deprecated Use `fullStream.pipeTo()` instead */ pipeTo(destination, options) { console.warn("WorkflowRunOutput.pipeTo() is deprecated. Use fullStream.pipeTo() instead."); return this.fullStream.pipeTo(destination, options); } /** * @deprecated Use `fullStream.tee()` instead */ tee() { console.warn("WorkflowRunOutput.tee() is deprecated. Use fullStream.tee() instead."); return this.fullStream.tee(); } /** * @deprecated Use `fullStream[Symbol.asyncIterator]()` instead */ [Symbol.asyncIterator]() { console.warn( "WorkflowRunOutput[Symbol.asyncIterator]() is deprecated. Use fullStream[Symbol.asyncIterator]() instead." ); return this.fullStream[Symbol.asyncIterator](); } /** * Helper method to treat this object as a ReadableStream * @deprecated Use `fullStream` directly instead */ toReadableStream() { console.warn("WorkflowRunOutput.toReadableStream() is deprecated. Use fullStream directly instead."); return this.fullStream; } }; // src/stream/aisdk/v5/transform.ts function sanitizeToolCallInput(input) { try { JSON.parse(input); return input; } catch { return input.replace(/<\|[^|]*\|>\s*/g, "").trim(); } } function tryRepairJson(input) { let repaired = input.trim(); repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)"/g, (match, prefix, name) => { if (prefix.trimEnd().endsWith('"')) { return match; } return `${prefix}"${name}"`; }); repaired = repaired.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'); repaired = repaired.replace(/'/g, '"'); repaired = repaired.replace(/,(\s*[}\]])/g, "$1"); repaired = repaired.replace(/:\s*(\d{4}-\d{2}-\d{2}(?:T[\d:]+)?)\s*([,}])/g, ': "$1"$2'); try { return JSON.parse(repaired); } catch { return null; } } function convertFullStreamChunkToMastra(value, ctx) { switch (value.type) { case "response-metadata": return { type: "response-metadata", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { ...value } }; case "text-start": return { type: "text-start", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, providerMetadata: value.providerMetadata } }; case "text-delta": if (value.delta) { return { type: "text-delta", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, providerMetadata: value.providerMetadata, text: value.delta } }; } return; case "text-end": return { type: "text-end", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: value }; case "reasoning-start": return { type: "reasoning-start", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, providerMetadata: value.providerMetadata } }; case "reasoning-delta": return { type: "reasoning-delta", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, providerMetadata: value.providerMetadata, text: value.delta } }; case "reasoning-end": return { type: "reasoning-end", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, providerMetadata: value.providerMetadata } }; case "source": return { type: "source", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { id: value.id, sourceType: value.sourceType, title: value.title || "", mimeType: value.sourceType === "document" ? value.mediaType : void 0, filename: value.sourceType === "document" ? value.filename : void 0, url: value.sourceType === "url" ? value.url : void 0, providerMetadata: value.providerMetadata } }; case "file": { const pm = value.providerMetadata; return { type: "file", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { data: value.data, base64: typeof value.data === "string" ? value.data : void 0, mimeType: value.mediaType, ...pm != null ? { providerMetadata: pm } : {} } }; } case "tool-call": { let toolCallInput = void 0; if (value.input) { const sanitized = sanitizeToolCallInput(value.input); if (sanitized) { try { toolCallInput = JSON.parse(sanitized); } catch { const repaired = tryRepairJson(sanitized); if (repaired) { toolCallInput = repaired; } else { console.error("Error converting tool call input to JSON", { input: value.input }); toolCallInput = void 0; } } } } return { type: "tool-call", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { toolCallId: value.toolCallId, toolName: value.toolName, args: toolCallInput, providerExecuted: value.providerExecuted, providerMetadata: value.providerMetadata, ...value.observability ? { observability: value.observability } : {} } }; } case "tool-result": return { type: "tool-result", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { toolCallId: value.toolCallId, toolName: value.toolName, result: value.result, isError: value.isError, providerExecuted: value.providerExecuted, providerMetadata: value.providerMetadata } }; case "tool-input-start": return { type: "tool-call-input-streaming-start", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { toolCallId: value.id, toolName: value.toolName, providerExecuted: value.providerExecuted, providerMetadata: value.providerMetadata, dynamic: value.dynamic, ...value.observability ? { observability: value.observability } : {} } }; case "tool-input-delta": if (value.delta) { return { type: "tool-call-delta", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { argsTextDelta: value.delta, toolCallId: value.id, providerMetadata: value.providerMetadata } }; } return; case "tool-input-end": return { type: "tool-call-input-streaming-end", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { toolCallId: value.id, providerMetadata: value.providerMetadata } }; case "finish": const { finishReason, usage, providerMetadata, messages, ...rest } = value; return { type: "finish", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: { providerMetadata: value.providerMetadata, stepResult: { reason: normalizeFinishReason(value.finishReason) }, output: { // Normalize usage to handle both V2 (flat) and V3 (nested) formats usage: normalizeUsage(value.usage) }, metadata: { providerMetadata: value.providerMetadata }, messages: messages ?? { all: [], user: [], nonUser: [] }, ...rest } }; case "error": return { type: "error", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: value }; case "raw": return { type: "raw", runId: ctx.runId, from: "AGENT" /* AGENT */, payload: value.rawValue }; } return; } function convertMastraChunkToAISDKv5({ chunk, mode = "stream" }) { switch (chunk.type) { case "start": return { type: "start" }; case "step-start": const { messageId: _messageId, ...rest } = chunk.payload; return { type: "start-step", request: rest.request, warnings: rest.warnings || [] }; case "raw": return { type: "raw", rawValue: chunk.payload }; case "finish": { return { type: "finish", // Cast needed: Mastra extends reason with 'tripwire' | 'retry' for processor scenarios finishReason: chunk.payload.stepResult.reason, // Cast needed: Mastra's LanguageModelUsage has optional properties, V2 has required-but-nullable totalUsage: chunk.payload.output.usage }; } case "reasoning-start": return { type: "reasoning-start", id: chunk.payload.id, providerMetadata: chunk.payload.providerMetadata }; case "reasoning-delta": return { type: "reasoning-delta", id: chunk.payload.id, text: chunk.payload.text, providerMetadata: chunk.payload.providerMetadata }; case "reasoning-signature": throw new Error('AISDKv5 chunk type "reasoning-signature" not supported'); case "redacted-reasoning": throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported'); case "reasoning-end": return { type: "reasoning-end", id: chunk.payload.id, providerMetadata: chunk.payload.providerMetadata }; case "source": if (chunk.payload.sourceType === "url") { return { type: "source", sourceType: "url", id: chunk.payload.id, url: chunk.payload.url, title: chunk.payload.title, providerMetadata: chunk.payload.providerMetadata }; } else { return { type: "source", sourceType: "document", id: chunk.payload.id, mediaType: chunk.payload.mimeType, title: chunk.payload.title, filename: chunk.payload.filename, providerMetadata: chunk.payload.providerMetadata }; } case "file": { const filePart = mode === "generate" ? { type: "file", file: new DefaultGeneratedFile({ data: chunk.payload.data, mediaType: chunk.payload.mimeType }) } : { type: "file", file: new DefaultGeneratedFileWithType({ data: chunk.payload.data, mediaType: chunk.payload.mimeType }) }; if (chunk.payload.providerMetadata) { filePart.providerMetadata = chunk.payload.providerMetadata; } return filePart; } case "tool-call": { const toolCallPart = { type: "tool-call", toolCallId: chunk.payload.toolCallId, providerMetadata: chunk.payload.providerMetadata, providerExecuted: chunk.payload.providerExecuted, toolName: chunk.payload.toolName, input: chunk.payload.args }; if (chunk.payload.observability) { toolCallPart.observability = chunk.payload.observability; } return toolCallPart; } case "tool-call-input-streaming-start": return { type: "tool-input-start", id: chunk.payload.toolCallId, toolName: chunk.payload.toolName, dynamic: !!chunk.payload.dynamic, providerMetadata: chunk.payload.providerMetadata, providerExecuted: chunk.payload.providerExecuted, ...chunk.payload.observability ? { observability: chunk.payload.observability } : {} }; case "tool-call-input-streaming-end": return { type: "tool-input-end", id: chunk.payload.toolCallId, providerMetadata: chunk.payload.providerMetadata }; case "tool-call-delta": return { type: "tool-input-delta", id: chunk.payload.toolCallId, delta: chunk.payload.argsTextDelta, providerMetadata: chunk.payload.providerMetadata }; case "step-finish": { const { request: _request, providerMetadata: metadataProviderMetadata, ...rest2 } = chunk.payload.metadata; return { type: "finish-step", response: { id: chunk.payload.id || "", timestamp: /* @__PURE__ */ new Date(), modelId: rest2.modelId || "", ...rest2 }, usage: chunk.payload.output.usage, finishReason: chunk.payload.stepResult.reason, providerMetadata: metadataProviderMetadata ?? chunk.payload.providerMetadata }; } case "text-delta": return { type: "text-delta", id: chunk.payload.id, text: chunk.payload.text, providerMetadata: chunk.payload.providerMetadata }; case "text-end": return { type: "text-end", id: chunk.payload.id, providerMetadata: chunk.payload.providerMetadata }; case "text-start": return { type: "text-start", id: chunk.payload.id, providerMetadata: chunk.payload.providerMetadata }; case "tool-result": return { type: "tool-result", input: chunk.payload.args, toolCallId: chunk.payload.toolCallId, providerExecuted: chunk.payload.providerExecuted, toolName: chunk.payload.toolName, output: chunk.payload.result // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? }; case "tool-error": return { type: "tool-error", error: chunk.payload.error, input: chunk.payload.args, toolCallId: chunk.payload.toolCallId, providerExecuted: chunk.payload.providerExecuted, toolName: chunk.payload.toolName // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this? }; case "abort": return { type: "abort" }; case "error": return { type: "error", error: chunk.payload.error }; case "object": return { type: "object", object: chunk.object }; default: if (chunk.type && "payload" in chunk && chunk.payload) { return { type: chunk.type, ...chunk.payload || {} }; } return; } } function isV3Usage(usage) { if (!usage || typeof usage !== "object") return false; const u = usage; return typeof u.inputTokens === "object" && u.inputTokens !== null && "total" in u.inputTokens && typeof u.outputTokens === "object" && u.outputTokens !== null && "total" in u.outputTokens; } function normalizeUsage(usage) { if (!usage) { return { inputTokens: void 0, outputTokens: void 0, totalTokens: void 0, reasoningTokens: void 0, cachedInputTokens: void 0, cacheCreationInputTokens: void 0, raw: void 0 }; } if (isV3Usage(usage)) { const inputTokens = usage.inputTokens.total; const outputTokens = usage.outputTokens.total; return { inputTokens, outputTokens, totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0), reasoningTokens: usage.outputTokens.reasoning, cachedInputTokens: usage.inputTokens.cacheRead, cacheCreationInputTokens: usage.inputTokens.cacheWrite, raw: usage }; } const v2Usage = usage; return { inputTokens: v2Usage.inputTokens, outputTokens: v2Usage.outputTokens, totalTokens: v2Usage.totalTokens ?? (v2Usage.inputTokens ?? 0) + (v2Usage.outputTokens ?? 0), reasoningTokens: v2Usage.reasoningTokens, cachedInputTokens: v2Usage.cachedInputTokens, cacheCreationInputTokens: v2Usage.cacheCreationInputTokens, raw: usage }; } function isV3FinishReason(finishReason) { return typeof finishReason === "object" && finishReason !== null && "unified" in finishReason; } function normalizeFinishReason(finishReason) { if (!finishReason) { return "other"; } if (finishReason === "tripwire" || finishReason === "retry") { return finishReason; } if (isV3FinishReason(finishReason)) { return finishReason.unified; } return finishReason === "unknown" ? "other" : finishReason; } // src/stream/caching-transform-stream.ts function createCachingTransformStream(options) { const { cache, cacheKey, serialize = (x) => x, deserialize = (x) => x } = options; const transform = new TransformStream({ transform(chunk, controller) { const serialized = serialize(chunk); cache.listPush(cacheKey, serialized).catch(() => { }); controller.enqueue(chunk); } }); const getHistory = async (offset = 0) => { const cached = await cache.listFromTo(cacheKey, offset); return cached.map((item) => deserialize(item)); }; const clearCache = async () => { await cache.delete(cacheKey); }; return { transform, getHistory, clearCache }; } function createReplayStream(options) { const { history, liveSource, cache, cacheKey, serialize = (x) => x } = options; let historyIndex = 0; let liveReader = null; let historyComplete = false; return new ReadableStream({ async pull(controller) { if (!historyComplete) { if (historyIndex < history.length) { controller.enqueue(history[historyIndex]); historyIndex++; return; } historyComplete = true; liveReader = liveSource.getReader(); } if (liveReader) { try { const { done, value } = await liveReader.read(); if (done) { controller.close(); return; } if (cache && cacheKey) { const serialized = serialize(value); cache.listPush(cacheKey, serialized).catch(() => { }); } controller.enqueue(value); } catch (error) { controller.error(error); } } }, cancel() { if (liveReader) { void liveReader.cancel(); } } }); } function withStreamCaching(options) { const { cache, cacheKey, serialize, deserialize } = options; return { pipeThrough: () => { const { transform } = createCachingTransformStream({ cache, cacheKey, serialize, deserialize }); return transform; }, getHistory: async (offset = 0) => { const deserializeFn = deserialize ?? ((x) => x); const cached = await cache.listFromTo(cacheKey, offset); return cached.map((item) => deserializeFn(item)); }, clearCache: async () => { await cache.delete(cacheKey); } }; } export { MastraAgentNetworkStream, WorkflowRunOutput, convertFullStreamChunkToMastra, convertFullStreamChunkToUIMessageStream, convertMastraChunkToAISDKv5, createCachingTransformStream, createReplayStream, withStreamCaching }; //# sourceMappingURL=chunk-IZCPXICU.js.map //# sourceMappingURL=chunk-IZCPXICU.js.map