@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
1,127 lines (1,123 loc) • 34.1 kB
JavaScript
import { isZodType, delay } from './chunk-K3E3M5U5.js';
import { toStandardSchema, standardSchemaToJSONSchema, isStandardSchemaWithJSON } from './chunk-6SRTDZ7S.js';
import { isZodArray, getZodDef } from './chunk-RT2LCNDN.js';
import { resolveObservabilityContext } from './chunk-4ZCIE3Q5.js';
import { executeWithContext, executeWithContextSync } from './chunk-MJEXAXIO.js';
import { MastraBase } from './chunk-WENZPAHS.js';
import { output_exports, generateText, generateObject, streamText, streamObject } from './chunk-SUISXAWH.js';
import { MastraError } from './chunk-FJEVLHJT.js';
import { OpenAIReasoningSchemaCompatLayer, OpenAISchemaCompatLayer, GoogleSchemaCompatLayer, AnthropicSchemaCompatLayer, DeepSeekSchemaCompatLayer, MetaSchemaCompatLayer, applyCompatLayer, jsonSchema } from '@mastra/schema-compat';
import { randomUUID } from 'crypto';
// src/stream/aisdk/v4/usage.ts
function convertV4Usage(usage) {
if (!usage) {
return {};
}
return {
inputTokens: usage.promptTokens,
outputTokens: usage.completionTokens
};
}
// src/llm/model/model.ts
var MastraLLMV1 = class extends MastraBase {
#model;
#mastra;
#options;
constructor({ model, mastra, options }) {
super({ name: "aisdk" });
this.#model = model;
this.#options = options;
if (mastra) {
this.#mastra = mastra;
if (mastra.getLogger()) {
this.__setLogger(this.#mastra.getLogger());
}
}
}
__registerPrimitives(p) {
if (p.logger) {
this.__setLogger(p.logger);
}
}
__registerMastra(p) {
this.#mastra = p;
}
getProvider() {
return this.#model.provider;
}
getModelId() {
return this.#model.modelId;
}
getModel() {
return this.#model;
}
_applySchemaCompat(schema) {
const model = this.#model;
const schemaCompatLayers = [];
if (model) {
const modelInfo = {
modelId: model.modelId,
supportsStructuredOutputs: model.supportsStructuredOutputs ?? false,
provider: model.provider
};
schemaCompatLayers.push(
new OpenAIReasoningSchemaCompatLayer(modelInfo),
new OpenAISchemaCompatLayer(modelInfo),
new GoogleSchemaCompatLayer(modelInfo),
new AnthropicSchemaCompatLayer(modelInfo),
new DeepSeekSchemaCompatLayer(modelInfo),
new MetaSchemaCompatLayer(modelInfo)
);
}
return applyCompatLayer({
schema,
compatLayers: schemaCompatLayers,
mode: "aiSdkSchema"
});
}
async __text({
runId,
messages,
maxSteps = 5,
tools = {},
temperature,
toolChoice = "auto",
onStepFinish,
experimental_output,
threadId,
resourceId,
requestContext,
...rest
}) {
const model = this.#model;
const observabilityContext = resolveObservabilityContext(rest);
this.logger.debug("Generating text", {
runId,
messages,
maxSteps,
threadId,
resourceId,
tools: Object.keys(tools)
});
let schema = void 0;
if (experimental_output) {
this.logger.debug("Using experimental output", {
runId
});
if (isZodType(experimental_output)) {
schema = experimental_output;
if (isZodArray(schema)) {
schema = getZodDef(schema).type;
}
const standardSchema = toStandardSchema(schema);
const jsonSchemaToUse = standardSchemaToJSONSchema(standardSchema);
schema = jsonSchema(jsonSchemaToUse);
} else {
schema = jsonSchema(experimental_output);
}
}
if (tools && Object.keys(tools).length > 0) {
for (const tool of Object.values(tools)) {
if (tool.parameters) {
if ("validate" in tool.parameters) {
tool.parameters = tool.parameters;
} else if (isStandardSchemaWithJSON(tool.parameters)) {
tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters));
} else {
tool.parameters = jsonSchema(tool.parameters);
}
}
}
}
const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({
name: `llm: '${model.modelId}'`,
type: "model_generation" /* MODEL_GENERATION */,
input: {
messages,
schema
},
attributes: {
model: model.modelId,
provider: model.provider,
parameters: {
temperature,
maxOutputTokens: rest.maxTokens,
topP: rest.topP,
frequencyPenalty: rest.frequencyPenalty,
presencePenalty: rest.presencePenalty
},
streaming: false
},
metadata: {
runId,
threadId,
resourceId
},
tracingPolicy: this.#options?.tracingPolicy,
requestContext
});
const argsForExecute = {
...rest,
messages,
model,
temperature,
tools: {
...tools
},
toolChoice,
maxSteps,
onStepFinish: async (props) => {
try {
await onStepFinish?.({ ...props, runId });
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_TEXT_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown",
finishReason: props?.finishReason,
toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "",
toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "",
usage: props?.usage ? JSON.stringify(props.usage) : ""
}
},
e
);
throw mastraError;
}
this.logger.debug("Text step change", {
text: props?.text,
toolCalls: props?.toolCalls,
toolResults: props?.toolResults,
finishReason: props?.finishReason,
usage: props?.usage,
runId
});
const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10);
if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) {
this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId });
await delay(10 * 1e3);
}
},
experimental_output: schema ? output_exports.object({
schema
}) : void 0
};
try {
const result = await executeWithContext({
span: llmSpan,
fn: () => generateText(argsForExecute)
});
if (schema && result.finishReason === "stop") {
result.object = result.experimental_output;
}
llmSpan?.end({
output: {
text: result.text,
object: result.object,
reasoning: result.reasoningDetails,
reasoningText: result.reasoning,
files: result.files,
sources: result.sources,
toolCalls: result.toolCalls,
warnings: result.warnings
},
attributes: {
finishReason: result.finishReason,
responseId: result.response?.id,
responseModel: result.response?.modelId,
usage: convertV4Usage(result.usage)
}
});
return result;
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_GENERATE_TEXT_AI_SDK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Generate text failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
}
async __textObject({
messages,
structuredOutput,
runId,
threadId,
resourceId,
requestContext,
...rest
}) {
const model = this.#model;
const observabilityContext = resolveObservabilityContext(rest);
this.logger.debug("Generating text object", { runId });
const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({
name: `llm: '${model.modelId}'`,
type: "model_generation" /* MODEL_GENERATION */,
input: {
messages
},
attributes: {
model: model.modelId,
provider: model.provider,
parameters: {
temperature: rest.temperature,
maxOutputTokens: rest.maxTokens,
topP: rest.topP,
frequencyPenalty: rest.frequencyPenalty,
presencePenalty: rest.presencePenalty
},
streaming: false
},
metadata: {
runId,
threadId,
resourceId
},
tracingPolicy: this.#options?.tracingPolicy,
requestContext
});
try {
let output = "object";
if (isZodArray(structuredOutput)) {
output = "array";
const zodDef = getZodDef(structuredOutput);
if ("element" in zodDef) {
structuredOutput = zodDef.element;
} else {
structuredOutput = zodDef.type;
}
}
const processedSchema = this._applySchemaCompat(structuredOutput);
llmSpan?.update({
input: {
messages,
schema: processedSchema
}
});
const argsForExecute = {
...rest,
messages,
model,
output,
schema: processedSchema
};
try {
const result = await generateObject(argsForExecute);
llmSpan?.end({
output: {
object: result.object,
warnings: result.warnings
},
attributes: {
finishReason: result.finishReason,
responseId: result.response?.id,
responseModel: result.response?.modelId,
usage: convertV4Usage(result.usage)
}
});
return result;
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_GENERATE_OBJECT_AI_SDK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Generate object failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
} catch (e) {
if (e instanceof MastraError) {
throw e;
}
const mastraError = new MastraError(
{
id: "LLM_GENERATE_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Generate object schema conversion failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
}
__stream({
messages,
onStepFinish,
onFinish,
maxSteps = 5,
tools = {},
runId,
temperature,
toolChoice = "auto",
experimental_output,
threadId,
resourceId,
requestContext,
...rest
}) {
const model = this.#model;
const observabilityContext = resolveObservabilityContext(rest);
let schema;
if (experimental_output) {
if (typeof experimental_output.parse === "function") {
schema = experimental_output;
if (isZodArray(schema)) {
schema = getZodDef(schema).type;
}
} else {
schema = jsonSchema(experimental_output);
}
}
const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({
name: `llm: '${model.modelId}'`,
type: "model_generation" /* MODEL_GENERATION */,
input: {
messages
},
attributes: {
model: model.modelId,
provider: model.provider,
parameters: {
temperature,
maxOutputTokens: rest.maxTokens,
topP: rest.topP,
frequencyPenalty: rest.frequencyPenalty,
presencePenalty: rest.presencePenalty
},
streaming: true
},
metadata: {
runId,
threadId,
resourceId
},
tracingPolicy: this.#options?.tracingPolicy,
requestContext
});
if (llmSpan) {
executeWithContextSync({
span: llmSpan,
fn: () => this.logger.debug("Streaming text", {
runId,
threadId,
resourceId,
messages,
maxSteps,
tools: Object.keys(tools || {})
})
});
}
if (tools && Object.keys(tools).length > 0) {
for (const tool of Object.values(tools)) {
if (tool.parameters) {
if ("validate" in tool.parameters) {
tool.parameters = tool.parameters;
} else if (isStandardSchemaWithJSON(tool.parameters)) {
tool.parameters = jsonSchema(standardSchemaToJSONSchema(tool.parameters));
} else {
tool.parameters = jsonSchema(tool.parameters);
}
}
}
}
const argsForExecute = {
model,
temperature,
tools: {
...tools
},
maxSteps,
toolChoice,
onStepFinish: async (props) => {
try {
await onStepFinish?.({ ...props, runId });
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_STREAM_ON_STEP_FINISH_CALLBACK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown",
finishReason: props?.finishReason,
toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "",
toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "",
usage: props?.usage ? JSON.stringify(props.usage) : ""
}
},
e
);
this.logger.trackException(mastraError);
llmSpan?.error({ error: mastraError });
throw mastraError;
}
this.logger.debug("Stream step change", {
text: props?.text,
toolCalls: props?.toolCalls,
toolResults: props?.toolResults,
finishReason: props?.finishReason,
usage: props?.usage,
runId
});
const remainingTokens = parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"] ?? "", 10);
if (!isNaN(remainingTokens) && remainingTokens > 0 && remainingTokens < 2e3) {
this.logger.warn("Rate limit approaching, waiting 10 seconds", { runId });
await delay(10 * 1e3);
}
},
onFinish: async (props) => {
llmSpan?.end({
output: {
text: props?.text,
reasoning: props?.reasoningDetails,
reasoningText: props?.reasoning,
files: props?.files,
sources: props?.sources,
toolCalls: props?.toolCalls,
warnings: props?.warnings
},
attributes: {
finishReason: props?.finishReason,
usage: convertV4Usage(props?.usage)
}
});
try {
await onFinish?.({ ...props, runId });
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_STREAM_ON_FINISH_CALLBACK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown",
finishReason: props?.finishReason,
toolCalls: props?.toolCalls ? JSON.stringify(props.toolCalls) : "",
toolResults: props?.toolResults ? JSON.stringify(props.toolResults) : "",
usage: props?.usage ? JSON.stringify(props.usage) : ""
}
},
e
);
llmSpan?.error({ error: mastraError });
this.logger.trackException(mastraError);
throw mastraError;
}
this.logger.debug("Stream finished", {
text: props?.text,
toolCalls: props?.toolCalls,
toolResults: props?.toolResults,
finishReason: props?.finishReason,
usage: props?.usage,
runId,
threadId,
resourceId
});
},
onError: ({ error }) => {
const mastraError = new MastraError(
{
id: "LLM_STREAM_TEXT_AI_SDK_STREAMING_ERROR",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
error
);
this.logger.error("Stream text error", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
},
...rest,
messages,
experimental_output: schema ? output_exports.object({
schema
}) : void 0
};
try {
return executeWithContextSync({ span: llmSpan, fn: () => streamText(argsForExecute) });
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_STREAM_TEXT_AI_SDK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Stream text failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
}
__streamObject({
messages,
runId,
requestContext,
threadId,
resourceId,
onFinish,
structuredOutput,
...rest
}) {
const model = this.#model;
const observabilityContext = resolveObservabilityContext(rest);
this.logger.debug("Streaming structured output", {
runId,
messages
});
const llmSpan = observabilityContext.tracingContext.currentSpan?.createChildSpan({
name: `llm: '${model.modelId}'`,
type: "model_generation" /* MODEL_GENERATION */,
input: {
messages
},
attributes: {
model: model.modelId,
provider: model.provider,
parameters: {
temperature: rest.temperature,
maxOutputTokens: rest.maxTokens,
topP: rest.topP,
frequencyPenalty: rest.frequencyPenalty,
presencePenalty: rest.presencePenalty
},
streaming: true
},
metadata: {
runId,
threadId,
resourceId
},
tracingPolicy: this.#options?.tracingPolicy,
requestContext
});
try {
let output = "object";
if (isZodArray(structuredOutput)) {
output = "array";
structuredOutput = getZodDef(structuredOutput).type;
}
const processedSchema = this._applySchemaCompat(structuredOutput);
llmSpan?.update({
input: {
messages,
schema: processedSchema
}
});
const argsForExecute = {
...rest,
model,
onFinish: async (props) => {
llmSpan?.end({
output: {
text: props?.text,
object: props?.object,
reasoning: props?.reasoningDetails,
reasoningText: props?.reasoning,
files: props?.files,
sources: props?.sources,
warnings: props?.warnings
},
attributes: {
finishReason: props?.finishReason,
usage: props?.usage
}
});
try {
await onFinish?.({ ...props, runId });
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_STREAM_OBJECT_ON_FINISH_CALLBACK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown",
toolCalls: "",
toolResults: "",
finishReason: "",
usage: props?.usage ? JSON.stringify(props.usage) : ""
}
},
e
);
this.logger.trackException(mastraError);
llmSpan?.error({ error: mastraError });
throw mastraError;
}
this.logger.debug("Object stream finished", {
usage: props?.usage,
runId,
threadId,
resourceId
});
},
onError: ({ error }) => {
const mastraError = new MastraError(
{
id: "LLM_STREAM_OBJECT_AI_SDK_STREAMING_ERROR",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
error
);
this.logger.error("Stream object error", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
},
messages,
output,
schema: processedSchema
};
try {
return streamObject(argsForExecute);
} catch (e) {
const mastraError = new MastraError(
{
id: "LLM_STREAM_OBJECT_AI_SDK_EXECUTION_FAILED",
domain: "LLM" /* LLM */,
category: "THIRD_PARTY" /* THIRD_PARTY */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Stream object failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
} catch (e) {
if (e instanceof MastraError) {
llmSpan?.error({ error: e });
throw e;
}
const mastraError = new MastraError(
{
id: "LLM_STREAM_OBJECT_AI_SDK_SCHEMA_CONVERSION_FAILED",
domain: "LLM" /* LLM */,
category: "USER" /* USER */,
details: {
modelId: model.modelId,
modelProvider: model.provider,
runId: runId ?? "unknown",
threadId: threadId ?? "unknown",
resourceId: resourceId ?? "unknown"
}
},
e
);
this.logger.error("Stream object schema conversion failed", {
error: mastraError,
runId,
threadId,
resourceId,
modelId: model.modelId,
modelProvider: model.provider
});
llmSpan?.error({ error: mastraError });
throw mastraError;
}
}
convertToMessages(messages) {
if (Array.isArray(messages)) {
return messages.map((m) => {
if (typeof m === "string") {
return {
role: "user",
content: m
};
}
return m;
});
}
return [
{
role: "user",
content: messages
}
];
}
async generate(messages, args) {
const msgs = this.convertToMessages(messages);
const { output, ...rest } = args ?? {};
if (!output) {
return await this.__text({
messages: msgs,
...rest
});
}
return await this.__textObject({
messages: msgs,
structuredOutput: output,
...rest
});
}
stream(messages, args) {
const msgs = this.convertToMessages(messages);
const { output, ...rest } = args ?? {};
if (!output) {
const {
maxSteps = 5,
onFinish: onFinish2,
...streamRest
} = rest;
return this.__stream({
messages: msgs,
maxSteps,
onFinish: onFinish2,
...streamRest
});
}
const { onFinish, ...objectRest } = rest;
return this.__streamObject({
messages: msgs,
structuredOutput: output,
onFinish,
...objectRest
});
}
};
function createStreamFromGenerateResult(result) {
return new ReadableStream({
start(controller) {
controller.enqueue({ type: "stream-start", warnings: result.warnings });
controller.enqueue({
type: "response-metadata",
id: result.response?.id,
modelId: result.response?.modelId,
timestamp: result.response?.timestamp
});
const toolCallMeta = {};
for (const message of result.content) {
if (message.type === "tool-call") {
const toolCall = message;
toolCallMeta[toolCall.toolCallId] = { providerExecuted: toolCall.providerExecuted };
controller.enqueue({
type: "tool-input-start",
id: toolCall.toolCallId,
toolName: toolCall.toolName,
providerExecuted: toolCall.providerExecuted,
dynamic: toolCall.dynamic,
providerMetadata: toolCall.providerMetadata
});
controller.enqueue({
type: "tool-input-delta",
id: toolCall.toolCallId,
delta: toolCall.input,
providerMetadata: toolCall.providerMetadata
});
controller.enqueue({
type: "tool-input-end",
id: toolCall.toolCallId,
providerMetadata: toolCall.providerMetadata
});
controller.enqueue(toolCall);
} else if (message.type === "tool-result") {
const toolResult = message;
const meta = toolCallMeta[toolResult.toolCallId];
if (meta?.providerExecuted) {
controller.enqueue({ ...toolResult, providerExecuted: meta.providerExecuted });
} else {
controller.enqueue(message);
}
} else if (message.type === "text") {
const text = message;
const id = `msg_${randomUUID()}`;
controller.enqueue({
type: "text-start",
id,
providerMetadata: text.providerMetadata
});
controller.enqueue({
type: "text-delta",
id,
delta: text.text
});
controller.enqueue({
type: "text-end",
id
});
} else if (message.type === "reasoning") {
const id = `reasoning_${randomUUID()}`;
const reasoning = message;
controller.enqueue({
type: "reasoning-start",
id,
providerMetadata: reasoning.providerMetadata
});
controller.enqueue({
type: "reasoning-delta",
id,
delta: reasoning.text,
providerMetadata: reasoning.providerMetadata
});
controller.enqueue({
type: "reasoning-end",
id,
providerMetadata: reasoning.providerMetadata
});
} else if (message.type === "file") {
const file = message;
controller.enqueue({
type: "file",
mediaType: file.mediaType,
data: file.data
});
} else if (message.type === "source") {
const source = message;
if (source.sourceType === "url") {
controller.enqueue({
type: "source",
id: source.id,
sourceType: "url",
url: source.url,
title: source.title,
providerMetadata: source.providerMetadata
});
} else {
controller.enqueue({
type: "source",
id: source.id,
sourceType: "document",
mediaType: source.mediaType,
filename: source.filename,
title: source.title,
providerMetadata: source.providerMetadata
});
}
}
}
controller.enqueue({
type: "finish",
finishReason: result.finishReason,
usage: result.usage,
providerMetadata: result.providerMetadata
});
controller.close();
}
});
}
// src/llm/model/aisdk/v5/model.ts
function applyStrictForV2(options) {
if (!options.tools?.length) {
return options;
}
let hasStrictTool = false;
const sanitizedTools = options.tools.map((tool) => {
if (tool.type !== "function" || !("strict" in tool)) {
return tool;
}
if (tool.strict === true) {
hasStrictTool = true;
}
const { strict: _strict, ...rest } = tool;
return rest;
});
let result = {
...options,
tools: sanitizedTools
};
if (hasStrictTool) {
const existingOpenai = options.providerOptions?.openai ?? {};
if (existingOpenai.strictJsonSchema == null) {
result = {
...result,
providerOptions: {
...options.providerOptions,
openai: {
...existingOpenai,
strictJsonSchema: true
}
}
};
}
}
return result;
}
var AISDKV5LanguageModel = class {
/**
* The language model must specify which language model interface version it implements.
*/
specificationVersion = "v2";
/**
* Name of the provider for logging purposes.
*/
provider;
/**
* Provider-specific model ID for logging purposes.
*/
modelId;
gatewayId;
/**
* Supported URL patterns by media type for the provider.
*
* The keys are media type patterns or full media types (e.g. `*\/*` for everything, `audio/*`, `video/*`, or `application/pdf`).
* and the values are arrays of regular expressions that match the URL paths.
* The matching should be against lower-case URLs.
* Matched URLs are supported natively by the model and are not downloaded.
* @returns A map of supported URL patterns by media type (as a promise or a plain object).
*/
supportedUrls;
#model;
constructor(config) {
this.#model = config;
this.provider = this.#model.provider;
this.modelId = this.#model.modelId;
this.gatewayId = config.gatewayId;
this.supportedUrls = this.#model.supportedUrls;
}
async doGenerate(options) {
const result = await this.#model.doGenerate(applyStrictForV2(options));
return {
...result,
request: result.request,
response: result.response,
stream: createStreamFromGenerateResult(result)
};
}
async doStream(options) {
return await this.#model.doStream(applyStrictForV2(options));
}
/**
* Custom serialization for tracing/observability spans.
* `#model` is already a true JS private field and not enumerable, so
* the wrapped provider SDK client can't leak. This method makes the
* safe shape explicit and avoids walking `supportedUrls` (a
* PromiseLike / regex map that isn't useful in spans).
*/
serializeForSpan() {
return {
specificationVersion: this.specificationVersion,
modelId: this.modelId,
provider: this.provider,
gatewayId: this.gatewayId
};
}
};
export { AISDKV5LanguageModel, MastraLLMV1, createStreamFromGenerateResult };
//# sourceMappingURL=chunk-7U3XH5CC.js.map
//# sourceMappingURL=chunk-7U3XH5CC.js.map