@ai-sdk/swarm
Version:
> **Warning** > This is an experimental package. It is not maintained and the API is not stable.
138 lines (137 loc) • 4.45 kB
JavaScript
// src/agent.ts
function functionTool(tool) {
return tool;
}
function handoverTool(tool) {
return tool;
}
var Agent = class {
constructor(options) {
this.name = options.name;
this.model = options.model;
this.system = options.system;
this.tools = options.tools;
this.toolChoice = options.toolChoice;
}
};
// src/run-swarm.ts
import {
generateText
} from "ai";
import { z } from "zod";
async function runSwarm({
agent: activeAgent,
prompt,
context,
model,
maxSteps = 100,
toolChoice,
debug = false,
onStepFinish
// TODO include agent information
}) {
var _a, _b, _c, _d, _e, _f;
const initialMessages = typeof prompt === "string" ? [{ role: "user", content: prompt }] : prompt;
let lastResult;
const responseMessages = [];
do {
lastResult = await generateText({
model: (_a = activeAgent.model) != null ? _a : model,
system: typeof activeAgent.system === "function" ? activeAgent.system(context) : activeAgent.system,
tools: Object.fromEntries(
Object.entries((_b = activeAgent.tools) != null ? _b : {}).map(
([name, tool]) => [
name,
tool.type === "handover" ? {
type: "function",
description: tool.description,
parameters: z.object({})
// no execute function
} : {
type: "function",
description: tool.description,
parameters: tool.parameters,
execute: (args, { abortSignal }) => tool.execute(args, { context, abortSignal })
}
]
)
),
maxSteps,
toolChoice: (_c = activeAgent.toolChoice) != null ? _c : toolChoice,
onStepFinish,
messages: [...initialMessages, ...responseMessages]
});
responseMessages.push(...lastResult.response.messages);
if (lastResult.finishReason !== "tool-calls") {
break;
}
const { toolCalls, toolResults } = lastResult;
const toolResultIds = toolResults.map((result) => result.toolCallId);
const unhandledToolCalls = toolCalls.filter(
(toolCall) => !toolResultIds.includes(toolCall.toolCallId)
);
const handoverCalls = unhandledToolCalls.filter(
(toolCall) => {
var _a2;
return ((_a2 = activeAgent.tools) == null ? void 0 : _a2[toolCall.toolName].type) === "handover";
}
);
let handoverToolResult = void 0;
if (handoverCalls.length > 0) {
const handoverTool2 = (_d = activeAgent.tools) == null ? void 0 : _d[handoverCalls[0].toolName];
const result = handoverTool2.execute(handoverCalls[0].args, {
context
});
activeAgent = result.agent;
context = (_e = result.context) != null ? _e : context;
if (debug) {
console.log(`\x1B[36mHanding over to agent ${activeAgent.name}\x1B[0m`);
if (result.context != null) {
console.log(
`\x1B[36mUpdated context: ${JSON.stringify(
result.context,
null,
2
)}\x1B[0m`
);
}
}
handoverToolResult = {
type: "tool-result",
toolCallId: handoverCalls[0].toolCallId,
toolName: handoverCalls[0].toolName,
result: `Handing over to agent ${activeAgent.name}`
};
}
const toolMessage = ((_f = responseMessages.at(-1)) == null ? void 0 : _f.role) === "tool" ? responseMessages.at(-1) : void 0;
const assistantMessage = responseMessages.at(
toolMessage === void 0 ? -1 : -2
);
if (handoverToolResult != null) {
if (toolMessage == null) {
responseMessages.push({ role: "tool", content: [handoverToolResult] });
} else {
toolMessage.content.push(handoverToolResult);
}
}
if (typeof assistantMessage.content !== "string") {
const unusedToolCallIds = handoverCalls.filter((call, index) => index > 0).map((call) => call.toolCallId);
assistantMessage.content = assistantMessage.content.filter((part) => {
return part.type === "tool-call" ? !unusedToolCallIds.includes(part.toolCallId) : true;
});
}
} while (responseMessages.filter((message) => message.role === "assistant").length < maxSteps);
return {
responseMessages,
activeAgent,
text: lastResult.text,
finishReason: lastResult.finishReason
};
}
export {
Agent,
functionTool,
handoverTool,
runSwarm
};
//# sourceMappingURL=index.mjs.map