Create Retrieval Graph Draft

This commit is contained in:
William Fu-Hinthorn
2024-08-25 22:42:34 -07:00
parent 6068fc2b04
commit c427163ff4
15 changed files with 541 additions and 113 deletions
-1
View File
@@ -2,7 +2,6 @@
This repo offers the basic code structure to get started building LangGraph workflows in JavaScript within LangGraph studio.
## Repo Structure
```txt
+3 -2
View File
@@ -1,9 +1,10 @@
{
"node_version": "v20.16.0",
"node_version": "20",
"dockerfile_lines": [],
"dependencies": ["."],
"graphs": {
"agent": "./graph.ts:graph"
"retrieval_graph": "./retrieval-graph/graph.ts:graph",
"indexer": "./retrieval-graph/index_graph.ts:graph"
},
"env": ".env"
}
-67
View File
@@ -1,67 +0,0 @@
/**
* Empty LangGraph Template
*
* Make this code your own!
*/
import { StateGraph, Annotation } from "@langchain/langgraph";
/**
* The State defines three things:
* 1. The structure of the graph's state (which "channels" are available to read/write)
* 2. The default values for the state's channels
* 3. The reducers for the state's channels. Reducers are functions that determine how to apply updates to the state.
* See [Reducers](https://langchain-ai.github.io/langgraphjs/concepts/low_level/#reducers) for more information.
*/
const State = Annotation.Root({
// Example of a channel that will be replaced any time
// it is written to
input: Annotation<string>(),
// Example of a channel that is "append-only"
stringList: Annotation<string[]>({
reducer: (x: string[], y: string[]) => x.concat(y),
default: () => [],
}),
});
type StateT = typeof State.State;
// Define nodes, these do the work:
const callModel = async (state: StateT) => {
// Do some work... (e.g. call an LLM)
return { stringList: [state.input, "b", "c"] };
};
// Define conditional edge logic:
/**
* Routing function: Determines whether to continue research or end the workflow.
* This function decides if the gathered information is satisfactory or if more research is needed.
*
* @param state - The current state of the research workflow
* @returns Either "callModel" to continue research or END to finish the workflow
*/
export const _route = (state: StateT): "__end__" | "callModel" => {
if (state.stringList.length > 0) {
return "__end__";
}
// Loop back
return "callModel";
};
// Finally, create the graph itself.
const workflow = new StateGraph(State)
// Add the nodes to do the work.
// Chaining the nodes together in this way
// updates the types of the StateGraph instance
// so you have static type checking when it comes time
// to add the edges.
.addNode("callModel", callModel)
// Regular edges mean "always transition to node B after node A is done"
// The "__start__" and "__end__" nodes are "virtual" nodes that are always present
// and represent the beginning and end of the workflow.
.addEdge("__start__", "callModel")
.addConditionalEdges("callModel", _route);
export const graph: any = workflow.compile();
+7 -1
View File
@@ -15,9 +15,15 @@
"format": "prettier --write ."
},
"dependencies": {
"@langchain/langgraph": "^0.0.34",
"@elastic/elasticsearch": "^8.15.0",
"@langchain/community": "^0.2.31",
"@langchain/langgraph": "^0.1.1",
"langchain": "^0.2.17",
"ts-node": "^10.9.2"
},
"resolutions": {
"@langchain/core": "^0.2.28"
},
"devDependencies": {
"@langchain/openai": "^0.2.7",
"@tsconfig/recommended": "^1.0.7",
+101
View File
@@ -0,0 +1,101 @@
import { initChatModel } from "langchain/chat_models/universal";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RunnableConfig } from "@langchain/core/runnables";
import { StateGraph } from "@langchain/langgraph";
import { ensureConfigurable } from "./utils/configuration.js";
import { makeRetriever, State, StateT } from "./utils/state.js";
import { formatDocs, getMessageText } from "./utils/utils.js";
import { z } from "zod";
// Define the function that calls the model
const SearchQuery = z.object({
query: z.string().describe("Search the indexed documents for a query."),
});
async function generateQuery(
state: StateT,
config?: RunnableConfig,
): Promise<{ queries: string[] }> {
const messages = state.messages;
if (messages.length === 1) {
// It's the first user question. We will use the input directly to search.
const humanInput = getMessageText(messages[messages.length - 1]);
return { queries: [humanInput] };
} else {
const configuration = ensureConfigurable(config);
// Feel free to customize the prompt, model, and other logic!
const prompt = ChatPromptTemplate.fromMessages([
["system", configuration.querySystemPrompt],
["placeholder", "{messages}"],
]);
const model = (
await initChatModel(configuration.responseModelName)
).withStructuredOutput(SearchQuery);
const messageValue = await prompt.invoke(
{
...state,
queries: (state.queries || []).join("\n- "),
systemTime: new Date().toISOString(),
},
config,
);
const generated = await model.invoke(messageValue, config);
return {
queries: [generated.query],
};
}
}
async function retrieve(
state: StateT,
config: RunnableConfig,
): Promise<{ retrievedDocs: any[] }> {
const query = state.queries[state.queries.length - 1];
const retriever = await makeRetriever(config);
const response = await retriever.invoke(query, config);
return { retrievedDocs: response };
}
async function respond(state: StateT, config: RunnableConfig) {
/**
* Call the LLM powering our "agent".
*/
const configuration = ensureConfigurable(config);
// Feel free to customize the prompt, model, and other logic!
const prompt = ChatPromptTemplate.fromMessages([
["system", configuration.responseSystemPrompt],
["placeholder", "{messages}"],
]);
const model = await initChatModel(configuration.responseModelName);
const retrievedDocs = formatDocs(state.retrievedDocs);
const messageValue = await prompt.invoke(
{
...state,
retrievedDocs,
systemTime: new Date().toISOString(),
},
config,
);
const response = await model.invoke(messageValue, config);
// We return a list, because this will get added to the existing list
return { messages: [response] };
}
// Define a new graph (It's just a pipe)
const builder = new StateGraph(State)
.addNode("generateQuery", generateQuery)
.addNode("retrieve", retrieve)
.addNode("respond", respond)
.addEdge("__start__", "generateQuery")
.addEdge("generateQuery", "retrieve")
.addEdge("retrieve", "respond");
// Finally, we compile it!
// This compiles it into a graph you can invoke and deploy.
export const graph = builder.compile({
interruptBefore: [], // if you want to update the state before calling the tools
interruptAfter: [],
});
+47
View File
@@ -0,0 +1,47 @@
/**
* This "graph" simply exposes an endpoint for a user to upload docs to be indexed.
*/
import { Document } from "@langchain/core/documents";
import { RunnableConfig } from "@langchain/core/runnables";
import { StateGraph } from "@langchain/langgraph";
import { IndexState, IndexStateT, makeRetriever } from "./utils/state.js";
function ensureDocsHaveUserId(
docs: Document[],
config: RunnableConfig,
): Document[] {
const userId = config?.configurable?.user_id;
return docs.map((doc) => {
return new Document({
pageContent: doc.pageContent,
metadata: { ...doc.metadata, user_id: userId },
});
});
}
async function indexDocs(
state: IndexStateT,
config?: RunnableConfig,
): Promise<{ docs: string }> {
if (!config) {
throw new Error("Configuration required to run index_docs.");
}
const docs = state["docs"];
const retriever = await makeRetriever(config);
const stampedDocs = ensureDocsHaveUserId(docs, config);
await retriever.addDocuments(stampedDocs);
return { docs: "delete" };
}
// Define a new graph
const builder = new StateGraph(IndexState)
.addNode("indexDocs", indexDocs)
.addEdge("__start__", "indexDocs");
// Finally, we compile it!
// This compiles it into a graph you can invoke and deploy.
export const graph = builder.compile();
View File
+63
View File
@@ -0,0 +1,63 @@
/**
* Define the configurable parameters for the agent.
*/
import { RunnableConfig } from "@langchain/core/runnables";
export interface IndexConfiguration {
embeddingModelName: string;
searchKwargs: Record<string, any>;
userId: string;
}
export function ensureIndexConfigurable(
config: RunnableConfig | undefined = undefined,
): IndexConfiguration {
// Ensure the defaults are populated.
const configurable = (config?.configurable || {}) as Record<string, any>;
return {
userId: configurable.userId,
embeddingModelName:
configurable.embeddingModelName || "text-embedding-3-small",
searchKwargs: configurable.searchKwargs || {},
};
}
interface Configuration extends IndexConfiguration {
responseSystemPrompt: string;
responseModelName: string;
querySystemPrompt: string;
queryModelName: string;
threadId: string;
}
export function ensureConfigurable(
config: RunnableConfig | undefined = undefined,
): Configuration {
// Ensure the defaults are populated.
const configurable = (config?.configurable || {}) as Record<string, any>;
return {
userId: configurable.userId,
threadId: configurable.threadId,
responseSystemPrompt:
configurable.responseSystemPrompt ||
"You are a helpful AI assistant. Answer the user's questions based on the retrieved documents." +
"\n\n{retrievedDocs}" +
"\n\nSystem time: {systemTime}",
responseModelName:
configurable.responseModelName || "claude-3-5-sonnet-20240620",
querySystemPrompt:
configurable.querySystemPrompt ||
"Generate search queries to retrieve documents that may help answer the user's question." +
"\n\nPreviously, you made the following queries:<previousQueries/>" +
"\n{queries}\n<\\previousQueries/>\n\nSystem time: {systemTime}",
queryModelName:
configurable.queryModelName ||
"accounts/fireworks/models/firefunction-v2",
// In general, you could make these things nested configs and load from a file to get the
// defaults. But for now, we'll keep it simple.
embeddingModelName:
configurable.embeddingModelName || "text-embedding-3-small",
searchKwargs: configurable.searchKwargs || {},
};
}
+103
View File
@@ -0,0 +1,103 @@
import { BaseMessage } from "@langchain/core/messages";
import { RunnableConfig } from "@langchain/core/runnables";
import { Annotation } from "@langchain/langgraph";
import { messagesStateReducer } from "@langchain/langgraph";
import { v4 as uuidv4 } from "uuid";
import { Client } from "@elastic/elasticsearch";
import { OpenAIEmbeddings } from "@langchain/openai";
import { ElasticVectorSearch } from "@langchain/community/vectorstores/elasticsearch";
import {
VectorStoreRetriever,
} from "@langchain/core/vectorstores";
import { Document } from "@langchain/core/documents";
import { ensureConfigurable } from "./configuration.js";
export function reduceDocs(
existing?: Document[],
newDocs?:
| Document[]
| { [key: string]: any }[]
| string[]
| string
| "delete",
) {
if (newDocs === "delete") {
return [];
}
if (typeof newDocs === "string") {
return [{ pageContent: newDocs, metadata: { id: uuidv4() } }];
}
if (Array.isArray(newDocs)) {
const coerced: Document[] = [];
for (const item of newDocs) {
if (typeof item === "string") {
coerced.push({ pageContent: item, metadata: { id: uuidv4() } });
} else if (typeof item === "object") {
coerced.push(item as Document);
}
}
return coerced;
}
return existing || [];
}
export async function makeRetriever(
config: RunnableConfig,
): Promise<VectorStoreRetriever> {
const configuration = ensureConfigurable(config);
const embeddingModel = new OpenAIEmbeddings({
model: configuration.embeddingModelName,
});
const userId = configuration.userId;
if (!userId) {
throw new Error("Please provide a valid user_id in the configuration.");
}
const client = new Client({
node: process.env.ELASTICSEARCH_URL,
auth: {
apiKey: process.env.ELASTICSEARCH_API_KEY || "",
},
});
const vectorStore = new ElasticVectorSearch(embeddingModel, {
client,
indexName: "langchain_index",
});
const searchKwargs = configuration.searchKwargs || {};
searchKwargs.filter = searchKwargs.filter || [];
searchKwargs.filter.push({ term: { "metadata.user_id": userId } });
return vectorStore.asRetriever({ searchKwargs });
}
export const IndexState = Annotation.Root({
docs: Annotation<Document[], Document[] | string | string[]>({
reducer: reduceDocs,
default: () => [],
}),
});
export type IndexStateT = typeof IndexState.State;
export function addQueries(existing: string[], newQueries: string[]): string[] {
return [...existing, ...newQueries];
}
/**
* The State defines three things:
* 1. The structure of the graph's state (which "channels" are available to read/write)
* 2. The default values for the state's channels
* 3. The reducers for the state's channels. Reducers are functions that determine how to apply updates to the state.
* See [Reducers](https://langchain-ai.github.io/langgraphjs/concepts/low_level/#reducers) for more information.
*/
export const State = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: messagesStateReducer,
default: () => [],
}),
queries: Annotation<string[]>({ reducer: addQueries, default: () => [] }),
retrievedDocs: Annotation<Document[]>,
});
export type StateT = typeof State.State;
+34
View File
@@ -0,0 +1,34 @@
import { Document } from "langchain/document";
import { BaseMessage } from "@langchain/core/messages";
export function getMessageText(msg: BaseMessage): string {
/**Get the text content of a message. */
const content = msg.content;
if (typeof content === "string") {
return content;
} else {
const txts = (content as any[]).map((c) =>
typeof c === "string" ? c : c.text || "",
);
return txts.join("").trim();
}
}
export function formatDoc(doc: Document): string {
const metadata = doc.metadata || {};
const meta = Object.entries(metadata)
.map(([k, v]) => ` ${k}=${v}`)
.join("");
const metaStr = meta ? ` ${meta}` : "";
return `<document${metaStr}>\n${doc.pageContent}\n</document>`;
}
export function formatDocs(docs?: Document[]): string {
/**Format a list of documents as XML. */
if (!docs || docs.length === 0) {
return "<documents></documents>";
}
const formatted = docs.map(formatDoc).join("\n");
return `<documents>\n${formatted}\n</documents>`;
}
+2 -6
View File
@@ -1,8 +1,4 @@
import { describe, it, expect } from "@jest/globals";
import { graph } from "../../my-app/graph.js";
import { describe, it } from "@jest/globals";
describe("Researcher", () => {
it("Simple runthrough", async () => {
const res = await graph.invoke({ input: "ExampleInput" });
expect(res.stringList).toEqual(["ExampleInput", "b", "c"]);
}, 100_000);
it("Simple runthrough", async () => {}, 100_000);
});
+2 -6
View File
@@ -1,8 +1,4 @@
import { describe, it, expect } from "@jest/globals";
import { _route } from "../../my-app/graph.js";
import { describe, it } from "@jest/globals";
describe("Routers", () => {
it("Test route", async () => {
const res = _route({ input: "ExampleInput", stringList: [] });
expect(res).toEqual("callModel");
}, 100_000);
it("Test route", async () => {}, 100_000);
});
-1
View File
@@ -6,7 +6,6 @@
"module": "NodeNext",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"declaration": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
+179 -29
View File
@@ -298,6 +298,27 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@elastic/elasticsearch@^8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.15.0.tgz#cb29b3ae33203c545d435cf3dc4b557c8b4961d5"
integrity sha512-mG90EMdTDoT6GFSdqpUAhWK9LGuiJo6tOWqs0Usd/t15mPQDj7ZqHXfCBqNkASZpwPZpbAYVjd57S6nbUBINCg==
dependencies:
"@elastic/transport" "^8.7.0"
tslib "^2.4.0"
"@elastic/transport@^8.7.0":
version "8.7.1"
resolved "https://registry.yarnpkg.com/@elastic/transport/-/transport-8.7.1.tgz#b380f0b90ee98ff84892c0958b94477cfbf84a05"
integrity sha512-2eeMVkz57Ayxv+UAZkIKzzrUu7nm96jr3+N3kLfbBqALYe2jwDpLr9pR0jc/x9HyJKAM909YGaNlHFDZeb0+Mw==
dependencies:
"@opentelemetry/api" "1.x"
debug "^4.3.4"
hpagent "^1.0.0"
ms "^2.1.3"
secure-json-parse "^2.4.0"
tslib "^2.4.0"
undici "^6.12.0"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -546,16 +567,33 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@langchain/core@>=0.2.20 <0.3.0", "@langchain/core@>=0.2.26 <0.3.0":
version "0.2.27"
resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.2.27.tgz#ee05b3e55954b9369b968b9faa9c2e5df121e86a"
integrity sha512-QAIlGxXWW7fox1oGmQjEHs1fbPaXOE9CeunmwZl9grFpu1igdkLbKnEJF7fjbVchyJHRB6yzpQ1bwP/S12O4mQ==
"@langchain/community@^0.2.31":
version "0.2.31"
resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.2.31.tgz#4b5ae3ea1e1f694d3c5323f2bf32c1a141b09e57"
integrity sha512-UayfsFyxHBLGnc9nODLupC46lvTMssYkfmFalMKqWAWQLWPEKOcDriy8Dg8+0MBME/y7SzqlCniEeEvml16hog==
dependencies:
"@langchain/core" ">=0.2.21 <0.3.0"
"@langchain/openai" ">=0.2.0 <0.3.0"
binary-extensions "^2.2.0"
expr-eval "^2.0.2"
flat "^5.0.2"
js-yaml "^4.1.0"
langchain "~0.2.3"
langsmith "~0.1.30"
uuid "^10.0.0"
zod "^3.22.3"
zod-to-json-schema "^3.22.5"
"@langchain/core@>0.2.0 <0.3.0", "@langchain/core@>=0.2.20 <0.3.0", "@langchain/core@>=0.2.21 <0.3.0", "@langchain/core@>=0.2.26 <0.3.0", "@langchain/core@^0.2.28":
version "0.2.28"
resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.2.28.tgz#4b1653bbc2fb529ba9483678dcc37db1951bcb13"
integrity sha512-xN3+UdfxFaBcm29auMHFHGEYRh+3HwBc/dICHtwfk2wTSmw4HzWmBtZMx3BG+TOgh5Et7+mT6eF6E3omDLfk+A==
dependencies:
ansi-styles "^5.0.0"
camelcase "6"
decamelize "1.2.0"
js-tiktoken "^1.0.12"
langsmith "~0.1.39"
langsmith "^0.1.43"
mustache "^4.2.0"
p-queue "^6.6.2"
p-retry "4"
@@ -563,16 +601,33 @@
zod "^3.22.4"
zod-to-json-schema "^3.22.3"
"@langchain/langgraph@^0.0.34":
version "0.0.34"
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.0.34.tgz#1504c29ce524d08d6f076c34e0623c6de1f1246c"
integrity sha512-cuig46hGmZkf+eXw1Cx2CtkAWgsAbIpa5ABLxn9oe1rbtvHXmfekqHZA6tGE0DipEmsN4H64zFcDEJydll6Sdw==
"@langchain/langgraph-checkpoint-sqlite@~0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@langchain/langgraph-checkpoint-sqlite/-/langgraph-checkpoint-sqlite-0.0.1.tgz#6eb46934f6767a6509d2dc812cf8940dc076b684"
integrity sha512-GaZo/rMS9WCO11FdYgO/omCmYnk50zjKdsxPiEKMkorXkPDLuMIgIEfUs5VKc0PMclvFfSNzX8gmvp8Kwk5MpA==
dependencies:
"@langchain/langgraph-checkpoint" "~0.0.1"
"@langchain/langgraph-checkpoint@~0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-0.0.1.tgz#ef0a61df0e3763864891fe87dfe875bf01b5be12"
integrity sha512-RmAw6K7B2293Eu0ikxatzIwxRgD2p6E6PfYlJldTX15TJyFANMreW7A6Qnx4SmxmmFFoH5LtITeqSF4SdXfyvg==
dependencies:
uuid "^10.0.0"
"@langchain/langgraph@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.1.1.tgz#1a50669ea9ecfecb83154108ede7a15226f59692"
integrity sha512-yzgyqhTBUSKtQY0s3w9lojU04hj5t8KnfQNwRjz29fHCB4pOrzCPMe2OcWhGo08tJ+Rjc/IoY8D+O20/BlMxOg==
dependencies:
"@langchain/core" ">=0.2.20 <0.3.0"
"@langchain/langgraph-checkpoint" "~0.0.1"
"@langchain/langgraph-checkpoint-sqlite" "~0.0.1"
double-ended-queue "^2.1.0-0"
uuid "^10.0.0"
zod "^3.23.8"
"@langchain/openai@^0.2.7":
"@langchain/openai@>=0.1.0 <0.3.0", "@langchain/openai@>=0.2.0 <0.3.0", "@langchain/openai@^0.2.7":
version "0.2.7"
resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.2.7.tgz#5a1ca6ae2c61e1836e24181faa891adb79dc978c"
integrity sha512-f2XDXbExJf4SYsy17QSiq0YY/UWJXhJwoiS8uRi/gBa20zBQ8+bBFRnb9vPdLkOkGiaTy+yXZVFro3a9iW2r3w==
@@ -583,6 +638,19 @@
zod "^3.22.4"
zod-to-json-schema "^3.22.3"
"@langchain/textsplitters@~0.0.0":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@langchain/textsplitters/-/textsplitters-0.0.3.tgz#1a3cc93dd2ab330edb225400ded190a22fea14e3"
integrity sha512-cXWgKE3sdWLSqAa8ykbCcUsUF1Kyr5J3HOWYGuobhPEycXW4WI++d5DhzdpL238mzoEXTi90VqfSCra37l5YqA==
dependencies:
"@langchain/core" ">0.2.0 <0.3.0"
js-tiktoken "^1.0.12"
"@opentelemetry/api@1.x":
version "1.9.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe"
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
"@sinclair/typebox@^0.27.8":
version "0.27.8"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
@@ -726,10 +794,10 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
"@types/uuid@^9.0.1":
version "9.0.8"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba"
integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==
"@types/uuid@^10.0.0":
version "10.0.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d"
integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==
"@types/yargs-parser@*":
version "21.0.3"
@@ -820,6 +888,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
async@^3.2.3:
version "3.2.6"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
@@ -903,6 +976,11 @@ base64-js@^1.5.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
binary-extensions@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1098,7 +1176,7 @@ cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
version "4.3.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b"
integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==
@@ -1140,6 +1218,11 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
double-ended-queue@^2.1.0-0:
version "2.1.0-0"
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
integrity sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==
ejs@^3.1.10:
version "3.1.10"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
@@ -1230,6 +1313,11 @@ expect@^29.0.0, expect@^29.7.0:
jest-message-util "^29.7.0"
jest-util "^29.7.0"
expr-eval@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expr-eval/-/expr-eval-2.0.2.tgz#fa6f044a7b0c93fde830954eb9c5b0f7fbc7e201"
integrity sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
@@ -1264,6 +1352,11 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
form-data-encoder@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040"
@@ -1360,6 +1453,11 @@ hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
hpagent@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-1.2.0.tgz#0ae417895430eb3770c03443456b8d90ca464903"
integrity sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==
html-escaper@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
@@ -1881,6 +1979,13 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -1896,22 +2001,47 @@ json5@^2.2.3:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jsonpointer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559"
integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==
kleur@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
langsmith@~0.1.39:
version "0.1.42"
resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.1.42.tgz#581783097508da9e3fffb3a4e0397db54752cacb"
integrity sha512-P7o8sEkWVh009XFMm23hJ8yy4h6cNBw0vFxPw2uUS8KSF2tjgDDGlBU6SYXfemho4zucWAwONclnjU84HwYpFw==
langchain@^0.2.17, langchain@~0.2.3:
version "0.2.17"
resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.2.17.tgz#c408d5f70e817f335511f79ad53db2addfadb278"
integrity sha512-wFn7wo+XGzqYrv3KJLmMZ1M6BHx12C3YUSASOa03rcDsBzRL5onxhKAC/g4xAIqlAHrJYgU6Jb/T/S6uJ6UdkQ==
dependencies:
"@types/uuid" "^9.0.1"
"@langchain/core" ">=0.2.21 <0.3.0"
"@langchain/openai" ">=0.1.0 <0.3.0"
"@langchain/textsplitters" "~0.0.0"
binary-extensions "^2.2.0"
js-tiktoken "^1.0.12"
js-yaml "^4.1.0"
jsonpointer "^5.0.1"
langsmith "~0.1.40"
openapi-types "^12.1.3"
p-retry "4"
uuid "^10.0.0"
yaml "^2.2.1"
zod "^3.22.4"
zod-to-json-schema "^3.22.3"
langsmith@^0.1.43, langsmith@~0.1.30, langsmith@~0.1.40:
version "0.1.47"
resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.1.47.tgz#9c29acac104c63cf638302025d33eca942f7558d"
integrity sha512-A54kamjY1zn4CRTxxVxhfnn/rjO7VNZS13XuzyXgw7defV8sgclofex+hzMjSb2nhssraSAXGA0KEzEo3+WyWw==
dependencies:
"@types/uuid" "^10.0.0"
commander "^10.0.1"
p-queue "^6.6.2"
p-retry "4"
semver "^7.6.3"
uuid "^9.0.0"
uuid "^10.0.0"
leven@^3.1.0:
version "3.1.0"
@@ -2010,7 +2140,7 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.0.0:
ms@^2.0.0, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -2086,6 +2216,11 @@ openai@^4.55.0:
formdata-node "^4.3.2"
node-fetch "^2.6.7"
openapi-types@^12.1.3:
version "12.1.3"
resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3"
integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
@@ -2260,6 +2395,11 @@ retry@^0.13.1:
resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==
secure-json-parse@^2.4.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862"
integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==
semver@^6.3.0, semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
@@ -2452,6 +2592,11 @@ ts-node@^10.9.2:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
tslib@^2.4.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
type-detect@4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
@@ -2477,6 +2622,11 @@ undici-types@~6.19.2:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
undici@^6.12.0:
version "6.19.8"
resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.8.tgz#002d7c8a28f8cc3a44ff33c3d4be4d85e15d40e1"
integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==
update-browserslist-db@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e"
@@ -2490,11 +2640,6 @@ uuid@^10.0.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
uuid@^9.0.0:
version "9.0.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
@@ -2573,6 +2718,11 @@ yallist@^3.0.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yaml@^2.2.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d"
integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==
yargs-parser@^21.0.1, yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
@@ -2601,12 +2751,12 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zod-to-json-schema@^3.22.3:
zod-to-json-schema@^3.22.3, zod-to-json-schema@^3.22.5:
version "3.23.2"
resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.23.2.tgz#bc7e379c8050462538383e382964c03d8fe008f9"
integrity sha512-uSt90Gzc/tUfyNqxnjlfBs8W6WSGpNBv0rVsNxP/BVSMHMKGdthPYff4xtCHYloJGM0CFxFsb3NbC0eqPhfImw==
zod@^3.22.4, zod@^3.23.8:
zod@^3.22.3, zod@^3.22.4, zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==