You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ai-net/server/tools.ts

108 lines
3.1 KiB
TypeScript

import {
streamText,
generateText,
generateObject,
type Message,
jsonSchema,
} from "ai";
import { getAgentById, openrouter } from "./agentRegistry.js";
// Define the tools with explicit type
export interface DelegateParams {
agentId?: string;
prompt?: string;
[key: string]: any;
}
export interface EchoParams {
message: string;
}
interface ToolFunctions {
[key: string]: (params: any) => Promise<string>;
}
const tools: ToolFunctions = {
delegate: async function ({
agentId,
prompt,
}: DelegateParams): Promise<string> {
// Validate required parameters
if (!agentId || !prompt) {
return "Error: Missing required parameters. Both 'agentId' and 'prompt' are required.";
}
// Find the target agent
const agent = getAgentById(agentId);
if (!agent) {
return `Error: No such agent: ${agentId}`;
}
try {
const conversation: { messages: Array<Omit<Message, "id">> } = {
messages: [
{ role: "system", content: agent.systemMessage },
{ role: "user", content: prompt },
],
};
let isConversationDone = false;
while (!isConversationDone) {
// Generate a response from the agent using the prompt
const result = await generateText({
model: openrouter(agent.modelName),
messages: conversation.messages,
tools: agent.tools,
});
conversation.messages.push({ role: "assistant", content: result.text });
const sentimentIsConversationDone = await generateObject<{
isConversationDone: boolean;
}>({
model: openrouter("mistralai/mistral-nemo"),
messages: [
{
role: "system",
content:
"You are a tool to determine whether a conversation is done or should continue with another reply.",
},
{
role: "user",
content: conversation.messages
.map((message) => `${message.role}: ${message.content}`)
.join("\n"),
},
],
schema: jsonSchema({
type: "object",
properties: {
isConversationDone: {
type: "boolean",
description:
"Whether the conversation is done or should continue and requires a reply.",
},
},
}),
});
isConversationDone =
sentimentIsConversationDone.object.isConversationDone;
}
// const summaryText = await generateSummary();
// // Return the agent's response
// return summaryText;
return conversation.messages
.map((message) => `${message.role}: ${message.content}`)
.join("\n");
} catch (error: unknown) {
const errorMessage =
error instanceof Error ? error.message : "Unknown error";
console.error("Error delegating to agent:", error);
return `Error delegating to agent ${agentId}: ${errorMessage}`;
}
},
echo: async function ({ message }: EchoParams): Promise<string> {
return message;
},
};
export default tools;