@mastra/core
Version:
1,346 lines (1,339 loc) • 42.6 kB
JavaScript
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