import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres"; import { isAIMessage, isHumanMessage,isToolMessage } from "@langchain/core/messages"; import graph from "./graph.js"; import { ulid } from "ulid"; const checkpointer = PostgresSaver.fromConnString('postgres://postgres:eMd9hliASrN1yuNOYSk7LtOdlLRnnlnhUF31JKww6zQ=@supabase-pgdb-1:5432/solana'); 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; }; const thread_id = `did:privy:cm6uxey3z00852ix3h40ixj7c-acvcvcvfsssssd`; 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; } checkpointToVercelAI(thread_id);