@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
259 lines (255 loc) • 9.7 kB
JavaScript
import { Agent, isSupportedLanguageModel } from './chunk-AM3IOVFX.js';
import { resolveModelConfig } from './chunk-7SS36SRG.js';
import { generateId } from './chunk-7PQ4WG3V.js';
import { ToolLoopAgent } from './chunk-5THMFV44.js';
// src/tool-loop-agent/utils.ts
function isToolLoopAgentLike(obj) {
if (!obj) return false;
if (obj instanceof ToolLoopAgent) return true;
return "version" in obj && typeof obj.version === "string" && (obj.version === "agent-v1" || obj.version.startsWith("agent-v"));
}
function getSettings(agent) {
const settings = agent.settings;
if (!settings) {
throw new Error("Could not extract settings from ToolLoopAgent. The agent may be from an incompatible version.");
}
return settings;
}
// src/tool-loop-agent/tool-loop-processor.ts
var ToolLoopAgentProcessor = class {
id = "tool-loop-agent-processor";
name = "ToolLoop to Mastra Agent Processor";
agent;
settings;
prepareCallResult;
constructor(agent) {
this.agent = agent;
this.settings = getSettings(agent);
}
getAgentConfig() {
const tools = "tools" in this.agent ? this.agent.tools : void 0;
const defaultOptions = {};
if (this.settings.toolChoice) {
defaultOptions.toolChoice = this.settings.toolChoice;
}
if (this.settings.providerOptions) {
defaultOptions.providerOptions = this.settings.providerOptions;
}
if (this.settings.temperature !== void 0) {
defaultOptions.modelSettings = {
...defaultOptions.modelSettings ?? {},
temperature: this.settings.temperature
};
}
if (this.settings.topP !== void 0) {
defaultOptions.modelSettings = { ...defaultOptions.modelSettings ?? {}, topP: this.settings.topP };
}
if (this.settings.topK !== void 0) {
defaultOptions.modelSettings = { ...defaultOptions.modelSettings ?? {}, topK: this.settings.topK };
}
if (this.settings.seed !== void 0) {
defaultOptions.modelSettings = { ...defaultOptions.modelSettings ?? {}, seed: this.settings.seed };
}
if (this.settings.maxOutputTokens !== void 0) {
defaultOptions.modelSettings = {
...defaultOptions.modelSettings ?? {},
maxOutputTokens: this.settings.maxOutputTokens
};
}
if (this.settings.presencePenalty !== void 0) {
defaultOptions.modelSettings = {
...defaultOptions.modelSettings ?? {},
presencePenalty: this.settings.presencePenalty
};
}
if (this.settings.frequencyPenalty !== void 0) {
defaultOptions.modelSettings = {
...defaultOptions.modelSettings ?? {},
frequencyPenalty: this.settings.frequencyPenalty
};
}
if (this.settings.stopSequences !== void 0) {
defaultOptions.modelSettings = {
...defaultOptions.modelSettings ?? {},
stopSequences: this.settings.stopSequences
};
}
if (this.settings.stopWhen) {
defaultOptions.stopWhen = this.settings.stopWhen;
}
if (this.settings.onStepFinish) {
defaultOptions.onStepFinish = this.settings.onStepFinish;
}
if (this.settings.onFinish) {
defaultOptions.onFinish = this.settings.onFinish;
}
return {
id: this.settings.id,
name: this.settings.id,
instructions: this.settings.instructions ?? "",
model: this.settings.model,
tools,
maxRetries: this.settings.maxRetries,
defaultOptions: Object.keys(defaultOptions).length > 0 ? defaultOptions : void 0
};
}
/**
* Maps prepareCall or prepareStep result to ProcessInputStepResult.
* Both hooks return similar structures that can override model, tools, activeTools, etc.
*/
mapToProcessInputStepResult(result) {
if (!result) {
return {};
}
const stepResult = {};
if (result.model) {
stepResult.model = result.model;
}
if ("tools" in result && result.tools) {
stepResult.tools = result.tools;
}
if ("toolChoice" in result && result.toolChoice !== void 0) {
stepResult.toolChoice = result.toolChoice;
}
if (result.activeTools) {
stepResult.activeTools = result.activeTools;
}
if ("providerOptions" in result && result.providerOptions) {
stepResult.providerOptions = result.providerOptions;
}
const modelSettings = {};
if ("temperature" in result && result.temperature !== void 0) {
modelSettings.temperature = result.temperature;
}
if ("topP" in result && result.topP !== void 0) {
modelSettings.topP = result.topP;
}
if ("topK" in result && result.topK !== void 0) {
modelSettings.topK = result.topK;
}
if ("maxOutputTokens" in result && result.maxOutputTokens !== void 0) {
modelSettings.maxOutputTokens = result.maxOutputTokens;
}
if ("presencePenalty" in result && result.presencePenalty !== void 0) {
modelSettings.presencePenalty = result.presencePenalty;
}
if ("frequencyPenalty" in result && result.frequencyPenalty !== void 0) {
modelSettings.frequencyPenalty = result.frequencyPenalty;
}
if ("stopSequences" in result && result.stopSequences !== void 0) {
modelSettings.stopSequences = result.stopSequences;
}
if ("seed" in result && result.seed !== void 0) {
modelSettings.seed = result.seed;
}
if (Object.keys(modelSettings).length > 0) {
stepResult.modelSettings = modelSettings;
}
const systemContent = "instructions" in result ? result.instructions : "system" in result ? result.system : void 0;
if (systemContent) {
if (typeof systemContent === "string") {
stepResult.systemMessages = [{ role: "system", content: systemContent }];
} else if (Array.isArray(systemContent)) {
stepResult.systemMessages = systemContent.map(
(msg) => typeof msg === "string" ? { role: "system", content: msg } : msg
);
} else if (typeof systemContent === "object" && "role" in systemContent && "content" in systemContent) {
stepResult.systemMessages = [systemContent];
}
}
if ("messages" in result && result.messages && Array.isArray(result.messages)) {
stepResult.messages = result.messages;
}
return stepResult;
}
async handlePrepareCall(args) {
if (this.settings.prepareCall) {
const { model, messages, activeTools, providerOptions, modelSettings, tools } = args;
const prepareCallInput = {
// TODO: prepareCall expects messages in AI SDK format, we have them in Mastra format
messages,
model,
tools,
instructions: this.settings.instructions,
stopWhen: this.settings.stopWhen,
activeTools,
providerOptions,
// Model settings
temperature: modelSettings?.temperature,
topP: modelSettings?.topP,
topK: modelSettings?.topK,
maxOutputTokens: modelSettings?.maxOutputTokens,
presencePenalty: modelSettings?.presencePenalty,
frequencyPenalty: modelSettings?.frequencyPenalty,
stopSequences: modelSettings?.stopSequences,
seed: modelSettings?.seed
// Experimental options
// experimental_telemetry: this.settings.experimental_telemetry,
// experimental_context: this.settings.experimental_context,
// experimental_download: this.settings.experimental_download,
};
const prepareCallResult = await this.settings.prepareCall(prepareCallInput);
this.prepareCallResult = prepareCallResult;
}
}
async handlePrepareStep(args, currentResult) {
if (this.settings.prepareStep) {
const { messages, steps, stepNumber } = args;
let model = args.model;
if (currentResult.model) {
const resolvedModel = await resolveModelConfig(currentResult.model);
if (!isSupportedLanguageModel(resolvedModel)) {
throw new Error("prepareStep returned an unsupported model version");
}
model = resolvedModel;
}
const prepareStepInputArgs = {
model,
// Messages are in Mastra format (MastraDBMessage[])
messages,
// Steps may have minor type differences in usage properties (inputTokenDetails/outputTokenDetails)
steps,
stepNumber,
experimental_context: void 0
};
const prepareStepResult = await this.settings.prepareStep(prepareStepInputArgs);
return prepareStepResult;
}
}
async processInputStep(args) {
const { stepNumber } = args;
if (stepNumber === 0 && this.settings.prepareCall) {
await this.handlePrepareCall(args);
}
let result = {};
if (this.prepareCallResult) {
const mappedResult = this.mapToProcessInputStepResult(this.prepareCallResult);
if (Object.keys(mappedResult).length > 0) {
result = { ...result, ...mappedResult };
}
}
if (this.settings.prepareStep) {
const prepareStepResult = await this.handlePrepareStep(args, result);
if (prepareStepResult) {
const mappedResult = this.mapToProcessInputStepResult(prepareStepResult);
result = { ...result, ...mappedResult };
}
}
return result;
}
};
// src/tool-loop-agent/index.ts
function toolLoopAgentToMastraAgent(agent, options) {
const processor = new ToolLoopAgentProcessor(agent);
const agentConfig = processor.getAgentConfig();
const id = agentConfig.id || options?.fallbackName || `tool-loop-agent-${generateId()}`;
return new Agent({
...agentConfig,
id,
name: agentConfig.name || id,
inputProcessors: [processor]
});
}
export { getSettings, isToolLoopAgentLike, toolLoopAgentToMastraAgent };
//# sourceMappingURL=chunk-L4BINS4U.js.map
//# sourceMappingURL=chunk-L4BINS4U.js.map