diff --git a/app/agent_hil/page.tsx b/app/agent_hil/page.tsx new file mode 100644 index 0000000..a009cf9 --- /dev/null +++ b/app/agent_hil/page.tsx @@ -0,0 +1,88 @@ +import { ChatWindow } from "@/components/ChatWindow"; + +export default function AgentsPage() { + const InfoCard = ( +
+

+ ▲ Next.js + LangChain.js Agents 🦜🔗 +

+ +
+ ); + return ( + + ); +} diff --git a/app/api/chat/agent_hil/agent_creator.ts b/app/api/chat/agent_hil/agent_creator.ts new file mode 100644 index 0000000..f6ecee5 --- /dev/null +++ b/app/api/chat/agent_hil/agent_creator.ts @@ -0,0 +1,153 @@ +import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres"; +import { pool } from "@/app/lib/db"; + +import { z } from "zod"; + +import { + Annotation, + Command, + MessagesAnnotation, + StateGraph, + interrupt, +} from "@langchain/langgraph"; +import { ChatPromptTemplate } from "@langchain/core/prompts"; +import { ChatOpenAI } from "@langchain/openai"; +import { AIMessage, HumanMessage } from "@langchain/core/messages"; + +const GraphAnnotation = Annotation.Root({ + ...MessagesAnnotation.spec, + // isResuming is very useful if you want to ignore some workflow in some node + // that you want to ignore when the graph is resuming the run for the first time + // after interrupt happened + isResuming: Annotation({ + reducer: (currentState, updateValue) => updateValue, + default: () => false, + }), + gotoNext: Annotation({ + reducer: (currentState, updateValue) => updateValue, + default: () => "", + }), +}); + +const MainAgentChatPrompt = ChatPromptTemplate.fromMessages([ + ["system", `You're a helpful assistant.`], + ["placeholder", "{chat_history}"], +]); + +const mainAgent = async (state: typeof GraphAnnotation.State) => { + const { messages } = state; + + const structuredOutput = z.object({ + goto: z + .enum(["weatherAgent", "calculatorAgent", "mainAgent"]) + .describe( + "The next agent to run after user confirmation" + + "weatherAgent helps with weather queries" + + "calculatorAgent helps with calculations" + + "mainAgent is the main agent that handles the user's message", + ), + response: z.string().describe("Human readable response to user's message"), + }); + + const input = await MainAgentChatPrompt.invoke({ chat_history: messages }); + + const model = new ChatOpenAI({ + model: "gpt-4o-mini", + temperature: 0, + }); + + const response = await model + .withStructuredOutput(structuredOutput) + .invoke(input); + + return new Command({ + goto: "humanNode", + update: { + messages: [new AIMessage(response.response)], + gotoNext: response.goto, + }, + }); +}; + +const humanNode = async (state: typeof GraphAnnotation.State) => { + const { gotoNext } = state; + + // we're not using the object here. we ask for string feedback. + const input = await interrupt<{}, string>({}); + + if (input === "yes" || input === "y") { + return new Command({ + goto: gotoNext, + update: { + messages: [new HumanMessage(input)], + gotoNext: "", // reset the gotoNext + isResuming: false, + }, + }); + } + + return new Command({ + goto: "mainAgent", + update: { + messages: [new HumanMessage(input)], + gotoNext: "", // reset the gotoNext + }, + }); +}; + +const weatherAgent = async (state: typeof GraphAnnotation.State) => { + // sleep for 2 seconds to simulate weather agent + await new Promise((resolve) => setTimeout(resolve, 2000)); + + const weather = "It's sunny and 70 degrees"; + + return new Command({ + goto: "mainAgent", + update: { + messages: [new AIMessage(weather)], + }, + }); +}; + +const calculatorAgent = async (state: typeof GraphAnnotation.State) => { + const calculator = "The answer is 42"; + + return new Command({ + goto: "mainAgent", + update: { + messages: [new AIMessage(calculator)], + }, + }); +}; + +export const setupCheckpointer = async (): Promise => { + const checkpointer = new PostgresSaver(pool); + + // NOTE: you need to call .setup() the first time you're using your checkpointer + await checkpointer.setup(); +}; + +export const createAgent = () => { + // Initialize the checkpointer with the database pool + const checkpointer = new PostgresSaver(pool); + + // Build graph. + const graph = new StateGraph(GraphAnnotation) + .addNode("mainAgent", mainAgent, { + ends: ["humanNode", "weatherAgent", "calculatorAgent"], + }) + .addNode("humanNode", humanNode, { + ends: ["mainAgent", "weatherAgent", "calculatorAgent"], + }) + .addNode("weatherAgent", weatherAgent, { + ends: ["mainAgent"], + }) + .addNode("calculatorAgent", calculatorAgent, { + ends: ["mainAgent"], + }) + .addEdge("__start__", "mainAgent"); + + return graph.compile({ + checkpointer, + }); +}; diff --git a/app/api/chat/agent_hil/route.ts b/app/api/chat/agent_hil/route.ts new file mode 100644 index 0000000..89aead1 --- /dev/null +++ b/app/api/chat/agent_hil/route.ts @@ -0,0 +1,135 @@ +import { NextRequest, NextResponse } from "next/server"; +import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; + +import { + AIMessage, + BaseMessage, + ChatMessage, + HumanMessage, +} from "@langchain/core/messages"; +import { createAgent } from "./agent_creator"; +import { Command } from "@langchain/langgraph"; + +const convertVercelMessageToLangChainMessage = (message: VercelChatMessage) => { + if (message.role === "user") { + return new HumanMessage(message.content); + } else if (message.role === "assistant") { + return new AIMessage(message.content); + } else { + return new ChatMessage(message.content, message.role); + } +}; + +const convertLangChainMessageToVercelMessage = (message: BaseMessage) => { + if (message._getType() === "human") { + return { content: message.content, role: "user" }; + } else if (message._getType() === "ai") { + return { + content: message.content, + role: "assistant", + tool_calls: (message as AIMessage).tool_calls, + }; + } else { + return { content: message.content, role: message._getType() }; + } +}; + +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + const returnIntermediateSteps = body.show_intermediate_steps; + /** + * We represent intermediate steps as system messages for display purposes, + * but don't want them in the chat history. + */ + const messages = (body.messages ?? []) + .filter( + (message: VercelChatMessage) => + message.role === "user" || message.role === "assistant", + ) + .map(convertVercelMessageToLangChainMessage); + + // Setup checkpointer DO THIS ONCE if you haven't. + // await setupCheckpointer(); + + const agent = createAgent(); + + const threadId = "1999"; // TODO: get from request + + // Get the agent state, check whether the agent can be resumed. + const state = await agent.getState({ + configurable: { thread_id: threadId }, + }); + + const isBeginning = + state.next.length === 0 && Object.keys(state.values).length === 0; + + let runInput: { messages: (AIMessage | HumanMessage)[] } | Command = + new Command({ + resume: messages.findLast((m: any) => m.role === "user")?.content, + update: { + isResuming: true, // Important if you have workflows that you want to ignore when resuming + }, + }); + + if (isBeginning) { + runInput = { + messages, + }; + } + + if (!returnIntermediateSteps) { + /** + * Stream back all generated tokens and steps from their runs. + * + * We do some filtering of the generated events and only stream back + * the final response as a string. + * + * For this specific type of tool calling ReAct agents with OpenAI, we can tell when + * the agent is ready to stream back final output when it no longer calls + * a tool and instead streams back content. + * + * See: https://langchain-ai.github.io/langgraphjs/how-tos/stream-tokens/ + */ + const eventStream = await agent.streamEvents(runInput, { + version: "v2", + configurable: { thread_id: threadId }, + }); + + const textEncoder = new TextEncoder(); + const transformStream = new ReadableStream({ + async start(controller) { + for await (const { event, data } of eventStream) { + if (event === "on_chat_model_stream") { + // Intermediate chat model generations will contain tool calls and no content + if (!!data.chunk.content) { + controller.enqueue(textEncoder.encode(data.chunk.content)); + } + } + } + controller.close(); + }, + }); + + return new StreamingTextResponse(transformStream); + } else { + /** + * We could also pick intermediate steps out from `streamEvents` chunks, but + * they are generated as JSON objects, so streaming and displaying them with + * the AI SDK is more complicated. + */ + const result = await agent.invoke(runInput, { + configurable: { thread_id: threadId }, + }); + + return NextResponse.json( + { + messages: result.messages.map(convertLangChainMessageToVercelMessage), + }, + { status: 200 }, + ); + } + } catch (e: any) { + return NextResponse.json({ error: e.message }, { status: e.status ?? 500 }); + } +} diff --git a/app/lib/db.ts b/app/lib/db.ts new file mode 100644 index 0000000..ecae75b --- /dev/null +++ b/app/lib/db.ts @@ -0,0 +1,8 @@ +import { Pool } from "pg"; + +export const pool = new Pool({ + connectionString: process.env.DATABASE_URL, + ssl: { + rejectUnauthorized: false, + }, +}); diff --git a/package.json b/package.json index 9464f07..6ac8be3 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,9 @@ }, "dependencies": { "@langchain/community": "^0.3.11", - "@langchain/core": "^0.3.17", - "@langchain/langgraph": "^0.2.20", + "@langchain/core": "^0.3.27", + "@langchain/langgraph": "^0.2.39", + "@langchain/langgraph-checkpoint-postgres": "^0.0.2", "@langchain/openai": "^0.3.11", "@next/bundle-analyzer": "^13.4.19", "@supabase/supabase-js": "^2.32.0", @@ -28,6 +29,7 @@ "eslint-config-next": "13.4.12", "langchain": "^0.3.5", "next": "^14.2.3", + "pg": "^8.13.1", "postcss": "8.4.27", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -38,6 +40,7 @@ "zod-to-json-schema": "^3.21.4" }, "devDependencies": { + "@types/pg": "^8.11.10", "prettier": "3.0.0" }, "packageManager": "yarn@3.5.1" diff --git a/yarn.lock b/yarn.lock index 305860f..c19e523 100644 --- a/yarn.lock +++ b/yarn.lock @@ -122,6 +122,13 @@ __metadata: languageName: node linkType: hard +"@cfworker/json-schema@npm:^4.0.2": + version: 4.0.3 + resolution: "@cfworker/json-schema@npm:4.0.3" + checksum: e99d82b740a44442be64e2ab06e2e39a11cca2093ea89eda438c4d47140f4845104c725949cea065aa9e834ba2379f02b6dfe62e30b6ecdbfc94e5e6e73abb70 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -628,59 +635,72 @@ __metadata: languageName: node linkType: hard -"@langchain/core@npm:^0.3.17": - version: 0.3.17 - resolution: "@langchain/core@npm:0.3.17" +"@langchain/core@npm:^0.3.27": + version: 0.3.27 + resolution: "@langchain/core@npm:0.3.27" dependencies: + "@cfworker/json-schema": ^4.0.2 ansi-styles: ^5.0.0 camelcase: 6 decamelize: 1.2.0 js-tiktoken: ^1.0.12 - langsmith: ^0.2.0 + langsmith: ^0.2.8 mustache: ^4.2.0 p-queue: ^6.6.2 p-retry: 4 uuid: ^10.0.0 zod: ^3.22.4 zod-to-json-schema: ^3.22.3 - checksum: a240965948b2cfc4df4fb76de21d9d1bc9ec0f878db1ea265588e0086c9aff511600bfafc668d71a24dc17b73e335a7a41cd5767779c800f4ab9963fc8b2c730 + checksum: 416077ab412f25a9d40ab17b7a2c91b1cd5cf056e2148a72dba5e952575cdc15913ff17469cfd575d5a84a9ecdf326d4d6810c3eb03644b1a90531f0dd6f4c35 + languageName: node + linkType: hard + +"@langchain/langgraph-checkpoint-postgres@npm:^0.0.2": + version: 0.0.2 + resolution: "@langchain/langgraph-checkpoint-postgres@npm:0.0.2" + dependencies: + pg: ^8.12.0 + peerDependencies: + "@langchain/core": ">=0.2.31 <0.4.0" + "@langchain/langgraph-checkpoint": ~0.0.6 + checksum: 61f9782475b92c76a6e4f1905d362c13251a7025bba157e8051b38d8d0ecaf9efdb97ae9add60b968a157d9fdc8e0754752a9667e7a97e4cbf37093d8f9f832a languageName: node linkType: hard -"@langchain/langgraph-checkpoint@npm:~0.0.10": - version: 0.0.11 - resolution: "@langchain/langgraph-checkpoint@npm:0.0.11" +"@langchain/langgraph-checkpoint@npm:~0.0.13": + version: 0.0.13 + resolution: "@langchain/langgraph-checkpoint@npm:0.0.13" dependencies: uuid: ^10.0.0 peerDependencies: "@langchain/core": ">=0.2.31 <0.4.0" - checksum: 266803945782ca48bead72520125ae61333fe998b88e4c05d60a72758b324ea4e7adfad22195b7b1325c62bc2775ff335cc2e5488108eed93c45b188d4fc8fb1 + checksum: 721f6a99119e4445504d34d311f0c38c025ca65be04731c49915c08d6e7a2b5c9917b16e8c2f7b1ff9dd9f23ae56a4aa0918d902e0044ebdc8bf80704671163b languageName: node linkType: hard -"@langchain/langgraph-sdk@npm:~0.0.20": - version: 0.0.20 - resolution: "@langchain/langgraph-sdk@npm:0.0.20" +"@langchain/langgraph-sdk@npm:~0.0.32": + version: 0.0.33 + resolution: "@langchain/langgraph-sdk@npm:0.0.33" dependencies: "@types/json-schema": ^7.0.15 p-queue: ^6.6.2 p-retry: 4 uuid: ^9.0.0 - checksum: 0d3f1f887719bdaa3c75adb1409b734b0d3e240e92284ba90bfcf34443d2826f732ab7aab3db10f11b3e809d070566cc53d6cf1fa9660eacb2c2744da5b57cf3 + checksum: 0661144dc4a64944af615a178c51730099de8b5f7658df4549fd04fca45947e0d73db3a85fcd640c98ce918750b4fb914541b59d11387b4d34f7caef3113001e languageName: node linkType: hard -"@langchain/langgraph@npm:^0.2.20": - version: 0.2.20 - resolution: "@langchain/langgraph@npm:0.2.20" +"@langchain/langgraph@npm:^0.2.39": + version: 0.2.39 + resolution: "@langchain/langgraph@npm:0.2.39" dependencies: - "@langchain/langgraph-checkpoint": ~0.0.10 - "@langchain/langgraph-sdk": ~0.0.20 + "@langchain/langgraph-checkpoint": ~0.0.13 + "@langchain/langgraph-sdk": ~0.0.32 uuid: ^10.0.0 zod: ^3.23.8 peerDependencies: "@langchain/core": ">=0.2.36 <0.3.0 || >=0.3.9 < 0.4.0" - checksum: 94ea40e640fa4c060a69f3e04725b888142a36b73377087433c7513f77640ac8f6835564095029e1dd55bea421c7c6da8f440c963350205952b3c5ce1824e890 + checksum: 7c60ff39548842874d79b87473c00fb3b75f24a014e83af8363e1fd3cee2d6eb739bc199635c8af4edabbe31a0afb021dad9e5ecb37cc69644db154b9bd385db languageName: node linkType: hard @@ -1048,6 +1068,17 @@ __metadata: languageName: node linkType: hard +"@types/pg@npm:^8.11.10": + version: 8.11.10 + resolution: "@types/pg@npm:8.11.10" + dependencies: + "@types/node": "*" + pg-protocol: "*" + pg-types: ^4.0.1 + checksum: b2b481784e44429b284c7fc18121372f8afe747c3ada84aaff55de3aa07e205cecf18e8623c8b61860f8eeb499305bef8f934b62c9a1911bef3f8509febef071 + languageName: node + linkType: hard + "@types/phoenix@npm:^1.5.4": version: 1.6.5 resolution: "@types/phoenix@npm:1.6.5" @@ -3529,12 +3560,14 @@ __metadata: resolution: "langchain-nextjs-template@workspace:." dependencies: "@langchain/community": ^0.3.11 - "@langchain/core": ^0.3.17 - "@langchain/langgraph": ^0.2.20 + "@langchain/core": ^0.3.27 + "@langchain/langgraph": ^0.2.39 + "@langchain/langgraph-checkpoint-postgres": ^0.0.2 "@langchain/openai": ^0.3.11 "@next/bundle-analyzer": ^13.4.19 "@supabase/supabase-js": ^2.32.0 "@types/node": 20.12.12 + "@types/pg": ^8.11.10 "@types/react": 18.3.2 "@types/react-dom": 18.3.0 ai: ^3.1.12 @@ -3543,6 +3576,7 @@ __metadata: eslint-config-next: 13.4.12 langchain: ^0.3.5 next: ^14.2.3 + pg: ^8.13.1 postcss: 8.4.27 prettier: 3.0.0 react: ^18.3.1 @@ -3636,6 +3670,25 @@ __metadata: languageName: node linkType: hard +"langsmith@npm:^0.2.8": + version: 0.2.14 + resolution: "langsmith@npm:0.2.14" + dependencies: + "@types/uuid": ^10.0.0 + commander: ^10.0.1 + p-queue: ^6.6.2 + p-retry: 4 + semver: ^7.6.3 + uuid: ^10.0.0 + peerDependencies: + openai: "*" + peerDependenciesMeta: + openai: + optional: true + checksum: 6fc142d6b433a024679c600304953e8f53d62359f2d2026300e2993ddaa84d22e7bdaae96f8e0bf351df2faf487aa87846de7d23dd96e2a0c71e37b09e97eee7 + languageName: node + linkType: hard + "language-subtag-registry@npm:^0.3.20": version: 0.3.23 resolution: "language-subtag-registry@npm:0.3.23" @@ -4194,6 +4247,13 @@ __metadata: languageName: node linkType: hard +"obuf@npm:~1.1.2": + version: 1.1.2 + resolution: "obuf@npm:1.1.2" + checksum: 41a2ba310e7b6f6c3b905af82c275bf8854896e2e4c5752966d64cbcd2f599cfffd5932006bcf3b8b419dfdacebb3a3912d5d94e10f1d0acab59876c8757f27f + languageName: node + linkType: hard + "once@npm:^1.3.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -4403,6 +4463,109 @@ __metadata: languageName: node linkType: hard +"pg-cloudflare@npm:^1.1.1": + version: 1.1.1 + resolution: "pg-cloudflare@npm:1.1.1" + checksum: 32aac06b5dc4588bbf78801b6267781bc7e13be672009df949d08e9627ba9fdc26924916665d4de99d47f9b0495301930547488dad889d826856976c7b3f3731 + languageName: node + linkType: hard + +"pg-connection-string@npm:^2.7.0": + version: 2.7.0 + resolution: "pg-connection-string@npm:2.7.0" + checksum: 68015a8874b7ca5dad456445e4114af3d2602bac2fdb8069315ecad0ff9660ec93259b9af7186606529ac4f6f72a06831e6f20897a689b16cc7fda7ca0e247fd + languageName: node + linkType: hard + +"pg-int8@npm:1.0.1": + version: 1.0.1 + resolution: "pg-int8@npm:1.0.1" + checksum: a1e3a05a69005ddb73e5f324b6b4e689868a447c5fa280b44cd4d04e6916a344ac289e0b8d2695d66e8e89a7fba023affb9e0e94778770ada5df43f003d664c9 + languageName: node + linkType: hard + +"pg-numeric@npm:1.0.2": + version: 1.0.2 + resolution: "pg-numeric@npm:1.0.2" + checksum: 8899f8200caa1744439a8778a9eb3ceefb599d893e40a09eef84ee0d4c151319fd416634a6c0fc7b7db4ac268710042da5be700b80ef0de716fe089b8652c84f + languageName: node + linkType: hard + +"pg-pool@npm:^3.7.0": + version: 3.7.0 + resolution: "pg-pool@npm:3.7.0" + peerDependencies: + pg: ">=8.0" + checksum: 66fc1a5ad0e17b72671b9a2cd4c7a856fb08d3cb82da7af0b322590ada23127ac591111e855740405fde4f06c9de888abe9f3aa685ed6038c3232578e1fce8cf + languageName: node + linkType: hard + +"pg-protocol@npm:*, pg-protocol@npm:^1.7.0": + version: 1.7.0 + resolution: "pg-protocol@npm:1.7.0" + checksum: 2dba740f6fc4b7f9761682c4c42d183b444292cdc7638b373f5247ec995c8199c369953343479281da3c41611fe34130a80c8668348d49a399c164f802f76be2 + languageName: node + linkType: hard + +"pg-types@npm:^2.1.0": + version: 2.2.0 + resolution: "pg-types@npm:2.2.0" + dependencies: + pg-int8: 1.0.1 + postgres-array: ~2.0.0 + postgres-bytea: ~1.0.0 + postgres-date: ~1.0.4 + postgres-interval: ^1.1.0 + checksum: bf4ec3f594743442857fb3a8dfe5d2478a04c98f96a0a47365014557cbc0b4b0cee01462c79adca863b93befbf88f876299b75b72c665b5fb84a2c94fbd10316 + languageName: node + linkType: hard + +"pg-types@npm:^4.0.1": + version: 4.0.2 + resolution: "pg-types@npm:4.0.2" + dependencies: + pg-int8: 1.0.1 + pg-numeric: 1.0.2 + postgres-array: ~3.0.1 + postgres-bytea: ~3.0.0 + postgres-date: ~2.1.0 + postgres-interval: ^3.0.0 + postgres-range: ^1.1.1 + checksum: c4b813382d4a75f87462fab3245d5422b86ba1a54a1b330e6b43a459c127b4d02553dc7e5b4ae4fa0f5f17971d416eb393810f69ff6d30d986e45c2f20778c55 + languageName: node + linkType: hard + +"pg@npm:^8.12.0, pg@npm:^8.13.1": + version: 8.13.1 + resolution: "pg@npm:8.13.1" + dependencies: + pg-cloudflare: ^1.1.1 + pg-connection-string: ^2.7.0 + pg-pool: ^3.7.0 + pg-protocol: ^1.7.0 + pg-types: ^2.1.0 + pgpass: 1.x + peerDependencies: + pg-native: ">=3.0.1" + dependenciesMeta: + pg-cloudflare: + optional: true + peerDependenciesMeta: + pg-native: + optional: true + checksum: 22cb97fcbee3348d5ee0b195071cc572f9c88eb40cbb61fe6726af68d55d5962121b2d630509bb907703e1c8bdc33de775462029c5399e2a841fa9e6c9da0242 + languageName: node + linkType: hard + +"pgpass@npm:1.x": + version: 1.0.5 + resolution: "pgpass@npm:1.0.5" + dependencies: + split2: ^4.1.0 + checksum: 947ac096c031eebdf08d989de2e9f6f156b8133d6858c7c2c06c041e1e71dda6f5f3bad3c0ec1e96a09497bbc6ef89e762eefe703b5ef9cb2804392ec52ec400 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": version: 1.1.0 resolution: "picocolors@npm:1.1.0" @@ -4541,6 +4704,73 @@ __metadata: languageName: node linkType: hard +"postgres-array@npm:~2.0.0": + version: 2.0.0 + resolution: "postgres-array@npm:2.0.0" + checksum: 0e1e659888147c5de579d229a2d95c0d83ebdbffc2b9396d890a123557708c3b758a0a97ed305ce7f58edfa961fa9f0bbcd1ea9f08b6e5df73322e683883c464 + languageName: node + linkType: hard + +"postgres-array@npm:~3.0.1": + version: 3.0.2 + resolution: "postgres-array@npm:3.0.2" + checksum: 5955f9dffeb6fa960c1a0b04fd4b2ba16813ddb636934ad26f902e4d76a91c0b743dcc6edc4cffc52deba7d547505e0020adea027c1d50a774f989cf955420d1 + languageName: node + linkType: hard + +"postgres-bytea@npm:~1.0.0": + version: 1.0.0 + resolution: "postgres-bytea@npm:1.0.0" + checksum: d844ae4ca7a941b70e45cac1261a73ee8ed39d72d3d74ab1d645248185a1b7f0ac91a3c63d6159441020f4e1f7fe64689ac56536a307b31cef361e5187335090 + languageName: node + linkType: hard + +"postgres-bytea@npm:~3.0.0": + version: 3.0.0 + resolution: "postgres-bytea@npm:3.0.0" + dependencies: + obuf: ~1.1.2 + checksum: 5f917a003fcaa0df7f285e1c37108ad474ce91193466b9bd4bcaecef2cdea98ca069c00aa6a8dbe6d2e7192336cadc3c9b36ae48d1555a299521918e00e2936b + languageName: node + linkType: hard + +"postgres-date@npm:~1.0.4": + version: 1.0.7 + resolution: "postgres-date@npm:1.0.7" + checksum: 5745001d47e51cd767e46bcb1710649cd705d91a24d42fa661c454b6dcbb7353c066a5047983c90a626cd3bbfea9e626cc6fa84a35ec57e5bbb28b49f78e13ed + languageName: node + linkType: hard + +"postgres-date@npm:~2.1.0": + version: 2.1.0 + resolution: "postgres-date@npm:2.1.0" + checksum: 5c573b0602e17c6134fd8bc8ac7689ac0302e1b199f15dd3578fc45186f206dbd0609f97bf0e4bd1db62234d7a37f29c04f4df525f7efebb9304363b2efca272 + languageName: node + linkType: hard + +"postgres-interval@npm:^1.1.0": + version: 1.2.0 + resolution: "postgres-interval@npm:1.2.0" + dependencies: + xtend: ^4.0.0 + checksum: 746b71f93805ae33b03528e429dc624706d1f9b20ee81bf743263efb6a0cd79ae02a642a8a480dbc0f09547b4315ab7df6ce5ec0be77ed700bac42730f5c76b2 + languageName: node + linkType: hard + +"postgres-interval@npm:^3.0.0": + version: 3.0.0 + resolution: "postgres-interval@npm:3.0.0" + checksum: c7a1cf006de97de663b6b8c4d2b167aa9909a238c4866a94b15d303762f5ac884ff4796cd6e2111b7f0a91302b83c570453aa8506fd005b5a5d5dfa87441bebc + languageName: node + linkType: hard + +"postgres-range@npm:^1.1.1": + version: 1.1.4 + resolution: "postgres-range@npm:1.1.4" + checksum: 460af8c882a50e2c3d08ede5d5ee9e5e5a99dcf471e3ed55b4c17cad62dc85177b51bb8105b626a9c73de9edcba934e86665923b0d86e1c8e1f55d3e0f3530c6 + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -4978,6 +5208,13 @@ __metadata: languageName: node linkType: hard +"split2@npm:^4.1.0": + version: 4.2.0 + resolution: "split2@npm:4.2.0" + checksum: 05d54102546549fe4d2455900699056580cca006c0275c334611420f854da30ac999230857a85fdd9914dc2109ae50f80fda43d2a445f2aa86eccdc1dfce779d + languageName: node + linkType: hard + "sprintf-js@npm:^1.1.3": version: 1.1.3 resolution: "sprintf-js@npm:1.1.3" @@ -5751,6 +5988,13 @@ __metadata: languageName: node linkType: hard +"xtend@npm:^4.0.0": + version: 4.0.2 + resolution: "xtend@npm:4.0.2" + checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0"