|
|
|
@ -1,4 +1,10 @@
|
|
|
|
|
import { streamText } from "ai";
|
|
|
|
|
import {
|
|
|
|
|
streamText,
|
|
|
|
|
generateText,
|
|
|
|
|
generateObject,
|
|
|
|
|
type Message,
|
|
|
|
|
jsonSchema,
|
|
|
|
|
} from "ai";
|
|
|
|
|
import { getAgentById, openrouter } from "./agentRegistry.js";
|
|
|
|
|
|
|
|
|
|
// Define the tools with explicit type
|
|
|
|
@ -33,26 +39,59 @@ const tools: ToolFunctions = {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Generate a response from the agent using the prompt
|
|
|
|
|
const result = streamText({
|
|
|
|
|
model: openrouter(agent.modelName),
|
|
|
|
|
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,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Collect the response text
|
|
|
|
|
let responseText = "";
|
|
|
|
|
|
|
|
|
|
// The textStream is already an AsyncIterable, no need to call it as a function
|
|
|
|
|
for await (const chunk of result.textStream) {
|
|
|
|
|
responseText += chunk;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return the agent's response
|
|
|
|
|
return responseText;
|
|
|
|
|
// 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";
|
|
|
|
|