147 lines
3.9 KiB
JavaScript
147 lines
3.9 KiB
JavaScript
import { isAIMessage, isHumanMessage,isToolMessage } from "@langchain/core/messages";
|
|
import graph from "@/server/graph";
|
|
import checkpointer from "@/server/checkpointer";
|
|
import { ulid } from "ulid";
|
|
|
|
|
|
const interrupterMessageCreator = (id, toolCalls) => {
|
|
const template = {
|
|
id: id,
|
|
createdAt: new Date().toISOString(),
|
|
role: "assistant",
|
|
content: "",
|
|
parts: [
|
|
{
|
|
type: "tool-invocation",
|
|
toolInvocation: {
|
|
state: "result",
|
|
step: 0,
|
|
toolCallId: "interrupter",
|
|
toolName: "interrupter",
|
|
args: {
|
|
toolCalls: toolCalls,
|
|
},
|
|
result: "Your input is required to proceed",
|
|
},
|
|
},
|
|
],
|
|
toolInvocations: [
|
|
{
|
|
state: "result",
|
|
step: 0,
|
|
toolCallId: "01JM87QQ72ZDYY01389N4JTV6P",
|
|
toolName: "interrupter",
|
|
args: {
|
|
toolCalls: toolCalls,
|
|
},
|
|
result: "Your input is required to proceed",
|
|
},
|
|
],
|
|
revisionId: ulid(),
|
|
};
|
|
return template;
|
|
};
|
|
|
|
const humanMessageCreator = (message) => {
|
|
const template = {
|
|
id: message.id,
|
|
createdAt: new Date().toISOString(),
|
|
role: "user",
|
|
content: message.content,
|
|
parts: [
|
|
{
|
|
type: "text",
|
|
text: message.content,
|
|
},
|
|
],
|
|
};
|
|
return template;
|
|
};
|
|
|
|
const aiMessageCreator = (id, content, tools) => {
|
|
const template = {
|
|
id: id,
|
|
createdAt: new Date().toISOString(),
|
|
role: "assistant",
|
|
content: content,
|
|
parts: [],
|
|
revisionId: ulid(),
|
|
};
|
|
if (tools.length != 0) {
|
|
template.toolInvocations = tools;
|
|
}
|
|
|
|
tools.forEach((tool) => {
|
|
template.parts.push({
|
|
type: "tool-invocation",
|
|
toolInvocation: tool,
|
|
});
|
|
});
|
|
|
|
template.parts.push({
|
|
type: "text",
|
|
text: content,
|
|
});
|
|
|
|
return template;
|
|
};
|
|
|
|
const toolMessageCreator = (message, step) => {
|
|
const template = {
|
|
state: "result",
|
|
step: step,
|
|
toolCallId: message.tool_call_id,
|
|
toolName: message.name,
|
|
args: message.artifact ? { artifact: message.artifact } : {},
|
|
result: message.content,
|
|
};
|
|
|
|
return template;
|
|
};
|
|
|
|
export async function checkpointToVercelAI(thread_id) {
|
|
const config = { configurable: { thread_id } };
|
|
const checkpointerData = await checkpointer.get(config);
|
|
const vercel_messages = [
|
|
{
|
|
id: "1",
|
|
content: "Hi! How can i assist you today?",
|
|
role: "assistant",
|
|
},
|
|
];
|
|
|
|
if (!checkpointerData) {
|
|
return vercel_messages;
|
|
}
|
|
let tools_grouped = [];
|
|
|
|
for (const message of checkpointerData.channel_values.messages) {
|
|
if (isHumanMessage(message)) {
|
|
vercel_messages.push(humanMessageCreator(message));
|
|
} else if (isToolMessage(message)) {
|
|
tools_grouped.push(toolMessageCreator(message, tools_grouped.length));
|
|
} else if (isAIMessage(message) && message.content != "") {
|
|
vercel_messages.push(aiMessageCreator(message.id, message.content, tools_grouped));
|
|
tools_grouped = [];
|
|
}
|
|
}
|
|
|
|
if (typeof checkpointerData?.channel_values === "object" && "branch:agent:condition:checkApproval" in checkpointerData.channel_values) {
|
|
let interrupterTool;
|
|
for await (const event of await graph.stream(null, config)) {
|
|
interrupterTool = event.__interrupt__;
|
|
}
|
|
const toolCalls = interrupterTool[0].value.map((tool) => ({
|
|
id: tool.id,
|
|
name: tool.name,
|
|
args: Object.fromEntries(Object.entries(tool.args).filter(([key]) => key !== "debug")),
|
|
}));
|
|
|
|
const id = interrupterTool[0].ns[0];
|
|
const interruptMessage = interrupterMessageCreator(id, toolCalls);
|
|
vercel_messages.push(interruptMessage);
|
|
}
|
|
|
|
return vercel_messages;
|
|
}
|
|
|