From be34fb2c372b9aa39f3281a37ecf9cd4a455c0a5 Mon Sep 17 00:00:00 2001 From: Delacrobix Date: Mon, 10 Nov 2025 11:46:15 -0500 Subject: [PATCH 1/2] supporging blog content human-in-the-loop-with-langgraph-and-elasticsearch --- .../README.md | 56 + .../dataIngestion.ts | 141 + .../dataset.json | 152 + .../main.ts | 242 ++ .../package-lock.json | 3383 +++++++++++++++++ .../package.json | 22 + .../workflow_graph.png | Bin 0 -> 26754 bytes 7 files changed, 3996 insertions(+) create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package-lock.json create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package.json create mode 100644 supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/workflow_graph.png diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md new file mode 100644 index 00000000..b021ccfd --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md @@ -0,0 +1,56 @@ +# LangGraph + Elasticsearch Human-in-the-Loop + +Flight search application using LangGraph for human-in-the-loop workflow and Elasticsearch for vector search. + +## Prerequisites + +- Node.js 18+ +- Elasticsearch instance +- OpenAI API key + +## Installation + +### Quick Install + +```bash +npm install +``` + +### Manual Install (Alternative) + +```bash +npm install @elastic/elasticsearch @langchain/community @langchain/core @langchain/langgraph @langchain/openai dotenv --legacy-peer-deps +npm install --save-dev tsx +``` + +## Configuration + +Create a `.env` file in the root directory: + +```env +ELASTICSEARCH_ENDPOINT=https://your-elasticsearch-instance.com +ELASTICSEARCH_API_KEY=your-api-key +OPENAI_API_KEY=your-openai-api-key +``` + +## Usage + +```bash +npm start +``` + +## Features + +- 🔍 Vector search with Elasticsearch +- 🤖 LLM-powered natural language selection +- 👤 Human-in-the-loop workflow with LangGraph +- 📊 Workflow visualization (generates `workflow_graph.png`) + +## Workflow + +1. **Retrieve Flights** - Search Elasticsearch with vector similarity +2. **Evaluate Results** - Auto-select if 1 result, show options if multiple +3. **Show Results** - Display flight options to user +4. **Request User Choice** - Pause workflow for user input (HITL) +5. **Disambiguate & Answer** - Use LLM to interpret selection and return final answer + diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts new file mode 100644 index 00000000..7d4a7939 --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts @@ -0,0 +1,141 @@ +import { ElasticVectorSearch } from "@langchain/community/vectorstores/elasticsearch"; +import { OpenAIEmbeddings } from "@langchain/openai"; +import { Client } from "@elastic/elasticsearch"; +import { readFile } from "node:fs/promises"; +import dotenv from "dotenv"; + +dotenv.config(); + +const VECTOR_INDEX = "flights-offerings"; + +// Types +export interface DocumentMetadata { + from_city: string; + to_city: string; + airport_code: string; + airport_name: string; + country: string; + airline: string; + date: string; + price: number; + time_approx: string; + title: string; +} + +export interface Document { + pageContent: string; + metadata: DocumentMetadata; +} + +interface RawDocument { + pageContent?: string; + text?: string; + metadata?: DocumentMetadata; +} + +const esClient = new Client({ + node: process.env.ELASTICSEARCH_ENDPOINT!, + auth: { + apiKey: process.env.ELASTICSEARCH_API_KEY!, + }, +}); + +const embeddings = new OpenAIEmbeddings({ + model: "text-embedding-3-small", +}); + +const vectorStore = new ElasticVectorSearch(embeddings, { + client: esClient, + indexName: VECTOR_INDEX, +}); + +/** + * Load dataset from a JSON file + * @param path - Path to the JSON file + * @returns Array of documents with pageContent and metadata + */ +export async function loadDataset(path: string): Promise { + const raw = await readFile(path, "utf-8"); + const data: RawDocument[] = JSON.parse(raw); + + return data.map((d) => ({ + pageContent: String(d.pageContent ?? d.text ?? ""), + metadata: (d.metadata ?? {}) as DocumentMetadata, + })); +} + +/** + * Ingest data into Elasticsearch vector store + * Creates the index if it doesn't exist and loads initial dataset + */ +export async function ingestData(): Promise { + const vectorExists = await esClient.indices.exists({ index: VECTOR_INDEX }); + + if (!vectorExists) { + console.log("CREATING VECTOR INDEX..."); + + await esClient.indices.create({ + index: VECTOR_INDEX, + mappings: { + properties: { + text: { type: "text" }, + embedding: { + type: "dense_vector", + dims: 1536, + index: true, + similarity: "cosine", + }, + metadata: { + type: "object", + properties: { + from_city: { type: "keyword" }, + to_city: { type: "keyword" }, + airport_code: { type: "keyword" }, + airport_name: { + type: "text", + fields: { + keyword: { type: "keyword" }, + }, + }, + country: { type: "keyword" }, + airline: { type: "keyword" }, + date: { type: "date" }, + price: { type: "integer" }, + time_approx: { type: "keyword" }, + title: { + type: "text", + fields: { + keyword: { type: "keyword" }, + }, + }, + }, + }, + }, + }, + }); + } + + const indexExists = await esClient.indices.exists({ index: VECTOR_INDEX }); + + if (indexExists) { + const indexCount = await esClient.count({ index: VECTOR_INDEX }); + const documentCount = indexCount.count; + + // Only ingest if index is empty + if (documentCount > 0) { + console.log( + `Index already contains ${documentCount} documents. Skipping ingestion.` + ); + return; + } + + console.log("INGESTING DATASET..."); + const datasetPath = "./dataset.json"; + const initialDocs = await loadDataset(datasetPath).catch(() => []); + + await vectorStore.addDocuments(initialDocs); + console.log(`âś… Successfully ingested ${initialDocs.length} documents`); + } +} + +export { VECTOR_INDEX }; diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json new file mode 100644 index 00000000..46a4b408 --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json @@ -0,0 +1,152 @@ +[ + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Sao Paulo (GRU). 1 stop. Airline: AndeanSky.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Sao Paulo", + "airport_code": "GRU", + "airport_name": "Guarulhos International", + "country": "Brazil", + "airline": "AndeanSky", + "date": "2025-10-10", + "price": 480, + "time_approx": "7h 30m", + "title": "MDE → GRU (AndeanSky)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Sao Paulo (CGH). 1 stop. Airline: CoffeeAir.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Sao Paulo", + "airport_code": "CGH", + "airport_name": "Congonhas", + "country": "Brazil", + "airline": "CoffeeAir", + "date": "2025-10-10", + "price": 455, + "time_approx": "8h 05m", + "title": "MDE → CGH (CoffeeAir)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Tokyo (HND). 2 stops. Airline: CondorJet.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Tokyo", + "airport_code": "HND", + "airport_name": "Haneda", + "country": "Japan", + "airline": "CondorJet", + "date": "2025-11-05", + "price": 1290, + "time_approx": "22h 10m", + "title": "MDE → HND (CondorJet)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Tokyo (NRT). 1–2 stops. Airline: CaribeWings.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Tokyo", + "airport_code": "NRT", + "airport_name": "Narita", + "country": "Japan", + "airline": "CaribeWings", + "date": "2025-11-05", + "price": 1215, + "time_approx": "23h 30m", + "title": "MDE → NRT (CaribeWings)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → New York (JFK). 1 stop. Airline: AndeanSky.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "New York", + "airport_code": "JFK", + "airport_name": "John F. Kennedy International", + "country": "USA", + "airline": "AndeanSky", + "date": "2025-12-01", + "price": 340, + "time_approx": "6h 40m", + "title": "MDE → JFK (AndeanSky)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → New York (LGA). 1 stop. Airline: CoffeeAir.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "New York", + "airport_code": "LGA", + "airport_name": "LaGuardia", + "country": "USA", + "airline": "CoffeeAir", + "date": "2025-12-01", + "price": 325, + "time_approx": "6h 55m", + "title": "MDE → LGA (CoffeeAir)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → London (LHR). 1 stop. Airline: CondorJet.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "London", + "airport_code": "LHR", + "airport_name": "Heathrow", + "country": "UK", + "airline": "CondorJet", + "date": "2026-01-15", + "price": 890, + "time_approx": "14h 30m", + "title": "MDE → LHR (CondorJet)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → London (LGW). 1–2 stops. Airline: CaribeWings.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "London", + "airport_code": "LGW", + "airport_name": "Gatwick", + "country": "UK", + "airline": "CaribeWings", + "date": "2026-01-15", + "price": 760, + "time_approx": "15h 10m", + "title": "MDE → LGW (CaribeWings)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Paris (CDG). 1 stop. Airline: CoffeeAir.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Paris", + "airport_code": "CDG", + "airport_name": "Charles de Gaulle", + "country": "France", + "airline": "CoffeeAir", + "date": "2025-10-22", + "price": 720, + "time_approx": "13h 50m", + "title": "MDE → CDG (CoffeeAir)" + } + }, + { + "pageContent": "Ticket: MedellĂ­n (MDE) → Paris (ORY). 1 stop. Airline: AndeanSky.", + "metadata": { + "from_city": "MedellĂ­n", + "to_city": "Paris", + "airport_code": "ORY", + "airport_name": "Orly", + "country": "France", + "airline": "AndeanSky", + "date": "2025-10-22", + "price": 695, + "time_approx": "13h 20m", + "title": "MDE → ORY (AndeanSky)" + } + } +] diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts new file mode 100644 index 00000000..41f3593d --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts @@ -0,0 +1,242 @@ +import { + StateGraph, + Annotation, + interrupt, + Command, + MemorySaver, +} from "@langchain/langgraph"; +import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai"; +import { ElasticVectorSearch } from "@langchain/community/vectorstores/elasticsearch"; +import { Client } from "@elastic/elasticsearch"; +import { writeFileSync } from "node:fs"; +import readline from "node:readline"; +import { ingestData, Document, DocumentMetadata } from "./dataIngestion.ts"; + +const VECTOR_INDEX = "flights-offerings"; + +const llm = new ChatOpenAI({ model: "gpt-4o-mini" }); +const embeddings = new OpenAIEmbeddings({ + model: "text-embedding-3-small", +}); + +const esClient = new Client({ + node: process.env.ELASTICSEARCH_ENDPOINT!, + auth: { + apiKey: process.env.ELASTICSEARCH_API_KEY!, + }, +}); + +const vectorStore = new ElasticVectorSearch(embeddings, { + client: esClient, + indexName: VECTOR_INDEX, +}); + +// Define the state schema for application workflow +const SupportState = Annotation.Root({ + input: Annotation(), + candidates: Annotation(), + userChoice: Annotation(), + selected: Annotation(), + final: Annotation(), +}); + +// Node 1: Retrieve data from Elasticsearch +async function retrieveFlights(state: typeof SupportState.State) { + const results = await vectorStore.similaritySearch(state.input, 2); + const candidates = results.map((d) => d as Document); + + console.log(`đź“‹ Found ${candidates.length} different flights`); + return { candidates }; +} + +// Node 2: Evaluate if there are 1 or multiple responses +function evaluateResults(state: typeof SupportState.State) { + const candidates = state.candidates || []; + + // If there is 1 result, auto-select it + if (candidates.length === 1) { + const metadata = candidates[0].metadata || {}; + + return { + selected: candidates[0], + final: formatFlightDetails(metadata), + }; + } + + return { candidates }; +} + +// Node 3: Request user choice (separate from showing) +function requestUserChoice() { + const userChoice = interrupt({ + question: `Which flight do you prefer?:`, + }); + + return { userChoice }; +} + +// Node 4: Disambiguate user choice and provide final answer +async function disambiguateAndAnswer(state: typeof SupportState.State) { + const candidates = state.candidates || []; + const userInput = state.userChoice || ""; + + const prompt = ` + Based on the user's response: "${userInput}" + + These are the available flights: + ${candidates + .map( + (d, i) => + `${i}. ${d.metadata?.title} - ${d.metadata?.to_city} (${d.metadata?.airport_code}) - ${d.metadata?.airline} - $${d.metadata?.price} - ${d.metadata?.time_approx}` + ) + .join("\n")} + + Which flight is the user selecting? Respond ONLY with the flight number (1, 2, or 3). + `; + + const llmResponse = await llm.invoke([ + { + role: "system", + content: + "You are an assistant that interprets user selection. Respond ONLY with the selected flight number.", + }, + { role: "user", content: prompt }, + ]); + + const selectedNumber = Number.parseInt(llmResponse.content as string, 10); // Convert to zero-based index + const selectedFlight = candidates[selectedNumber] ?? candidates[0]; // Fallback to first option + + return { + selected: selectedFlight, + final: formatFlightDetails(selectedFlight.metadata), + }; +} + +// Node 5: Show results only +function showResults(state: typeof SupportState.State) { + const candidates = state.candidates || []; + const formattedOptions = candidates + .map((d: Document, index: number) => { + const m = d.metadata || {}; + + return `${index + 1}. ${m.title} - ${m.to_city} - ${m.airport_name}(${ + m.airport_code + }) airport - ${m.airline} - $${m.price} - ${m.time_approx}`; + }) + .join("\n"); + + console.log(`\nđź“‹ Flights found:\n${formattedOptions}\n`); + + return state; +} + +// Helper function to format flight details +function formatFlightDetails(metadata: DocumentMetadata): string { + return `Selected flight: ${metadata.title} - ${metadata.airline} + From: ${metadata.from_city} (${ + metadata.from_city?.slice(0, 3).toUpperCase() || "N/A" + }) + To: ${metadata.to_city} (${metadata.airport_code}) + Airport: ${metadata.airport_name} + Price: $${metadata.price} + Duration: ${metadata.time_approx} + Date: ${metadata.date}`; +} + +// Build the graph +const workflow = new StateGraph(SupportState) + .addNode("retrieveFlights", retrieveFlights) + .addNode("evaluateResults", evaluateResults) + .addNode("showResults", showResults) + .addNode("requestUserChoice", requestUserChoice) + .addNode("disambiguateAndAnswer", disambiguateAndAnswer) + .addEdge("__start__", "retrieveFlights") + .addEdge("retrieveFlights", "evaluateResults") + .addConditionalEdges( + "evaluateResults", + (state: typeof SupportState.State) => { + if (state.final) return "complete"; // 0 or 1 result + return "multiple"; // multiple results + }, + { + complete: "__end__", + multiple: "showResults", + } + ) + .addEdge("showResults", "requestUserChoice") + .addEdge("requestUserChoice", "disambiguateAndAnswer") + .addEdge("disambiguateAndAnswer", "__end__"); + +/** + * Get user input from the command line + * @param question - Question to ask the user + * @returns User's answer + */ +function getUserInput(question: string): Promise { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + return new Promise((resolve) => { + rl.question(question, (answer) => { + rl.close(); + resolve(answer.trim()); + }); + }); +} + +/** + * Save workflow graph as PNG image + * @param app - Compiled workflow application + */ +async function saveGraphImage(app: any): Promise { + try { + const graph = app.getGraph(); + const graphImage = await graph.drawMermaidPng(); + const graphArrayBuffer = await graphImage.arrayBuffer(); + + const filePath = "./workflow_graph.png"; + writeFileSync(filePath, new Uint8Array(graphArrayBuffer)); + console.log(`📊 Workflow graph saved as: ${filePath}`); + } catch (error) { + console.log("⚠️ Could not save graph image:", (error as Error).message); + } +} + +/** + * Main execution function + */ +async function main() { + // Ingest data + await ingestData(); + + // Compile workflow + const app = workflow.compile({ checkpointer: new MemorySaver() }); + const config = { configurable: { thread_id: "hitl-thread" } }; + + // Save graph image + await saveGraphImage(app); + + // Execute workflow + const question = "Flights to Tokyo"; // User query + console.log(`🔍 SEARCHING USER QUESTION: "${question}"\n`); + + let currentState = await app.invoke({ input: question }, config); + + // Handle interruption + if ((currentState as any).__interrupt__?.length > 0) { + console.log("\nđź’­ APPLICATION PAUSED WAITING FOR USER INPUT..."); + const userChoice = await getUserInput("👤 CHOICE ONE OPTION: "); + + currentState = await app.invoke( + new Command({ resume: userChoice }), + config + ); + } + + console.log("\nâś… Final result: \n", currentState.final); +} + +// Run main function +await main(); diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package-lock.json b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package-lock.json new file mode 100644 index 00000000..75ed5141 --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package-lock.json @@ -0,0 +1,3383 @@ +{ + "name": "LangGraph Elasticsearch", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "LangGraph Elasticsearch", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@elastic/elasticsearch": "^9.2.0", + "@langchain/community": "^0.3.57", + "@langchain/core": "^0.3.79", + "@langchain/langgraph": "^0.4.9", + "@langchain/openai": "^0.6.16", + "dotenv": "^16.6.1", + "express": "^4.19.2" + }, + "devDependencies": { + "tsx": "^4.20.6" + } + }, + "node_modules/@cfworker/json-schema": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz", + "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==", + "license": "MIT" + }, + "node_modules/@elastic/elasticsearch": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-9.2.0.tgz", + "integrity": "sha512-M59qmMOZOk8pTcI9Ns2ow18PlyMbYrpcXqYwkChjiyXSmmqoCTvFXkC2bGQLxrrQkXaPbYR7aZqWD9b5F1405A==", + "license": "Apache-2.0", + "dependencies": { + "@elastic/transport": "^9.2.0", + "apache-arrow": "18.x - 21.x", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@elastic/transport": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-9.2.1.tgz", + "integrity": "sha512-CLSWaaETmokbMiWTdgx0One+0qJJERsu9+CRI9VUTwOxEMhnjR6pkNk9JIkEqJ1mrocH2K7k0TTu2pMH77hl0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "1.x", + "@opentelemetry/core": "2.x", + "debug": "^4.4.1", + "hpagent": "^1.2.0", + "ms": "^2.1.3", + "secure-json-parse": "^4.0.0", + "tslib": "^2.8.1", + "undici": "^7.16.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.0.tgz", + "integrity": "sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.3", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@langchain/community": { + "version": "0.3.57", + "resolved": "https://registry.npmjs.org/@langchain/community/-/community-0.3.57.tgz", + "integrity": "sha512-xUe5UIlh1yZjt/cMtdSVlCoC5xm/RMN/rp+KZGLbquvjQeONmQ2rvpCqWjAOgQ6SPLqKiXvoXaKSm20r+LHISw==", + "license": "MIT", + "dependencies": { + "@langchain/openai": ">=0.2.0 <0.7.0", + "@langchain/weaviate": "^0.2.0", + "binary-extensions": "^2.2.0", + "expr-eval": "^2.0.2", + "flat": "^5.0.2", + "js-yaml": "^4.1.0", + "langchain": ">=0.2.3 <0.3.0 || >=0.3.4 <0.4.0", + "langsmith": "^0.3.67", + "uuid": "^10.0.0", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@arcjet/redact": "^v1.0.0-alpha.23", + "@aws-crypto/sha256-js": "^5.0.0", + "@aws-sdk/client-bedrock-agent-runtime": "^3.749.0", + "@aws-sdk/client-bedrock-runtime": "^3.749.0", + "@aws-sdk/client-dynamodb": "^3.749.0", + "@aws-sdk/client-kendra": "^3.749.0", + "@aws-sdk/client-lambda": "^3.749.0", + "@aws-sdk/client-s3": "^3.749.0", + "@aws-sdk/client-sagemaker-runtime": "^3.749.0", + "@aws-sdk/client-sfn": "^3.749.0", + "@aws-sdk/credential-provider-node": "^3.388.0", + "@azure/search-documents": "^12.0.0", + "@azure/storage-blob": "^12.15.0", + "@browserbasehq/sdk": "*", + "@browserbasehq/stagehand": "^1.0.0", + "@clickhouse/client": "^0.2.5", + "@cloudflare/ai": "*", + "@datastax/astra-db-ts": "^1.0.0", + "@elastic/elasticsearch": "^8.4.0", + "@getmetal/metal-sdk": "*", + "@getzep/zep-cloud": "^1.0.6", + "@getzep/zep-js": "^0.9.0", + "@gomomento/sdk": "^1.51.1", + "@gomomento/sdk-core": "^1.51.1", + "@google-ai/generativelanguage": "*", + "@google-cloud/storage": "^6.10.1 || ^7.7.0", + "@gradientai/nodejs-sdk": "^1.2.0", + "@huggingface/inference": "^4.0.5", + "@huggingface/transformers": "^3.5.2", + "@ibm-cloud/watsonx-ai": "*", + "@lancedb/lancedb": "^0.19.1", + "@langchain/core": ">=0.3.58 <0.4.0", + "@layerup/layerup-security": "^1.5.12", + "@libsql/client": "^0.14.0", + "@mendable/firecrawl-js": "^1.4.3", + "@mlc-ai/web-llm": "*", + "@mozilla/readability": "*", + "@neondatabase/serverless": "*", + "@notionhq/client": "^2.2.10", + "@opensearch-project/opensearch": "*", + "@pinecone-database/pinecone": "*", + "@planetscale/database": "^1.8.0", + "@premai/prem-sdk": "^0.3.25", + "@qdrant/js-client-rest": "^1.15.0", + "@raycast/api": "^1.55.2", + "@rockset/client": "^0.9.1", + "@smithy/eventstream-codec": "^2.0.5", + "@smithy/protocol-http": "^3.0.6", + "@smithy/signature-v4": "^2.0.10", + "@smithy/util-utf8": "^2.0.0", + "@spider-cloud/spider-client": "^0.0.21", + "@supabase/supabase-js": "^2.45.0", + "@tensorflow-models/universal-sentence-encoder": "*", + "@tensorflow/tfjs-converter": "*", + "@tensorflow/tfjs-core": "*", + "@upstash/ratelimit": "^1.1.3 || ^2.0.3", + "@upstash/redis": "^1.20.6", + "@upstash/vector": "^1.1.1", + "@vercel/kv": "*", + "@vercel/postgres": "*", + "@writerai/writer-sdk": "^0.40.2", + "@xata.io/client": "^0.28.0", + "@zilliz/milvus2-sdk-node": ">=2.3.5", + "apify-client": "^2.7.1", + "assemblyai": "^4.6.0", + "azion": "^1.11.1", + "better-sqlite3": ">=9.4.0 <12.0.0", + "cassandra-driver": "^4.7.2", + "cborg": "^4.1.1", + "cheerio": "^1.0.0-rc.12", + "chromadb": "*", + "closevector-common": "0.1.3", + "closevector-node": "0.1.6", + "closevector-web": "0.1.6", + "cohere-ai": "*", + "convex": "^1.3.1", + "crypto-js": "^4.2.0", + "d3-dsv": "^2.0.0", + "discord.js": "^14.14.1", + "duck-duck-scrape": "^2.2.5", + "epub2": "^3.0.1", + "fast-xml-parser": "*", + "firebase-admin": "^11.9.0 || ^12.0.0 || ^13.0.0", + "google-auth-library": "*", + "googleapis": "*", + "hnswlib-node": "^3.0.0", + "html-to-text": "^9.0.5", + "ibm-cloud-sdk-core": "*", + "ignore": "^5.2.0", + "interface-datastore": "^8.2.11", + "ioredis": "^5.3.2", + "it-all": "^3.0.4", + "jsdom": "*", + "jsonwebtoken": "^9.0.2", + "llmonitor": "^0.5.9", + "lodash": "^4.17.21", + "lunary": "^0.7.10", + "mammoth": "^1.6.0", + "mariadb": "^3.4.0", + "mem0ai": "^2.1.8", + "mongodb": "^6.17.0", + "mysql2": "^3.9.8", + "neo4j-driver": "*", + "notion-to-md": "^3.1.0", + "officeparser": "^4.0.4", + "openai": "*", + "pdf-parse": "1.1.1", + "pg": "^8.11.0", + "pg-copy-streams": "^6.0.5", + "pickleparser": "^0.2.1", + "playwright": "^1.32.1", + "portkey-ai": "^0.1.11", + "puppeteer": "*", + "pyodide": ">=0.24.1 <0.27.0", + "redis": "*", + "replicate": "*", + "sonix-speech-recognition": "^2.1.1", + "srt-parser-2": "^1.2.3", + "typeorm": "^0.3.20", + "typesense": "^1.5.3", + "usearch": "^1.1.1", + "voy-search": "0.6.2", + "weaviate-client": "^3.5.2", + "web-auth-library": "^1.0.3", + "word-extractor": "*", + "ws": "^8.14.2", + "youtubei.js": "*" + }, + "peerDependenciesMeta": { + "@arcjet/redact": { + "optional": true + }, + "@aws-crypto/sha256-js": { + "optional": true + }, + "@aws-sdk/client-bedrock-agent-runtime": { + "optional": true + }, + "@aws-sdk/client-bedrock-runtime": { + "optional": true + }, + "@aws-sdk/client-dynamodb": { + "optional": true + }, + "@aws-sdk/client-kendra": { + "optional": true + }, + "@aws-sdk/client-lambda": { + "optional": true + }, + "@aws-sdk/client-s3": { + "optional": true + }, + "@aws-sdk/client-sagemaker-runtime": { + "optional": true + }, + "@aws-sdk/client-sfn": { + "optional": true + }, + "@aws-sdk/credential-provider-node": { + "optional": true + }, + "@aws-sdk/dsql-signer": { + "optional": true + }, + "@azure/search-documents": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@browserbasehq/sdk": { + "optional": true + }, + "@clickhouse/client": { + "optional": true + }, + "@cloudflare/ai": { + "optional": true + }, + "@datastax/astra-db-ts": { + "optional": true + }, + "@elastic/elasticsearch": { + "optional": true + }, + "@getmetal/metal-sdk": { + "optional": true + }, + "@getzep/zep-cloud": { + "optional": true + }, + "@getzep/zep-js": { + "optional": true + }, + "@gomomento/sdk": { + "optional": true + }, + "@gomomento/sdk-core": { + "optional": true + }, + "@google-ai/generativelanguage": { + "optional": true + }, + "@google-cloud/storage": { + "optional": true + }, + "@gradientai/nodejs-sdk": { + "optional": true + }, + "@huggingface/inference": { + "optional": true + }, + "@huggingface/transformers": { + "optional": true + }, + "@lancedb/lancedb": { + "optional": true + }, + "@layerup/layerup-security": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@mendable/firecrawl-js": { + "optional": true + }, + "@mlc-ai/web-llm": { + "optional": true + }, + "@mozilla/readability": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@notionhq/client": { + "optional": true + }, + "@opensearch-project/opensearch": { + "optional": true + }, + "@pinecone-database/pinecone": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@premai/prem-sdk": { + "optional": true + }, + "@qdrant/js-client-rest": { + "optional": true + }, + "@raycast/api": { + "optional": true + }, + "@rockset/client": { + "optional": true + }, + "@smithy/eventstream-codec": { + "optional": true + }, + "@smithy/protocol-http": { + "optional": true + }, + "@smithy/signature-v4": { + "optional": true + }, + "@smithy/util-utf8": { + "optional": true + }, + "@spider-cloud/spider-client": { + "optional": true + }, + "@supabase/supabase-js": { + "optional": true + }, + "@tensorflow-models/universal-sentence-encoder": { + "optional": true + }, + "@tensorflow/tfjs-converter": { + "optional": true + }, + "@tensorflow/tfjs-core": { + "optional": true + }, + "@upstash/ratelimit": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@upstash/vector": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@writerai/writer-sdk": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "@zilliz/milvus2-sdk-node": { + "optional": true + }, + "apify-client": { + "optional": true + }, + "assemblyai": { + "optional": true + }, + "azion": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "cassandra-driver": { + "optional": true + }, + "cborg": { + "optional": true + }, + "cheerio": { + "optional": true + }, + "chromadb": { + "optional": true + }, + "closevector-common": { + "optional": true + }, + "closevector-node": { + "optional": true + }, + "closevector-web": { + "optional": true + }, + "cohere-ai": { + "optional": true + }, + "convex": { + "optional": true + }, + "crypto-js": { + "optional": true + }, + "d3-dsv": { + "optional": true + }, + "discord.js": { + "optional": true + }, + "duck-duck-scrape": { + "optional": true + }, + "epub2": { + "optional": true + }, + "fast-xml-parser": { + "optional": true + }, + "firebase-admin": { + "optional": true + }, + "google-auth-library": { + "optional": true + }, + "googleapis": { + "optional": true + }, + "hnswlib-node": { + "optional": true + }, + "html-to-text": { + "optional": true + }, + "ignore": { + "optional": true + }, + "interface-datastore": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "it-all": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "jsonwebtoken": { + "optional": true + }, + "llmonitor": { + "optional": true + }, + "lodash": { + "optional": true + }, + "lunary": { + "optional": true + }, + "mammoth": { + "optional": true + }, + "mariadb": { + "optional": true + }, + "mem0ai": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "neo4j-driver": { + "optional": true + }, + "notion-to-md": { + "optional": true + }, + "officeparser": { + "optional": true + }, + "pdf-parse": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-copy-streams": { + "optional": true + }, + "pickleparser": { + "optional": true + }, + "playwright": { + "optional": true + }, + "portkey-ai": { + "optional": true + }, + "puppeteer": { + "optional": true + }, + "pyodide": { + "optional": true + }, + "redis": { + "optional": true + }, + "replicate": { + "optional": true + }, + "sonix-speech-recognition": { + "optional": true + }, + "srt-parser-2": { + "optional": true + }, + "typeorm": { + "optional": true + }, + "typesense": { + "optional": true + }, + "usearch": { + "optional": true + }, + "voy-search": { + "optional": true + }, + "weaviate-client": { + "optional": true + }, + "web-auth-library": { + "optional": true + }, + "word-extractor": { + "optional": true + }, + "ws": { + "optional": true + }, + "youtubei.js": { + "optional": true + } + } + }, + "node_modules/@langchain/core": { + "version": "0.3.79", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.79.tgz", + "integrity": "sha512-ZLAs5YMM5N2UXN3kExMglltJrKKoW7hs3KMZFlXUnD7a5DFKBYxPFMeXA4rT+uvTxuJRZPCYX0JKI5BhyAWx4A==", + "license": "MIT", + "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.3.67", + "mustache": "^4.2.0", + "p-queue": "^6.6.2", + "p-retry": "4", + "uuid": "^10.0.0", + "zod": "^3.25.32", + "zod-to-json-schema": "^3.22.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@langchain/langgraph": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-0.4.9.tgz", + "integrity": "sha512-+rcdTGi4Ium4X/VtIX3Zw4RhxEkYWpwUyz806V6rffjHOAMamg6/WZDxpJbrP33RV/wJG1GH12Z29oX3Pqq3Aw==", + "license": "MIT", + "dependencies": { + "@langchain/langgraph-checkpoint": "^0.1.1", + "@langchain/langgraph-sdk": "~0.1.0", + "uuid": "^10.0.0", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.3.58 < 0.4.0", + "zod-to-json-schema": "^3.x" + }, + "peerDependenciesMeta": { + "zod-to-json-schema": { + "optional": true + } + } + }, + "node_modules/@langchain/langgraph-checkpoint": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-0.1.1.tgz", + "integrity": "sha512-h2bP0RUikQZu0Um1ZUPErQLXyhzroJqKRbRcxYRTAh49oNlsfeq4A3K4YEDRbGGuyPZI/Jiqwhks1wZwY73AZw==", + "license": "MIT", + "dependencies": { + "uuid": "^10.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.31 <0.4.0 || ^1.0.0-alpha" + } + }, + "node_modules/@langchain/langgraph-sdk": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@langchain/langgraph-sdk/-/langgraph-sdk-0.1.10.tgz", + "integrity": "sha512-9srSCb2bSvcvehMgjA2sMMwX0o1VUgPN6ghwm5Fwc9JGAKsQa6n1S4eCwy1h4abuYxwajH5n3spBw+4I2WYbgw==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15", + "p-queue": "^6.6.2", + "p-retry": "4", + "uuid": "^9.0.0" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.31 <0.4.0 || ^1.0.0-alpha", + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@langchain/core": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@langchain/langgraph-sdk/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@langchain/openai": { + "version": "0.6.16", + "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.6.16.tgz", + "integrity": "sha512-v9INBOjE0w6ZrUE7kP9UkRyNsV7daH7aPeSOsPEJ35044UI3udPHwNduQ8VmaOUsD26OvSdg1b1GDhrqWLMaRw==", + "license": "MIT", + "dependencies": { + "js-tiktoken": "^1.0.12", + "openai": "5.12.2", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.3.68 <0.4.0" + } + }, + "node_modules/@langchain/textsplitters": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@langchain/textsplitters/-/textsplitters-0.1.0.tgz", + "integrity": "sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==", + "license": "MIT", + "dependencies": { + "js-tiktoken": "^1.0.12" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.21 <0.4.0" + } + }, + "node_modules/@langchain/weaviate": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@langchain/weaviate/-/weaviate-0.2.3.tgz", + "integrity": "sha512-WqNGn1eSrI+ZigJd7kZjCj3fvHBYicKr054qts2nNJ+IyO5dWmY3oFTaVHFq1OLFVZJJxrFeDnxSEOC3JnfP0w==", + "license": "MIT", + "dependencies": { + "uuid": "^10.0.0", + "weaviate-client": "^3.5.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.21 <0.4.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.37.0.tgz", + "integrity": "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", + "license": "MIT" + }, + "node_modules/@types/command-line-usage": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz", + "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", + "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "license": "MIT" + }, + "node_modules/abort-controller-x": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/abort-controller-x/-/abort-controller-x-0.4.3.tgz", + "integrity": "sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==", + "license": "MIT" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apache-arrow": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz", + "integrity": "sha512-kQrYLxhC+NTVVZ4CCzGF6L/uPVOzJmD1T3XgbiUnP7oTeVFOFgEUu6IKNwCDkpFoBVqDKQivlX4RUFqqnWFlEA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/command-line-args": "^5.2.3", + "@types/command-line-usage": "^5.0.4", + "@types/node": "^24.0.3", + "command-line-args": "^6.0.1", + "command-line-usage": "^7.0.1", + "flatbuffers": "^25.1.24", + "json-bignum": "^0.0.3", + "tslib": "^2.6.2" + }, + "bin": { + "arrow2csv": "bin/arrow2csv.js" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/command-line-args": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.1.tgz", + "integrity": "sha512-Jr3eByUjqyK0qd8W0SGFW1nZwqCaNCtbXjRo2cRJC1OYxWl3MZ5t1US3jq+cO4sPavqgw4l9BMGX0CBe+trepg==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "find-replace": "^5.0.2", + "lodash.camelcase": "^4.3.0", + "typical": "^7.2.0" + }, + "engines": { + "node": ">=12.20" + }, + "peerDependencies": { + "@75lb/nature": "latest" + }, + "peerDependenciesMeta": { + "@75lb/nature": { + "optional": true + } + } + }, + "node_modules/command-line-usage": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", + "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^4.1.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/console-table-printer": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.15.0.tgz", + "integrity": "sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==", + "license": "MIT", + "dependencies": { + "simple-wcswidth": "^1.1.2" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/expr-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expr-eval/-/expr-eval-2.0.2.tgz", + "integrity": "sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==", + "license": "MIT" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-replace": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz", + "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@75lb/nature": "latest" + }, + "peerDependenciesMeta": { + "@75lb/nature": { + "optional": true + } + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphql": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", + "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", + "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.2.0", + "cross-fetch": "^3.1.5" + }, + "peerDependencies": { + "graphql": "14 - 16" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tiktoken": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz", + "integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.5.1" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bignum": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", + "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/langchain": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.3.36.tgz", + "integrity": "sha512-PqC19KChFF0QlTtYDFgfEbIg+SCnCXox29G8tY62QWfj9bOW7ew2kgWmPw5qoHLOTKOdQPvXET20/1Pdq8vAtQ==", + "license": "MIT", + "dependencies": { + "@langchain/openai": ">=0.1.0 <0.7.0", + "@langchain/textsplitters": ">=0.0.0 <0.2.0", + "js-tiktoken": "^1.0.12", + "js-yaml": "^4.1.0", + "jsonpointer": "^5.0.1", + "langsmith": "^0.3.67", + "openapi-types": "^12.1.3", + "p-retry": "4", + "uuid": "^10.0.0", + "yaml": "^2.2.1", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/anthropic": "*", + "@langchain/aws": "*", + "@langchain/cerebras": "*", + "@langchain/cohere": "*", + "@langchain/core": ">=0.3.58 <0.4.0", + "@langchain/deepseek": "*", + "@langchain/google-genai": "*", + "@langchain/google-vertexai": "*", + "@langchain/google-vertexai-web": "*", + "@langchain/groq": "*", + "@langchain/mistralai": "*", + "@langchain/ollama": "*", + "@langchain/xai": "*", + "axios": "*", + "cheerio": "*", + "handlebars": "^4.7.8", + "peggy": "^3.0.2", + "typeorm": "*" + }, + "peerDependenciesMeta": { + "@langchain/anthropic": { + "optional": true + }, + "@langchain/aws": { + "optional": true + }, + "@langchain/cerebras": { + "optional": true + }, + "@langchain/cohere": { + "optional": true + }, + "@langchain/deepseek": { + "optional": true + }, + "@langchain/google-genai": { + "optional": true + }, + "@langchain/google-vertexai": { + "optional": true + }, + "@langchain/google-vertexai-web": { + "optional": true + }, + "@langchain/groq": { + "optional": true + }, + "@langchain/mistralai": { + "optional": true + }, + "@langchain/ollama": { + "optional": true + }, + "@langchain/xai": { + "optional": true + }, + "axios": { + "optional": true + }, + "cheerio": { + "optional": true + }, + "handlebars": { + "optional": true + }, + "peggy": { + "optional": true + }, + "typeorm": { + "optional": true + } + } + }, + "node_modules/langsmith": { + "version": "0.3.77", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.77.tgz", + "integrity": "sha512-wbS/9IX/hOAsOEOtPj8kCS8H0tFHaelwQ97gTONRtIfoPPLd9MMUmhk0KQB5DdsGAI5abg966+f0dZ/B+YRRzg==", + "license": "MIT", + "dependencies": { + "@types/uuid": "^10.0.0", + "chalk": "^4.1.2", + "console-table-printer": "^2.12.1", + "p-queue": "^6.6.2", + "p-retry": "4", + "semver": "^7.6.3", + "uuid": "^10.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/exporter-trace-otlp-proto": "*", + "@opentelemetry/sdk-trace-base": "*", + "openai": "*" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "openai": { + "optional": true + } + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-grpc": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/nice-grpc/-/nice-grpc-2.1.13.tgz", + "integrity": "sha512-IkXNok2NFyYh0WKp1aJFwFV3Ue2frBkJ16ojrmgX3Tc9n0g7r0VU+ur3H/leDHPPGsEeVozdMynGxYT30k3D/Q==", + "license": "MIT", + "dependencies": { + "@grpc/grpc-js": "^1.14.0", + "abort-controller-x": "^0.4.0", + "nice-grpc-common": "^2.0.2" + } + }, + "node_modules/nice-grpc-client-middleware-retry": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-retry/-/nice-grpc-client-middleware-retry-3.1.12.tgz", + "integrity": "sha512-CHKIeHznAePOsT2dLeGwoOFaybQz6LvkIsFfN8SLcyGyTR7AB6vZMaECJjx+QPL8O2qVgaVE167PdeOmQrPuag==", + "license": "MIT", + "dependencies": { + "abort-controller-x": "^0.4.0", + "nice-grpc-common": "^2.0.2" + } + }, + "node_modules/nice-grpc-common": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-2.0.2.tgz", + "integrity": "sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==", + "license": "MIT", + "dependencies": { + "ts-error": "^1.0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/openai": { + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/openai/-/openai-5.12.2.tgz", + "integrity": "sha512-xqzHHQch5Tws5PcKR2xsZGX9xtch+JQFz5zb14dGqlshmmDAFBFEWmeIpf7wVqWV+w7Emj7jRgkNJakyKE0tYQ==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "license": "MIT" + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-wcswidth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz", + "integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "wordwrapjs": "^5.1.0" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-error": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ts-error/-/ts-error-1.0.6.tgz", + "integrity": "sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.20.6", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", + "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typical": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", + "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/undici": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", + "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/weaviate-client": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/weaviate-client/-/weaviate-client-3.9.0.tgz", + "integrity": "sha512-7qwg7YONAaT4zWnohLrFdzky+rZegVe76J+Tky/+7tuyvjFpdKgSrdqI/wPDh8aji0ZGZrL4DdGwGfFnZ+uV4w==", + "license": "BSD-3-Clause", + "dependencies": { + "abort-controller-x": "^0.4.3", + "graphql": "^16.11.0", + "graphql-request": "^6.1.0", + "long": "^5.3.2", + "nice-grpc": "^2.1.12", + "nice-grpc-client-middleware-retry": "^3.1.11", + "nice-grpc-common": "^2.0.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/weaviate-client/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wordwrapjs": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz", + "integrity": "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + } + } +} diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package.json b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package.json new file mode 100644 index 00000000..45cd986d --- /dev/null +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/package.json @@ -0,0 +1,22 @@ +{ + "name": "LangGraph Elasticsearch", + "version": "1.0.0", + "type": "module", + "main": "index.js", + "license": "MIT", + "scripts": { + "start": "tsx main.ts" + }, + "dependencies": { + "@elastic/elasticsearch": "^9.2.0", + "@langchain/community": "^0.3.57", + "@langchain/core": "^0.3.79", + "@langchain/langgraph": "^0.4.9", + "@langchain/openai": "^0.6.16", + "dotenv": "^16.6.1", + "express": "^4.19.2" + }, + "devDependencies": { + "tsx": "^4.20.6" + } +} diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/workflow_graph.png b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/workflow_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..2f857e3bfe23021da5a4f5b199c3bbcf4bf25c58 GIT binary patch literal 26754 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 ZM!=Oz#qDcL_6J)K Date: Tue, 25 Nov 2025 17:38:11 -0500 Subject: [PATCH 2/2] usecase change --- .../README.md | 14 +- .../dataIngestion.ts | 32 +- .../dataset.json | 190 ++++------ .../main.ts | 356 ++++++++++++------ .../workflow_graph.png | Bin 26754 -> 29690 bytes 5 files changed, 342 insertions(+), 250 deletions(-) diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md index b021ccfd..8e58214e 100644 --- a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/README.md @@ -1,6 +1,6 @@ # LangGraph + Elasticsearch Human-in-the-Loop -Flight search application using LangGraph for human-in-the-loop workflow and Elasticsearch for vector search. +Flight search application using LangGraph for human-in-the-loop workflow and Elasticsearch for vector search. This is a supporting blog content for the article: [Building Human-in-the-Loop AI Agents with LangGraph and Elasticsearch](https://www.elastic.co/search-labs/blog/human-in-the-loop-with-langgraph-and-elasticsearch). ## Prerequisites @@ -29,8 +29,8 @@ Create a `.env` file in the root directory: ```env ELASTICSEARCH_ENDPOINT=https://your-elasticsearch-instance.com -ELASTICSEARCH_API_KEY=your-api-key -OPENAI_API_KEY=your-openai-api-key +ELASTICSEARCH_API_KEY="your-api-key" +OPENAI_API_KEY="your-openai-api-key" ``` ## Usage @@ -46,11 +46,3 @@ npm start - 👤 Human-in-the-loop workflow with LangGraph - 📊 Workflow visualization (generates `workflow_graph.png`) -## Workflow - -1. **Retrieve Flights** - Search Elasticsearch with vector similarity -2. **Evaluate Results** - Auto-select if 1 result, show options if multiple -3. **Show Results** - Display flight options to user -4. **Request User Choice** - Pause workflow for user input (HITL) -5. **Disambiguate & Answer** - Use LLM to interpret selection and return final answer - diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts index 7d4a7939..22f52e5b 100644 --- a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataIngestion.ts @@ -6,19 +6,16 @@ import dotenv from "dotenv"; dotenv.config(); -const VECTOR_INDEX = "flights-offerings"; +const VECTOR_INDEX = "legal-precedents"; // Types export interface DocumentMetadata { - from_city: string; - to_city: string; - airport_code: string; - airport_name: string; - country: string; - airline: string; - date: string; - price: number; - time_approx: string; + caseId: string; + contractType: string; + delayPeriod: string; + outcome: string; + reasoning: string; + keyTerms: string; title: string; } @@ -88,20 +85,17 @@ export async function ingestData(): Promise { metadata: { type: "object", properties: { - from_city: { type: "keyword" }, - to_city: { type: "keyword" }, - airport_code: { type: "keyword" }, - airport_name: { + caseId: { type: "keyword" }, + contractType: { type: "keyword" }, + delayPeriod: { type: "text", fields: { keyword: { type: "keyword" }, }, }, - country: { type: "keyword" }, - airline: { type: "keyword" }, - date: { type: "date" }, - price: { type: "integer" }, - time_approx: { type: "keyword" }, + outcome: { type: "keyword" }, + reasoning: { type: "text" }, + keyTerms: { type: "text" }, title: { type: "text", fields: { diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json index 46a4b408..ec6a5b0a 100644 --- a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/dataset.json @@ -1,152 +1,122 @@ [ { - "pageContent": "Ticket: MedellĂ­n (MDE) → Sao Paulo (GRU). 1 stop. Airline: AndeanSky.", + "pageContent": "Legal precedent: Case A - Service delivery delay considered breach. A software development contract stipulated delivery within 'reasonable time'. A two-week delay significantly impacted the client's product launch, causing measurable financial harm. The court ruled this constituted material breach despite no explicit deadline.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Sao Paulo", - "airport_code": "GRU", - "airport_name": "Guarulhos International", - "country": "Brazil", - "airline": "AndeanSky", - "date": "2025-10-10", - "price": 480, - "time_approx": "7h 30m", - "title": "MDE → GRU (AndeanSky)" + "caseId": "CASE-A-2023", + "contractType": "service agreement", + "delayPeriod": "two weeks", + "outcome": "breach found", + "reasoning": "delay affected operations and caused financial harm", + "keyTerms": "reasonable time, material breach, timely delivery", + "title": "Case A: Delay Breach with Operational Impact" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → Sao Paulo (CGH). 1 stop. Airline: CoffeeAir.", + "pageContent": "Legal precedent: Case B - Service delay not considered breach. A consulting contract used term 'timely delivery' without specific dates. A three-week delay occurred but contract lacked explicit schedule. Court ruled no breach as parties had not defined concrete timeline and delay did not cause demonstrable harm.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Sao Paulo", - "airport_code": "CGH", - "airport_name": "Congonhas", - "country": "Brazil", - "airline": "CoffeeAir", - "date": "2025-10-10", - "price": 455, - "time_approx": "8h 05m", - "title": "MDE → CGH (CoffeeAir)" + "caseId": "CASE-B-2022", + "contractType": "consulting agreement", + "delayPeriod": "three weeks", + "outcome": "no breach found", + "reasoning": "no explicit deadline defined, no demonstrable harm", + "keyTerms": "timely delivery, open terms, schedule definition", + "title": "Case B: Delay Without Explicit Schedule" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → Tokyo (HND). 2 stops. Airline: CondorJet.", + "pageContent": "Legal precedent: Case C - Delay permitted due to justified causes. A construction service contract had defined timeline but external regulatory approval delays prevented timely completion. Court found delay was justified and did not constitute breach when causes were beyond provider's control.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Tokyo", - "airport_code": "HND", - "airport_name": "Haneda", - "country": "Japan", - "airline": "CondorJet", - "date": "2025-11-05", - "price": 1290, - "time_approx": "22h 10m", - "title": "MDE → HND (CondorJet)" + "caseId": "CASE-C-2023", + "contractType": "construction service", + "delayPeriod": "one month", + "outcome": "no breach found", + "reasoning": "external factors beyond control, force majeure applied", + "keyTerms": "justified causes, force majeure, regulatory delays", + "title": "Case C: Justified Delay External Factors" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → Tokyo (NRT). 1–2 stops. Airline: CaribeWings.", + "pageContent": "Legal precedent: Case D - Interpretation of 'prompt delivery' term. Contract stated services must be provided 'promptly'. Court analyzed industry standards and prior dealings between parties to determine reasonableness. Ten-day delay was found acceptable given industry norms for similar services.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Tokyo", - "airport_code": "NRT", - "airport_name": "Narita", - "country": "Japan", - "airline": "CaribeWings", - "date": "2025-11-05", - "price": 1215, - "time_approx": "23h 30m", - "title": "MDE → NRT (CaribeWings)" + "caseId": "CASE-D-2021", + "contractType": "service agreement", + "delayPeriod": "ten days", + "outcome": "no breach found", + "reasoning": "industry standards applied, reasonable interpretation", + "keyTerms": "prompt delivery, industry standards, reasonable time", + "title": "Case D: Prompt Delivery Industry Standards" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → New York (JFK). 1 stop. Airline: AndeanSky.", + "pageContent": "Legal precedent: Case E - Material breach vs minor delay. Service contract had approximate delivery timeline. Five-day delay occurred but service was fully functional and met all quality specifications. Court ruled this was minor breach not justifying contract termination.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "New York", - "airport_code": "JFK", - "airport_name": "John F. Kennedy International", - "country": "USA", - "airline": "AndeanSky", - "date": "2025-12-01", - "price": 340, - "time_approx": "6h 40m", - "title": "MDE → JFK (AndeanSky)" + "caseId": "CASE-E-2022", + "contractType": "service agreement", + "delayPeriod": "five days", + "outcome": "minor breach only", + "reasoning": "delay minimal, quality maintained, termination unjustified", + "keyTerms": "material breach, substantial performance, termination rights", + "title": "Case E: Minor Delay Quality Maintained" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → New York (LGA). 1 stop. Airline: CoffeeAir.", + "pageContent": "Legal precedent: Case F - Open-ended contract terms require good faith. Contract used 'timely manner' without definition. Provider took reasonable steps but faced unexpected technical issues causing delay. Court ruled parties must interpret open terms in good faith and delay was reasonable given circumstances.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "New York", - "airport_code": "LGA", - "airport_name": "LaGuardia", - "country": "USA", - "airline": "CoffeeAir", - "date": "2025-12-01", - "price": 325, - "time_approx": "6h 55m", - "title": "MDE → LGA (CoffeeAir)" + "caseId": "CASE-F-2023", + "contractType": "technology service", + "delayPeriod": "two weeks", + "outcome": "no breach found", + "reasoning": "good faith interpretation, reasonable efforts demonstrated", + "keyTerms": "timely manner, good faith, open terms interpretation", + "title": "Case F: Good Faith Open Terms" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → London (LHR). 1 stop. Airline: CondorJet.", + "pageContent": "Legal precedent: Case G - Schedule linked to milestones. Service contract defined delivery as 'upon completion of client's approval process'. Delay occurred but was directly caused by client's slow approval. Court found provider not in breach as timeline was dependent on client actions.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "London", - "airport_code": "LHR", - "airport_name": "Heathrow", - "country": "UK", - "airline": "CondorJet", - "date": "2026-01-15", - "price": 890, - "time_approx": "14h 30m", - "title": "MDE → LHR (CondorJet)" + "caseId": "CASE-G-2022", + "contractType": "professional service", + "delayPeriod": "variable", + "outcome": "no breach found", + "reasoning": "timeline dependent on client actions, conditional delivery", + "keyTerms": "milestone delivery, conditional timeline, client obligations", + "title": "Case G: Milestone Dependent Delivery" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → London (LGW). 1–2 stops. Airline: CaribeWings.", + "pageContent": "Legal precedent: Case H - Repeated delays pattern. Service provider had history of missing approximate deadlines across multiple deliverables. Court found pattern of delays constituted breach even when individual delays seemed minor, showing failure to meet contractual obligations consistently.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "London", - "airport_code": "LGW", - "airport_name": "Gatwick", - "country": "UK", - "airline": "CaribeWings", - "date": "2026-01-15", - "price": 760, - "time_approx": "15h 10m", - "title": "MDE → LGW (CaribeWings)" + "caseId": "CASE-H-2021", + "contractType": "ongoing service agreement", + "delayPeriod": "multiple instances", + "outcome": "breach found", + "reasoning": "pattern demonstrated failure to perform, cumulative effect", + "keyTerms": "repeated breach, pattern of conduct, consistent performance", + "title": "Case H: Pattern of Repeated Delays" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → Paris (CDG). 1 stop. Airline: CoffeeAir.", + "pageContent": "Legal precedent: Case I - Contractual obligation interpretation. Contract required 'expeditious service delivery'. Court examined contract as whole, prior communications, and purpose of service to interpret meaning. Two-week delay found unreasonable given urgent nature stated in preliminary negotiations.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Paris", - "airport_code": "CDG", - "airport_name": "Charles de Gaulle", - "country": "France", - "airline": "CoffeeAir", - "date": "2025-10-22", - "price": 720, - "time_approx": "13h 50m", - "title": "MDE → CDG (CoffeeAir)" + "caseId": "CASE-I-2023", + "contractType": "urgent service agreement", + "delayPeriod": "two weeks", + "outcome": "breach found", + "reasoning": "context and preliminary negotiations showed urgency expectation", + "keyTerms": "expeditious delivery, contract interpretation, preliminary negotiations", + "title": "Case I: Urgent Service Context" } }, { - "pageContent": "Ticket: MedellĂ­n (MDE) → Paris (ORY). 1 stop. Airline: AndeanSky.", + "pageContent": "Legal precedent: Case J - Provider notification obligations. Service contract had flexible timeline but required provider to notify of delays. Provider failed to communicate expected delay. Court found this failure to notify constituted breach regardless of whether delay itself was reasonable.", "metadata": { - "from_city": "MedellĂ­n", - "to_city": "Paris", - "airport_code": "ORY", - "airport_name": "Orly", - "country": "France", - "airline": "AndeanSky", - "date": "2025-10-22", - "price": 695, - "time_approx": "13h 20m", - "title": "MDE → ORY (AndeanSky)" + "caseId": "CASE-J-2022", + "contractType": "service agreement", + "delayPeriod": "one week", + "outcome": "breach found", + "reasoning": "failure to notify violated contractual communication obligations", + "keyTerms": "notification duty, communication obligations, transparency", + "title": "Case J: Notification Failure Breach" } } ] diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts index 41f3593d..1828b1c0 100644 --- a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts +++ b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/main.ts @@ -10,9 +10,9 @@ import { ElasticVectorSearch } from "@langchain/community/vectorstores/elasticse import { Client } from "@elastic/elasticsearch"; import { writeFileSync } from "node:fs"; import readline from "node:readline"; -import { ingestData, Document, DocumentMetadata } from "./dataIngestion.ts"; +import { ingestData, Document } from "./dataIngestion.ts"; -const VECTOR_INDEX = "flights-offerings"; +const VECTOR_INDEX = "legal-precedents"; const llm = new ChatOpenAI({ model: "gpt-4o-mini" }); const embeddings = new OpenAIEmbeddings({ @@ -20,9 +20,9 @@ const embeddings = new OpenAIEmbeddings({ }); const esClient = new Client({ - node: process.env.ELASTICSEARCH_ENDPOINT!, + node: process.env.ELASTICSEARCH_ENDPOINT, auth: { - apiKey: process.env.ELASTICSEARCH_API_KEY!, + apiKey: process.env.ELASTICSEARCH_API_KEY ?? "", }, }); @@ -31,141 +31,274 @@ const vectorStore = new ElasticVectorSearch(embeddings, { indexName: VECTOR_INDEX, }); -// Define the state schema for application workflow -const SupportState = Annotation.Root({ - input: Annotation(), - candidates: Annotation(), - userChoice: Annotation(), - selected: Annotation(), - final: Annotation(), +// Define the state schema for legal research workflow +const LegalResearchState = Annotation.Root({ + query: Annotation(), + precedents: Annotation(), + selectedPrecedent: Annotation(), + draftAnalysis: Annotation(), + ambiguityDetected: Annotation(), + userClarification: Annotation(), + finalAnalysis: Annotation(), }); -// Node 1: Retrieve data from Elasticsearch -async function retrieveFlights(state: typeof SupportState.State) { - const results = await vectorStore.similaritySearch(state.input, 2); - const candidates = results.map((d) => d as Document); - - console.log(`đź“‹ Found ${candidates.length} different flights`); - return { candidates }; -} - -// Node 2: Evaluate if there are 1 or multiple responses -function evaluateResults(state: typeof SupportState.State) { - const candidates = state.candidates || []; - - // If there is 1 result, auto-select it - if (candidates.length === 1) { - const metadata = candidates[0].metadata || {}; - - return { - selected: candidates[0], - final: formatFlightDetails(metadata), - }; +// Node 1: Search for relevant legal precedents +async function searchPrecedents(state: typeof LegalResearchState.State) { + console.log( + "📚 Searching for relevant legal precedents with query:\n", + state.query + ); + + const results = await vectorStore.similaritySearch(state.query, 5); + const precedents = results.map((d) => d as Document); + + console.log(`Found ${precedents.length} relevant precedents:\n`); + + for (let i = 0; i < precedents.length; i++) { + const p = precedents[i]; + const m = p.metadata; + console.log( + `${i + 1}. ${m.title} (${m.caseId})\n` + + ` Type: ${m.contractType}\n` + + ` Outcome: ${m.outcome}\n` + + ` Key reasoning: ${m.reasoning}\n` + + ` Delay period: ${m.delayPeriod}\n` + ); } - return { candidates }; + return { precedents }; } -// Node 3: Request user choice (separate from showing) -function requestUserChoice() { +// Node 2: HITL #1 - Request lawyer to select most relevant precedent +function precedentSelection(state: typeof LegalResearchState.State) { + console.log("\n⚖️ HITL #1: Human input needed\n"); const userChoice = interrupt({ - question: `Which flight do you prefer?:`, + question: "👨‍⚖️ Which precedent is most similar to your case? ", }); - return { userChoice }; } -// Node 4: Disambiguate user choice and provide final answer -async function disambiguateAndAnswer(state: typeof SupportState.State) { - const candidates = state.candidates || []; - const userInput = state.userChoice || ""; +// Node 3: Process precedent selection +async function selectPrecedent(state: typeof LegalResearchState.State) { + const precedents = state.precedents || []; + const userInput = (state as any).userChoice || ""; + + const precedentsList = precedents + .map((p, i) => { + const m = p.metadata; + return `${i + 1}. ${m.caseId}: ${m.title} - ${m.outcome}`; + }) + .join("\n"); + + const structuredLlm = llm.withStructuredOutput({ + name: "precedent_selection", + schema: { + type: "object", + properties: { + selected_number: { + type: "number", + description: + "The precedent number selected by the lawyer (1-based index)", + minimum: 1, + maximum: precedents.length, + }, + }, + required: ["selected_number"], + }, + }); const prompt = ` - Based on the user's response: "${userInput}" + The lawyer said: "${userInput}" + + Available precedents: + ${precedentsList} + + Which precedent number (1-${precedents.length}) matches their selection? + `; + + const response = await structuredLlm.invoke([ + { + role: "system", + content: + "You are an assistant that interprets lawyer's selection and returns the corresponding precedent number.", + }, + { role: "user", content: prompt }, + ]); + + const selectedIndex = response.selected_number - 1; + const selectedPrecedent = precedents[selectedIndex] || precedents[0]; + + console.log(`âś… Selected: ${selectedPrecedent.metadata.title}\n`); + return { selectedPrecedent }; +} - These are the available flights: - ${candidates - .map( - (d, i) => - `${i}. ${d.metadata?.title} - ${d.metadata?.to_city} (${d.metadata?.airport_code}) - ${d.metadata?.airline} - $${d.metadata?.price} - ${d.metadata?.time_approx}` - ) - .join("\n")} +// Node 4: Draft initial legal analysis +async function createDraft(state: typeof LegalResearchState.State) { + console.log("📝 Drafting initial legal analysis...\n"); + + const precedent = state.selectedPrecedent; + if (!precedent) return { draftAnalysis: "" }; + + const m = precedent.metadata; + + const structuredLlm = llm.withStructuredOutput({ + name: "draft_analysis", + schema: { + type: "object", + properties: { + needs_clarification: { + type: "boolean", + description: + "Whether the analysis requires clarification about contract terms or context", + }, + analysis_text: { + type: "string", + description: "The draft legal analysis or the ambiguity explanation", + }, + missing_information: { + type: "array", + items: { type: "string" }, + description: + "List of specific information needed if clarification is required (empty if no clarification needed)", + }, + }, + required: ["needs_clarification", "analysis_text", "missing_information"], + }, + }); - Which flight is the user selecting? Respond ONLY with the flight number (1, 2, or 3). + const prompt = ` + Based on this precedent: + Case: ${m.title} + Outcome: ${m.outcome} + Reasoning: ${m.reasoning} + Key terms: ${m.keyTerms} + + And the lawyer's question: "${state.query}" + + Draft a legal analysis applying this precedent to the question. + + If you need more context about the specific contract terms, timeline details, + or other critical information to provide accurate analysis, set needs_clarification + to true and list what information is missing. + + Otherwise, provide the legal analysis directly. `; - const llmResponse = await llm.invoke([ + const response = await structuredLlm.invoke([ { role: "system", content: - "You are an assistant that interprets user selection. Respond ONLY with the selected flight number.", + "You are a legal research assistant that analyzes cases and identifies when additional context is needed.", }, { role: "user", content: prompt }, ]); - const selectedNumber = Number.parseInt(llmResponse.content as string, 10); // Convert to zero-based index - const selectedFlight = candidates[selectedNumber] ?? candidates[0]; // Fallback to first option + let displayText: string; + if (response.needs_clarification) { + const missingInfoList = response.missing_information + .map((info: string, i: number) => `${i + 1}. ${info}`) + .join("\n"); + displayText = `AMBIGUITY DETECTED:\n${response.analysis_text}\n\nMissing information:\n${missingInfoList}`; + } else { + displayText = `ANALYSIS:\n${response.analysis_text}`; + } + + console.log(displayText + "\n"); return { - selected: selectedFlight, - final: formatFlightDetails(selectedFlight.metadata), + draftAnalysis: displayText, + ambiguityDetected: response.needs_clarification, }; } -// Node 5: Show results only -function showResults(state: typeof SupportState.State) { - const candidates = state.candidates || []; - const formattedOptions = candidates - .map((d: Document, index: number) => { - const m = d.metadata || {}; +// Node 5: HITL #2 - Request clarification from lawyer +function requestClarification(state: typeof LegalResearchState.State) { + console.log("\n⚖️ HITL #2: Additional context needed\n"); + const userClarification = interrupt({ + question: "👨‍⚖️ Please provide clarification about your contract terms:", + }); + return { userClarification }; +} - return `${index + 1}. ${m.title} - ${m.to_city} - ${m.airport_name}(${ - m.airport_code - }) airport - ${m.airline} - $${m.price} - ${m.time_approx}`; - }) - .join("\n"); +// Node 6: Generate final analysis with clarification +async function generateFinalAnalysis(state: typeof LegalResearchState.State) { + console.log("đź“‹ Generating final legal analysis...\n"); - console.log(`\nđź“‹ Flights found:\n${formattedOptions}\n`); + const precedent = state.selectedPrecedent; + if (!precedent) return { finalAnalysis: "" }; - return state; -} + const m = precedent.metadata; -// Helper function to format flight details -function formatFlightDetails(metadata: DocumentMetadata): string { - return `Selected flight: ${metadata.title} - ${metadata.airline} - From: ${metadata.from_city} (${ - metadata.from_city?.slice(0, 3).toUpperCase() || "N/A" - }) - To: ${metadata.to_city} (${metadata.airport_code}) - Airport: ${metadata.airport_name} - Price: $${metadata.price} - Duration: ${metadata.time_approx} - Date: ${metadata.date}`; + const prompt = ` + Original question: "${state.query}" + + Selected precedent: ${m.title} + Outcome: ${m.outcome} + Reasoning: ${m.reasoning} + + Lawyer's clarification: "${state.userClarification}" + + Provide a comprehensive legal analysis integrating: + 1. The selected precedent's reasoning + 2. The lawyer's specific contract context + 3. Conditions for breach vs. no breach + 4. Practical recommendations + `; + + const response = await llm.invoke([ + { + role: "system", + content: + "You are a legal research assistant providing comprehensive analysis.", + }, + { role: "user", content: prompt }, + ]); + + const finalAnalysis = response.content as string; + + console.log( + "\n" + + "=".repeat(80) + + "\n" + + "⚖️ FINAL LEGAL ANALYSIS\n" + + "=".repeat(80) + + "\n\n" + + finalAnalysis + + "\n\n" + + "=".repeat(80) + + "\n" + ); + + return { finalAnalysis }; } -// Build the graph -const workflow = new StateGraph(SupportState) - .addNode("retrieveFlights", retrieveFlights) - .addNode("evaluateResults", evaluateResults) - .addNode("showResults", showResults) - .addNode("requestUserChoice", requestUserChoice) - .addNode("disambiguateAndAnswer", disambiguateAndAnswer) - .addEdge("__start__", "retrieveFlights") - .addEdge("retrieveFlights", "evaluateResults") +// Build the legal research workflow graph +const workflow = new StateGraph(LegalResearchState) + .addNode("searchPrecedents", searchPrecedents) + .addNode("precedentSelection", precedentSelection) + .addNode("selectPrecedent", selectPrecedent) + .addNode("createDraft", createDraft) + .addNode("requestClarification", requestClarification) + .addNode("generateFinalAnalysis", generateFinalAnalysis) + .addEdge("__start__", "searchPrecedents") + .addEdge("searchPrecedents", "precedentSelection") // HITL #1 + .addEdge("precedentSelection", "selectPrecedent") + .addEdge("selectPrecedent", "createDraft") .addConditionalEdges( - "evaluateResults", - (state: typeof SupportState.State) => { - if (state.final) return "complete"; // 0 or 1 result - return "multiple"; // multiple results + "createDraft", + (state: typeof LegalResearchState.State) => { + // If ambiguity detected, request clarification (HITL #2) + if (state.ambiguityDetected) return "needsClarification"; + // Otherwise, generate final analysis + return "final"; }, { - complete: "__end__", - multiple: "showResults", + needsClarification: "requestClarification", + final: "generateFinalAnalysis", } ) - .addEdge("showResults", "requestUserChoice") - .addEdge("requestUserChoice", "disambiguateAndAnswer") - .addEdge("disambiguateAndAnswer", "__end__"); + .addEdge("requestClarification", "generateFinalAnalysis") // HITL #2 + .addEdge("generateFinalAnalysis", "__end__"); /** * Get user input from the command line @@ -208,34 +341,37 @@ async function saveGraphImage(app: any): Promise { * Main execution function */ async function main() { - // Ingest data await ingestData(); // Compile workflow const app = workflow.compile({ checkpointer: new MemorySaver() }); - const config = { configurable: { thread_id: "hitl-thread" } }; + const config = { configurable: { thread_id: "hitl-circular-thread" } }; - // Save graph image await saveGraphImage(app); // Execute workflow - const question = "Flights to Tokyo"; // User query - console.log(`🔍 SEARCHING USER QUESTION: "${question}"\n`); + const legalQuestion = + "Does a pattern of repeated delays constitute breach even if each individual delay is minor?"; + + console.log(`⚖️ LEGAL QUESTION: "${legalQuestion}"\n`); - let currentState = await app.invoke({ input: question }, config); + let currentState = await app.invoke({ query: legalQuestion }, config); - // Handle interruption - if ((currentState as any).__interrupt__?.length > 0) { + // Handle all interruptions in a loop + while ((currentState as any).__interrupt__?.length > 0) { console.log("\nđź’­ APPLICATION PAUSED WAITING FOR USER INPUT..."); - const userChoice = await getUserInput("👤 CHOICE ONE OPTION: "); + + const interruptQuestion = (currentState as any).__interrupt__[0]?.value + ?.question; + const userChoice = await getUserInput( + interruptQuestion || "👤 YOUR CHOICE: " + ); currentState = await app.invoke( new Command({ resume: userChoice }), config ); } - - console.log("\nâś… Final result: \n", currentState.final); } // Run main function diff --git a/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/workflow_graph.png b/supporting-blog-content/human-in-the-loop-with-langgraph-and-elasticsearch/workflow_graph.png index 2f857e3bfe23021da5a4f5b199c3bbcf4bf25c58..33ba812eb95047ca7e333bcbecc14058d63df3ff 100644 GIT binary patch literal 29690 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≦O&*#AI9pa9`f76L;Feqbhm5uNfjafltHBt`z2 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 z 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 Y-0yHXHhTg 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 ZM!=Oz#qDcL_6J)K