Merge branch 'main' into vwp/eval_chains

This commit is contained in:
vowelparrot
2023-06-13 11:21:47 -07:00
68 changed files with 1668 additions and 342 deletions
@@ -0,0 +1,14 @@
# Weaviate Self Query Retriever
This example shows how to use a self query retriever with a [Weaviate](https://weaviate.io/) vector store.
If you haven't already set up Weaviate, please [follow the instructions here](/docs/modules/indexes/vector_stores/integrations/weaviate.mdx).
## Usage
This example shows how to intialize a `SelfQueryRetriever` with a vector store:
import CodeBlock from "@theme/CodeBlock";
import Example from "@examples/retrievers/weaviate_self_query.ts";
<CodeBlock language="typescript">{Example}</CodeBlock>
@@ -6,7 +6,7 @@ hide_table_of_contents: true
LangChain supports a variety of different markup and programming language-specific text splitters to split your text based on language-specific syntax.
This results in more semantically self-contained chunks that are more useful to a vector store or other retriever.
Popular languages like JavaScript, Python, and Rust are supported as well as Latex, HTML, and Markdown.
Popular languages like JavaScript, Python, Solidity, and Rust are supported as well as Latex, HTML, and Markdown.
## Usage
@@ -159,6 +159,14 @@ import AI21Example from "@examples/models/llm/ai21.ts";
<CodeBlock language="typescript">{AI21Example}</CodeBlock>
## `AlephAlpha`
You can get started with AlephAlpha' Luminous family of models by signing up for an API key [on their website](https://www.aleph-alpha.com/).
import AlephAlphaExample from "@examples/models/llm/aleph_alpha.ts";
<CodeBlock language="typescript">{AlephAlphaExample}</CodeBlock>
## Additional LLM Implementations
### `PromptLayerOpenAI`
+3 -2
View File
@@ -4,8 +4,8 @@
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "rm -rf ./docs/api && docusaurus start",
"build": "rm -rf ./build && docusaurus build",
"start": "rimraf ./docs/api && docusaurus start",
"build": "rimraf ./build && NODE_OPTIONS=--max-old-space-size=6144 DOCUSAURUS_SSR_CONCURRENCY=4 docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
@@ -44,6 +44,7 @@
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^2.7.1",
"rimraf": "^5.0.1",
"swc-loader": "^0.2.3",
"typedoc": "^0.24.4",
"typedoc-plugin-markdown": "next"
-1
View File
@@ -40,7 +40,6 @@
"graphql": "^16.6.0",
"js-yaml": "^4.1.0",
"langchain": "workspace:*",
"langchainplus-sdk": ">=0.0.11",
"ml-distance": "^4.0.0",
"mongodb": "^5.2.0",
"mysql2": "^3.3.3",
+68 -69
View File
@@ -1,4 +1,5 @@
/* eslint-disable no-process-env */
// eslint-disable-next-line import/no-extraneous-dependencies
import { LangChainPlusClient, Dataset } from "langchainplus-sdk";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { runOnDataset } from "langchain/client";
@@ -19,48 +20,47 @@ import { initializeAgentExecutorWithOptions } from "langchain/agents";
// Please note that this example assumes you have LangChain+ tracing running in the background.
// It is configured to work only with the V2 endpoints.
export const run = async () => {
// Capture traces by setting the LANGCHAIN_TRACING_V2 environment variable
process.env.LANGCHAIN_TRACING_V2 = "true";
const model = new ChatOpenAI({ temperature: 0 });
const tools = [
new SerpAPI(process.env.SERPAPI_API_KEY, {
location: "Austin,Texas,United States",
hl: "en",
gl: "us",
}),
new Calculator(),
];
// Capture traces by setting the LANGCHAIN_TRACING_V2 environment variable
process.env.LANGCHAIN_TRACING_V2 = "true";
const model = new ChatOpenAI({ temperature: 0 });
const tools = [
new SerpAPI(process.env.SERPAPI_API_KEY, {
location: "Austin,Texas,United States",
hl: "en",
gl: "us",
}),
new Calculator(),
];
const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
verbose: true,
});
console.log("Loaded agent.");
const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
verbose: true,
});
console.log("Loaded agent.");
const inputs: string[] = [
"How many people live in canada as of 2023?",
"who is dua lipa's boyfriend? what is his age raised to the .43 power?",
"what is dua lipa's boyfriend age raised to the .43 power?",
"how far is it from paris to boston in miles",
"what was the total number of points scored in the 2023 super bowl? what is that number raised to the .23 power?",
];
for (const input of inputs) {
const result = await executor.call({ input });
console.log(`Got output ${result.output}`);
}
// Now you can navigate to the UI at http://localhost/sessions then:
// 1. Select the default session from the list.
// 2. Next to the fist example, click "+ to Dataset".
// 3. Click "Create Dataset" and select a title like "calculator-example-dataset".
// 4. Add the other examples to the dataset as well
const inputs: string[] = [
"How many people live in canada as of 2023?",
"who is dua lipa's boyfriend? what is his age raised to the .43 power?",
"what is dua lipa's boyfriend age raised to the .43 power?",
"how far is it from paris to boston in miles",
"what was the total number of points scored in the 2023 super bowl? what is that number raised to the .23 power?",
];
for (const input of inputs) {
const result = await executor.call({ input });
console.log(`Got output ${result.output}`);
}
// Now you can navigate to the UI at http://localhost/sessions then:
// 1. Select the default session from the list.
// 2. Next to the fist example, click "+ to Dataset".
// 3. Click "Create Dataset" and select a title like "calculator-example-dataset".
// 4. Add the other examples to the dataset as well
// So that you don't have to create the dataset manually, we will create it for you
const client: LangChainPlusClient = new LangChainPlusClient({
// apiUrl: "https://api.langchain.plus", // Default: LANGCHAIN_ENDPOINT environment variable of "http://localhost:1984"
// apiKey: "<Your API Key>", // Default: LANGCHAIN_API_KEY environment variable
});
const csvContent = `
// So that you don't have to create the dataset manually, we will create it for you
const client: LangChainPlusClient = new LangChainPlusClient({
// apiUrl: "https://api.langchain.plus", // Default: LANGCHAIN_ENDPOINT environment variable of "http://localhost:1984"
// apiKey: "<Your API Key>", // Default: LANGCHAIN_API_KEY environment variable
});
const csvContent = `
input,output
How many people live in canada as of 2023?,"approximately 38,625,801"
who is dua lipa's boyfriend? what is his age raised to the .43 power?,her boyfriend is Romain Gravas. his age raised to the .43 power is approximately 4.9373857399466665
@@ -73,36 +73,35 @@ what is 153 raised to .1312 power?,approximately 1.9347796717823205
who is kendall jenner's boyfriend? what is his height (in inches) raised to .13 power?,approximately 1.7589107138176394
what is 1213 divided by 4345?,approximately 0.2791714614499425
`;
const blobData = new Blob([Buffer.from(csvContent)]);
const blobData = new Blob([Buffer.from(csvContent)]);
const datasetName = "mathy.csv";
const description = "Silly Math Dataset";
const inputKeys = ["input"];
const outputKeys = ["output"];
// Check if dataset name exists in listDatasets
const datasets = await client.listDatasets();
if (!datasets.map((d: Dataset) => d.name).includes(datasetName)) {
await client.uploadCsv({
csvFile: blobData,
fileName: datasetName,
inputKeys,
outputKeys,
description,
});
}
const datasetName = "mathy.csv";
const description = "Silly Math Dataset";
const inputKeys = ["input"];
const outputKeys = ["output"];
// Check if dataset name exists in listDatasets
const datasets = await client.listDatasets();
if (!datasets.map((d: Dataset) => d.name).includes(datasetName)) {
await client.uploadCsv({
csvFile: blobData,
fileName: datasetName,
inputKeys,
outputKeys,
description,
});
}
// Many chains incorporate memory. For independent trials over the dataset, we
// pass in a factory function that creates a new executor for each trial.
// If you know that your chain does not use memory, you can return the same
// executor for each trial.
const executorFactory = async () =>
initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
verbose: true,
});
// Many chains incorporate memory. For independent trials over the dataset, we
// pass in a factory function that creates a new executor for each trial.
// If you know that your chain does not use memory, you can return the same
// executor for each trial.
const executorFactory = async () =>
initializeAgentExecutorWithOptions(tools, model, {
agentType: "chat-conversational-react-description",
verbose: true,
});
// If using the traced dataset, you can update the datasetName to be
// "calculator-example-dataset" or the custom name you chose.
const results = await runOnDataset(datasetName, executorFactory, { client });
console.log(results);
};
// If using the traced dataset, you can update the datasetName to be
// "calculator-example-dataset" or the custom name you chose.
const results = await runOnDataset(datasetName, executorFactory, { client });
console.log(results);
+15
View File
@@ -0,0 +1,15 @@
import { AlephAlpha } from "langchain/llms/aleph_alpha";
const model = new AlephAlpha({
aleph_alpha_api_key: "YOUR_ALEPH_ALPHA_API_KEY", // Or set as process.env.ALEPH_ALPHA_API_KEY
});
const res = await model.call(`Is cereal soup?`);
console.log({ res });
/*
{
res: "\nIs soup a cereal? I dont think so, but it is delicious."
}
*/
@@ -1,4 +1,5 @@
import { createClient } from "@supabase/supabase-js";
import { AttributeInfo } from "langchain/schema/query_constructor";
import { Document } from "langchain/document";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
@@ -83,9 +84,6 @@ const attributeInfo: AttributeInfo[] = [
/**
* Next, we instantiate a vector store. This is where we store the embeddings of the documents.
* We use the Pinecone vector store here, but you can use any vector store you want.
* At this point we only support Chroma and Pinecone, but we will add more in the future.
* We also need to provide an embeddings object. This is used to embed the documents.
*/
if (!process.env.SUPABASE_URL || !process.env.SUPABASE_PRIVATE_KEY) {
throw new Error(
@@ -0,0 +1,135 @@
import weaviate from "weaviate-ts-client";
import { AttributeInfo } from "langchain/schema/query_constructor";
import { Document } from "langchain/document";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { SelfQueryRetriever } from "langchain/retrievers/self_query";
import { OpenAI } from "langchain/llms/openai";
import { WeaviateStore } from "langchain/vectorstores/weaviate";
import { WeaviateTranslator } from "langchain/retrievers/self_query/weaviate";
/**
* First, we create a bunch of documents. You can load your own documents here instead.
* Each document has a pageContent and a metadata field. Make sure your metadata matches the AttributeInfo below.
*/
const docs = [
new Document({
pageContent:
"A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata: { year: 1993, rating: 7.7, genre: "science fiction" },
}),
new Document({
pageContent:
"Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata: { year: 2010, director: "Christopher Nolan", rating: 8.2 },
}),
new Document({
pageContent:
"A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",
metadata: { year: 2006, director: "Satoshi Kon", rating: 8.6 },
}),
new Document({
pageContent:
"A bunch of normal-sized women are supremely wholesome and some men pine after them",
metadata: { year: 2019, director: "Greta Gerwig", rating: 8.3 },
}),
new Document({
pageContent: "Toys come alive and have a blast doing so",
metadata: { year: 1995, genre: "animated" },
}),
new Document({
pageContent: "Three men walk into the Zone, three men walk out of the Zone",
metadata: {
year: 1979,
director: "Andrei Tarkovsky",
genre: "science fiction",
rating: 9.9,
},
}),
];
/**
* Next, we define the attributes we want to be able to query on.
* in this case, we want to be able to query on the genre, year, director, rating, and length of the movie.
* We also provide a description of each attribute and the type of the attribute.
* This is used to generate the query prompts.
*/
const attributeInfo: AttributeInfo[] = [
{
name: "genre",
description: "The genre of the movie",
type: "string or array of strings",
},
{
name: "year",
description: "The year the movie was released",
type: "number",
},
{
name: "director",
description: "The director of the movie",
type: "string",
},
{
name: "rating",
description: "The rating of the movie (1-10)",
type: "number",
},
{
name: "length",
description: "The length of the movie in minutes",
type: "number",
},
];
/**
* Next, we instantiate a vector store. This is where we store the embeddings of the documents.
*/
const embeddings = new OpenAIEmbeddings();
const llm = new OpenAI();
const documentContents = "Brief summary of a movie";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const client = (weaviate as any).client({
scheme: process.env.WEAVIATE_SCHEME || "https",
host: process.env.WEAVIATE_HOST || "localhost",
apiKey: process.env.WEAVIATE_API_KEY
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
new (weaviate as any).ApiKey(process.env.WEAVIATE_API_KEY)
: undefined,
});
const vectorStore = await WeaviateStore.fromDocuments(docs, embeddings, {
client,
indexName: "Test",
textKey: "text",
metadataKeys: ["year", "director", "rating", "genre"],
});
const selfQueryRetriever = await SelfQueryRetriever.fromLLM({
llm,
vectorStore,
documentContents,
attributeInfo,
/**
* We need to use a translator that translates the queries into a
* filter format that the vector store can understand. LangChain provides one here.
*/
structuredQueryTranslator: new WeaviateTranslator(),
});
/**
* Now we can query the vector store.
* We can ask questions like "Which movies are less than 90 minutes?" or "Which movies are rated higher than 8.5?".
* We can also ask questions like "Which movies are either comedy or drama and are less than 90 minutes?".
* The retriever will automatically convert these questions into queries that can be used to retrieve documents.
*
* Note that unlike other vector stores, you have to make sure each metadata keys are actually presnt in the database,
* meaning that Weaviate will throw an error if the self query chain generate a query with a metadata key that does
* not exist in your Weaviate database.
*/
const query1 = await selfQueryRetriever.getRelevantDocuments(
"Which movies are rated higher than 8.5?"
);
const query2 = await selfQueryRetriever.getRelevantDocuments(
"Which movies are directed by Greta Gerwig?"
);
console.log(query1, query2);
+6
View File
@@ -76,6 +76,9 @@ llms/openai.d.ts
llms/ai21.cjs
llms/ai21.js
llms/ai21.d.ts
llms/aleph_alpha.cjs
llms/aleph_alpha.js
llms/aleph_alpha.d.ts
llms/cohere.cjs
llms/cohere.js
llms/cohere.d.ts
@@ -331,6 +334,9 @@ retrievers/self_query/pinecone.d.ts
retrievers/self_query/supabase.cjs
retrievers/self_query/supabase.js
retrievers/self_query/supabase.d.ts
retrievers/self_query/weaviate.cjs
retrievers/self_query/weaviate.js
retrievers/self_query/weaviate.d.ts
retrievers/vespa.cjs
retrievers/vespa.js
retrievers/vespa.d.ts
+24 -6
View File
@@ -1,6 +1,6 @@
{
"name": "langchain",
"version": "0.0.92",
"version": "0.0.93",
"description": "Typescript bindings for langchain",
"type": "module",
"engines": {
@@ -88,6 +88,9 @@
"llms/ai21.cjs",
"llms/ai21.js",
"llms/ai21.d.ts",
"llms/aleph_alpha.cjs",
"llms/aleph_alpha.js",
"llms/aleph_alpha.d.ts",
"llms/cohere.cjs",
"llms/cohere.js",
"llms/cohere.d.ts",
@@ -343,6 +346,9 @@
"retrievers/self_query/supabase.cjs",
"retrievers/self_query/supabase.js",
"retrievers/self_query/supabase.d.ts",
"retrievers/self_query/weaviate.cjs",
"retrievers/self_query/weaviate.js",
"retrievers/self_query/weaviate.d.ts",
"retrievers/vespa.cjs",
"retrievers/vespa.js",
"retrievers/vespa.d.ts",
@@ -407,13 +413,13 @@
},
"scripts": {
"build": "yarn clean && yarn build:esm && yarn build:cjs && node scripts/create-entrypoints.js && node scripts/check-tree-shaking.js",
"build:esm": "tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
"build:cjs": "tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rm -r dist-cjs",
"build:esm": "tsc --outDir dist/ && rimraf dist/tests dist/**/tests",
"build:cjs": "tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rimraf dist-cjs",
"build:watch": "node scripts/create-entrypoints.js && tsc --outDir dist/ --watch",
"lint": "eslint src && dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
"lint:fix": "yarn lint --fix",
"precommit": "tsc --noEmit && lint-staged",
"clean": "rm -rf dist/ && node scripts/create-entrypoints.js pre",
"clean": "rimraf dist/ && node scripts/create-entrypoints.js pre",
"prepack": "yarn build",
"release": "release-it --only-version --config .release-it.json",
"test": "NODE_OPTIONS=--experimental-vm-modules jest --testPathIgnorePatterns=\\.int\\.test.ts --testTimeout 30000",
@@ -495,6 +501,7 @@
"redis": "^4.6.6",
"release-it": "^15.10.1",
"replicate": "^0.9.0",
"rimraf": "^5.0.1",
"rollup": "^3.19.1",
"sqlite3": "^5.1.4",
"srt-parser-2": "^1.2.2",
@@ -699,12 +706,13 @@
"@anthropic-ai/sdk": "^0.4.3",
"ansi-styles": "^5.0.0",
"binary-extensions": "^2.2.0",
"case-anything": "^2.1.13",
"camelcase": "6",
"decamelize": "5",
"expr-eval": "^2.0.2",
"flat": "^5.0.2",
"js-tiktoken": "^1.0.6",
"jsonpointer": "^5.0.1",
"langchainplus-sdk": ">=0.0.11",
"langchainplus-sdk": "^0.0.11",
"ml-distance": "^4.0.0",
"object-hash": "^3.0.0",
"openai": "^3.2.0",
@@ -872,6 +880,11 @@
"import": "./llms/ai21.js",
"require": "./llms/ai21.cjs"
},
"./llms/aleph_alpha": {
"types": "./llms/aleph_alpha.d.ts",
"import": "./llms/aleph_alpha.js",
"require": "./llms/aleph_alpha.cjs"
},
"./llms/cohere": {
"types": "./llms/cohere.d.ts",
"import": "./llms/cohere.js",
@@ -1305,6 +1318,11 @@
"import": "./retrievers/self_query/supabase.js",
"require": "./retrievers/self_query/supabase.cjs"
},
"./retrievers/self_query/weaviate": {
"types": "./retrievers/self_query/weaviate.d.ts",
"import": "./retrievers/self_query/weaviate.js",
"require": "./retrievers/self_query/weaviate.cjs"
},
"./retrievers/vespa": {
"types": "./retrievers/vespa.d.ts",
"import": "./retrievers/vespa.js",
+3
View File
@@ -40,6 +40,7 @@ const entrypoints = {
"llms/base": "llms/base",
"llms/openai": "llms/openai",
"llms/ai21": "llms/ai21",
"llms/aleph_alpha": "llms/aleph_alpha",
"llms/cohere": "llms/cohere",
"llms/hf": "llms/hf",
"llms/replicate": "llms/replicate",
@@ -139,6 +140,7 @@ const entrypoints = {
"retrievers/self_query/functional": "retrievers/self_query/functional",
"retrievers/self_query/pinecone": "retrievers/self_query/pinecone",
"retrievers/self_query/supabase": "retrievers/self_query/supabase",
"retrievers/self_query/weaviate": "retrievers/self_query/weaviate",
"retrievers/vespa": "retrievers/vespa",
// cache
cache: "cache/index",
@@ -244,6 +246,7 @@ const requiresOptionalDependency = [
"retrievers/self_query/functional",
"retrievers/self_query/pinecone",
"retrievers/self_query/supabase",
"retrievers/self_query/weaviate",
"output_parsers/expression",
"chains/query_constructor",
"chains/query_constructor/ir",
+9
View File
@@ -21,6 +21,7 @@ export type SerializedLLM = {
export interface BaseLangChainParams {
verbose?: boolean;
callbacks?: Callbacks;
tags?: string[];
}
/**
@@ -37,6 +38,8 @@ export abstract class BaseLangChain
callbacks?: Callbacks;
tags?: string[];
get lc_attributes(): { [key: string]: undefined } | undefined {
return {
callbacks: undefined,
@@ -48,6 +51,7 @@ export abstract class BaseLangChain
super(params);
this.verbose = params.verbose ?? getVerbosity();
this.callbacks = params.callbacks;
this.tags = params.tags ?? [];
}
}
@@ -82,6 +86,11 @@ export interface BaseLanguageModelCallOptions {
* If provided, the call will be aborted when the signal is aborted.
*/
signal?: AbortSignal;
/**
* Tags to attach to this call.
*/
tags?: string[];
}
/**
+8 -4
View File
@@ -32,7 +32,8 @@ abstract class BaseCallbackHandlerMethodsClass {
prompts: string[],
runId: string,
parentRunId?: string,
extraParams?: Record<string, unknown>
extraParams?: Record<string, unknown>,
tags?: string[]
): Promise<void> | void;
/**
@@ -71,7 +72,8 @@ abstract class BaseCallbackHandlerMethodsClass {
messages: BaseChatMessage[][],
runId: string,
parentRunId?: string,
extraParams?: Record<string, unknown>
extraParams?: Record<string, unknown>,
tags?: string[]
): Promise<void> | void;
/**
@@ -82,7 +84,8 @@ abstract class BaseCallbackHandlerMethodsClass {
chain: Serialized,
inputs: ChainValues,
runId: string,
parentRunId?: string
parentRunId?: string,
tags?: string[]
): Promise<void> | void;
/**
@@ -111,7 +114,8 @@ abstract class BaseCallbackHandlerMethodsClass {
tool: Serialized,
input: string,
runId: string,
parentRunId?: string
parentRunId?: string,
tags?: string[]
): Promise<void> | void;
/**
+103 -31
View File
@@ -1,37 +1,29 @@
import { KVMap, BaseRun } from "langchainplus-sdk/schemas";
import {
AgentAction,
BaseChatMessage,
ChainValues,
LLMResult,
RunInputs,
RunOutputs,
} from "../../schema/index.js";
import { Serialized } from "../../load/serializable.js";
import { BaseCallbackHandler, BaseCallbackHandlerInput } from "../base.js";
export type RunType = "llm" | "chain" | "tool";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Extra = Record<string, any>;
export interface BaseRun {
id: string;
name: string;
start_time: number;
end_time?: number;
extra?: Extra;
error?: string;
execution_order: number;
serialized: object;
inputs: RunInputs;
outputs?: RunOutputs;
reference_example_id?: string; // uuid
run_type: RunType;
}
export interface Run extends BaseRun {
// some optional fields are always present here
id: string;
start_time: number;
execution_order: number;
// some additional fields that don't exist in sdk runs
child_runs: this[];
child_execution_order: number;
parent_run_id?: string; // uuid
events: Array<{
name: string;
time: number;
kwargs?: Record<string, unknown>;
}>;
}
export interface AgentRun extends Run {
@@ -94,21 +86,30 @@ export abstract class BaseTracer extends BaseCallbackHandler {
prompts: string[],
runId: string,
parentRunId?: string,
extraParams?: Record<string, unknown>
extraParams?: KVMap,
tags?: string[]
): Promise<void> {
const execution_order = this._getExecutionOrder(parentRunId);
const start_time = Date.now();
const run: Run = {
id: runId,
name: llm.id[llm.id.length - 1],
parent_run_id: parentRunId,
start_time: Date.now(),
start_time,
serialized: llm,
events: [
{
name: "start",
time: start_time,
},
],
inputs: { prompts },
execution_order,
child_runs: [],
child_execution_order: execution_order,
run_type: "llm",
extra: extraParams,
extra: extraParams ?? {},
tags: tags || [],
};
this._startTrace(run);
@@ -120,21 +121,30 @@ export abstract class BaseTracer extends BaseCallbackHandler {
messages: BaseChatMessage[][],
runId: string,
parentRunId?: string,
extraParams?: Record<string, unknown>
extraParams?: KVMap,
tags?: string[]
): Promise<void> {
const execution_order = this._getExecutionOrder(parentRunId);
const start_time = Date.now();
const run: Run = {
id: runId,
name: llm.id[llm.id.length - 1],
parent_run_id: parentRunId,
start_time: Date.now(),
start_time,
serialized: llm,
events: [
{
name: "start",
time: start_time,
},
],
inputs: { messages },
execution_order,
child_runs: [],
child_execution_order: execution_order,
run_type: "llm",
extra: extraParams,
extra: extraParams ?? {},
tags: tags || [],
};
this._startTrace(run);
@@ -148,6 +158,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.outputs = output;
run.events.push({
name: "end",
time: run.end_time,
});
await this.onLLMEnd?.(run);
await this._endTrace(run);
}
@@ -159,6 +173,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.error = error.message;
run.events.push({
name: "error",
time: run.end_time,
});
await this.onLLMError?.(run);
await this._endTrace(run);
}
@@ -167,20 +185,30 @@ export abstract class BaseTracer extends BaseCallbackHandler {
chain: Serialized,
inputs: ChainValues,
runId: string,
parentRunId?: string
parentRunId?: string,
tags?: string[]
): Promise<void> {
const execution_order = this._getExecutionOrder(parentRunId);
const start_time = Date.now();
const run: Run = {
id: runId,
name: chain.id[chain.id.length - 1],
parent_run_id: parentRunId,
start_time: Date.now(),
start_time,
serialized: chain,
events: [
{
name: "start",
time: start_time,
},
],
inputs,
execution_order,
child_execution_order: execution_order,
run_type: "chain",
child_runs: [],
extra: {},
tags: tags || [],
};
this._startTrace(run);
@@ -194,6 +222,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.outputs = outputs;
run.events.push({
name: "end",
time: run.end_time,
});
await this.onChainEnd?.(run);
await this._endTrace(run);
}
@@ -205,6 +237,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.error = error.message;
run.events.push({
name: "error",
time: run.end_time,
});
await this.onChainError?.(run);
await this._endTrace(run);
}
@@ -213,20 +249,30 @@ export abstract class BaseTracer extends BaseCallbackHandler {
tool: Serialized,
input: string,
runId: string,
parentRunId?: string
parentRunId?: string,
tags?: string[]
): Promise<void> {
const execution_order = this._getExecutionOrder(parentRunId);
const start_time = Date.now();
const run: Run = {
id: runId,
name: tool.id[tool.id.length - 1],
parent_run_id: parentRunId,
start_time: Date.now(),
start_time,
serialized: tool,
events: [
{
name: "start",
time: start_time,
},
],
inputs: { input },
execution_order,
child_execution_order: execution_order,
run_type: "tool",
child_runs: [],
extra: {},
tags: tags || [],
};
this._startTrace(run);
@@ -240,6 +286,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.outputs = { output };
run.events.push({
name: "end",
time: run.end_time,
});
await this.onToolEnd?.(run);
await this._endTrace(run);
}
@@ -251,6 +301,10 @@ export abstract class BaseTracer extends BaseCallbackHandler {
}
run.end_time = Date.now();
run.error = error.message;
run.events.push({
name: "error",
time: run.end_time,
});
await this.onToolError?.(run);
await this._endTrace(run);
}
@@ -263,9 +317,27 @@ export abstract class BaseTracer extends BaseCallbackHandler {
const agentRun = run as AgentRun;
agentRun.actions = agentRun.actions || [];
agentRun.actions.push(action);
agentRun.events.push({
name: "agent_action",
time: Date.now(),
kwargs: { action },
});
await this.onAgentAction?.(run as AgentRun);
}
async handleText(text: string, runId: string): Promise<void> {
const run = this.runMap.get(runId);
if (!run || run?.run_type !== "chain") {
return;
}
run.events.push({
name: "text",
time: Date.now(),
kwargs: { text },
});
await this.onText?.(run);
}
// custom event handlers
onLLMStart?(run: Run): void | Promise<void>;
@@ -292,5 +364,5 @@ export abstract class BaseTracer extends BaseCallbackHandler {
// onAgentEnd?(run: ChainRun): void | Promise<void>;
// onText?(run: Run): void | Promise<void>;
onText?(run: Run): void | Promise<void>;
}
@@ -1,5 +1,9 @@
import { LangChainPlusClient } from "langchainplus-sdk";
import { BaseRun, RunCreate, RunUpdate } from "langchainplus-sdk/schemas";
import {
BaseRun,
RunCreate,
RunUpdate as BaseRunUpdate,
} from "langchainplus-sdk/schemas";
import {
getEnvironmentVariable,
getRuntimeEnvironment,
@@ -13,6 +17,10 @@ export interface Run extends BaseRun {
child_execution_order: number;
}
export interface RunUpdate extends BaseRunUpdate {
events: BaseRun["events"];
}
export interface LangChainTracerFields extends BaseCallbackHandlerInput {
exampleId?: string;
sessionName?: string;
@@ -45,15 +53,16 @@ export class LangChainTracer
run: Run,
example_id: string | undefined = undefined
): Promise<RunCreate> {
const runExtra = run.extra ?? {};
runExtra.runtime = await getRuntimeEnvironment();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { child_runs: _, ...restOfRun } = run;
restOfRun.extra = runExtra;
restOfRun.reference_example_id = restOfRun.parent_run_id
? undefined
: example_id;
return { child_runs: [], session_name: this.sessionName, ...restOfRun };
return {
...run,
extra: {
...run.extra,
runtime: await getRuntimeEnvironment(),
},
child_runs: undefined,
session_name: this.sessionName,
reference_example_id: run.parent_run_id ? undefined : example_id,
};
}
protected async persistRun(_run: Run): Promise<void> {}
@@ -71,8 +80,7 @@ export class LangChainTracer
end_time: run.end_time,
error: run.error,
outputs: run.outputs,
parent_run_id: run.parent_run_id,
reference_example_id: run.reference_example_id,
events: run.events,
};
await this.client.updateRun(run.id, runUpdate);
}
+1 -1
View File
@@ -4,7 +4,7 @@ export {
BaseCallbackHandlerInput,
} from "./base.js";
export { Run, RunType, BaseRun, BaseTracer } from "./handlers/tracer.js";
export { Run, RunType, BaseTracer } from "./handlers/tracer.js";
export { ConsoleCallbackHandler } from "./handlers/console.js";
+62 -7
View File
@@ -53,6 +53,8 @@ class BaseRunManager {
public readonly runId: string,
protected readonly handlers: BaseCallbackHandler[],
protected readonly inheritableHandlers: BaseCallbackHandler[],
protected readonly tags: string[],
protected readonly inheritableTags: string[],
protected readonly _parentRunId?: string
) {}
@@ -148,10 +150,14 @@ export class CallbackManagerForChainRun
extends BaseRunManager
implements BaseCallbackManagerMethods
{
getChild(): CallbackManager {
getChild(tag?: string): CallbackManager {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const manager = new CallbackManager(this.runId);
manager.setHandlers(this.inheritableHandlers);
manager.addTags(this.inheritableTags);
if (tag) {
manager.addTags([tag], false);
}
return manager;
}
@@ -248,10 +254,14 @@ export class CallbackManagerForToolRun
extends BaseRunManager
implements BaseCallbackManagerMethods
{
getChild(): CallbackManager {
getChild(tag?: string): CallbackManager {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const manager = new CallbackManager(this.runId);
manager.setHandlers(this.inheritableHandlers);
manager.addTags(this.inheritableTags);
if (tag) {
manager.addTags([tag], false);
}
return manager;
}
@@ -308,6 +318,10 @@ export class CallbackManager
inheritableHandlers: BaseCallbackHandler[];
tags: string[] = [];
inheritableTags: string[] = [];
name = "callback_manager";
private readonly _parentRunId?: string;
@@ -336,7 +350,8 @@ export class CallbackManager
prompts,
runId,
this._parentRunId,
extraParams
extraParams,
this.tags
);
} catch (err) {
console.error(
@@ -351,6 +366,8 @@ export class CallbackManager
runId,
this.handlers,
this.inheritableHandlers,
this.tags,
this.inheritableTags,
this._parentRunId
);
}
@@ -374,7 +391,8 @@ export class CallbackManager
messages,
runId,
this._parentRunId,
extraParams
extraParams,
this.tags
);
else if (handler.handleLLMStart) {
messageStrings = messages.map((x) => getBufferString(x));
@@ -383,7 +401,8 @@ export class CallbackManager
messageStrings,
runId,
this._parentRunId,
extraParams
extraParams,
this.tags
);
}
} catch (err) {
@@ -399,6 +418,8 @@ export class CallbackManager
runId,
this.handlers,
this.inheritableHandlers,
this.tags,
this.inheritableTags,
this._parentRunId
);
}
@@ -417,7 +438,8 @@ export class CallbackManager
chain,
inputs,
runId,
this._parentRunId
this._parentRunId,
this.tags
);
} catch (err) {
console.error(
@@ -432,6 +454,8 @@ export class CallbackManager
runId,
this.handlers,
this.inheritableHandlers,
this.tags,
this.inheritableTags,
this._parentRunId
);
}
@@ -450,7 +474,8 @@ export class CallbackManager
tool,
input,
runId,
this._parentRunId
this._parentRunId,
this.tags
);
} catch (err) {
console.error(
@@ -465,6 +490,8 @@ export class CallbackManager
runId,
this.handlers,
this.inheritableHandlers,
this.tags,
this.inheritableTags,
this._parentRunId
);
}
@@ -491,6 +518,21 @@ export class CallbackManager
}
}
addTags(tags: string[], inherit = true): void {
this.removeTags(tags); // Remove duplicates
this.tags.push(...tags);
if (inherit) {
this.inheritableTags.push(...tags);
}
}
removeTags(tags: string[]): void {
this.tags = this.tags.filter((tag) => !tags.includes(tag));
this.inheritableTags = this.inheritableTags.filter(
(tag) => !tags.includes(tag)
);
}
copy(
additionalHandlers: BaseCallbackHandler[] = [],
inherit = true
@@ -500,6 +542,10 @@ export class CallbackManager
const inheritable = this.inheritableHandlers.includes(handler);
manager.addHandler(handler, inheritable);
}
for (const tag of this.tags) {
const inheritable = this.inheritableTags.includes(tag);
manager.addTags([tag], inheritable);
}
for (const handler of additionalHandlers) {
if (
// Prevent multiple copies of console_callback_handler
@@ -532,6 +578,8 @@ export class CallbackManager
static async configure(
inheritableHandlers?: Callbacks,
localHandlers?: Callbacks,
inheritableTags?: string[],
localTags?: string[],
options?: CallbackManagerOptions
): Promise<CallbackManager | undefined> {
let callbackManager: CallbackManager | undefined;
@@ -552,6 +600,7 @@ export class CallbackManager
false
);
}
const verboseEnabled =
getEnvironmentVariable("LANGCHAIN_VERBOSE") || options?.verbose;
const tracingV2Enabled =
@@ -589,6 +638,12 @@ export class CallbackManager
}
}
}
if (inheritableTags || localTags) {
if (callbackManager) {
callbackManager.addTags(inheritableTags ?? []);
callbackManager.addTags(localTags ?? [], false);
}
}
return callbackManager;
}
}
@@ -378,8 +378,12 @@ test("CallbackManager.copy()", () => {
callbackManager1.addHandler(handler1, true);
callbackManager1.addHandler(handler2, false);
callbackManager1.addTags(["a"], true);
callbackManager1.addTags(["b"], false);
expect(callbackManager1.handlers).toEqual([handler1, handler2]);
expect(callbackManager1.inheritableHandlers).toEqual([handler1]);
expect(callbackManager1.tags).toEqual(["a", "b"]);
expect(callbackManager1.inheritableTags).toEqual(["a"]);
const callbackManager2 = callbackManager1.copy([handler3]);
expect(callbackManager2.handlers.map((h) => h.name)).toEqual([
@@ -391,6 +395,8 @@ test("CallbackManager.copy()", () => {
handler1.name,
handler3.name,
]);
expect(callbackManager2.tags).toEqual(["a", "b"]);
expect(callbackManager2.inheritableTags).toEqual(["a"]);
const callbackManager3 = callbackManager2.copy([handler4], false);
expect(callbackManager3.handlers.map((h) => h.name)).toEqual([
@@ -10,6 +10,12 @@ import { initializeAgentExecutorWithOptions } from "../../agents/initialize.js";
import { HumanChatMessage } from "../../schema/index.js";
import { ChatOpenAI } from "../../chat_models/openai.js";
import { Serialized } from "../../load/serializable.js";
import {
ConstitutionalChain,
ConstitutionalPrinciple,
LLMChain,
} from "../../chains/index.js";
import { PromptTemplate } from "../../prompts/prompt.js";
const serialized: Serialized = {
lc: 1,
@@ -47,6 +53,38 @@ test("Test LangChain V2 tracer", async () => {
await tracer.handleLLMEnd({ generations: [[]] }, llmRunId3);
});
test("Test traced chain with tags", async () => {
const llm = new OpenAI();
const qaPrompt = new PromptTemplate({
template: "Q: {question} A:",
inputVariables: ["question"],
});
const qaChain = new LLMChain({
llm,
prompt: qaPrompt,
});
const constitutionalChain = ConstitutionalChain.fromLLM(llm, {
tags: ["only-in-root-chain"],
chain: qaChain,
constitutionalPrinciples: [
new ConstitutionalPrinciple({
critiqueRequest: "Tell me if this answer is good.",
revisionRequest: "Give a better answer.",
}),
],
});
await constitutionalChain.call(
{
question: "What is the meaning of life?",
},
[new LangChainTracer()],
["test-for-tags"]
);
});
test("Test Traced Agent with concurrency", async () => {
process.env.LANGCHAIN_TRACING_V2 = "true";
const model = new OpenAI({ temperature: 0 });
+98 -3
View File
@@ -45,15 +45,27 @@ test("Test LLMRun", async () => {
execution_order: 1,
child_execution_order: 1,
serialized,
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
inputs: { prompts: ["test"] },
run_type: "llm",
outputs: { generations: [] },
child_runs: [],
extra: {},
tags: [],
};
expect(run).toEqual(compareRun);
});
test("Test Chat Message Run", async () => {
test("Test Chat Model Run", async () => {
const tracer = new FakeTracer();
const runId = uuid.v4();
const messages = [[new HumanChatMessage("Avast")]];
@@ -70,8 +82,18 @@ test("Test Chat Message Run", async () => {
"child_execution_order": 1,
"child_runs": [],
"end_time": 1620000000000,
"events": [
{
"name": "start",
"time": 1620000000000,
},
{
"name": "end",
"time": 1620000000000,
},
],
"execution_order": 1,
"extra": undefined,
"extra": {},
"id": Any<String>,
"inputs": {
"messages": [
@@ -101,6 +123,7 @@ test("Test Chat Message Run", async () => {
"type": "constructor",
},
"start_time": 1620000000000,
"tags": [],
}
`
);
@@ -125,10 +148,22 @@ test("Test Chain Run", async () => {
execution_order: 1,
child_execution_order: 1,
serialized,
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
inputs: { foo: "bar" },
outputs: { foo: "bar" },
run_type: "chain",
child_runs: [],
extra: {},
tags: [],
};
await tracer.handleChainStart(serialized, { foo: "bar" }, runId);
await tracer.handleChainEnd({ foo: "bar" }, runId);
@@ -148,10 +183,22 @@ test("Test Tool Run", async () => {
execution_order: 1,
child_execution_order: 1,
serialized,
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
inputs: { input: "test" },
outputs: { output: "output" },
run_type: "tool",
child_runs: [],
extra: {},
tags: [],
};
await tracer.handleToolStart(serialized, "test", runId);
await tracer.handleToolEnd("output", runId);
@@ -208,9 +255,21 @@ test("Test nested runs", async () => {
generations: [[]],
},
serialized: { ...serialized, id: ["test_llm_child_run"] },
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
start_time: 1620000000000,
run_type: "llm",
child_runs: [],
extra: {},
tags: [],
},
],
end_time: 1620000000000,
@@ -218,9 +277,21 @@ test("Test nested runs", async () => {
child_execution_order: 3,
outputs: { output: "output" },
serialized: { ...serialized, id: ["test_tool"] },
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
start_time: 1620000000000,
inputs: { input: "test" },
run_type: "tool",
extra: {},
tags: [],
},
{
id: llmRunId2,
@@ -234,9 +305,21 @@ test("Test nested runs", async () => {
generations: [[]],
},
serialized: { ...serialized, id: ["test_llm2"] },
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
start_time: 1620000000000,
run_type: "llm",
child_runs: [],
extra: {},
tags: [],
},
],
id: chainRunId,
@@ -249,10 +332,22 @@ test("Test nested runs", async () => {
outputs: {
foo: "bar",
},
serialized: { ...serialized, id: ["test"] },
events: [
{
name: "start",
time: 1620000000000,
},
{
name: "end",
time: 1620000000000,
},
],
name: "test",
serialized,
start_time: 1620000000000,
run_type: "chain",
extra: {},
tags: [],
};
expect(tracer.runs.length).toBe(1);
expect(tracer.runs[0]).toEqual(compareRun);
@@ -63,7 +63,7 @@ export class AnalyzeDocumentChain
const newInputs = { input_documents: currentDocs, ...rest };
const result = await this.combineDocumentsChain.call(
newInputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
return result;
}
+2 -2
View File
@@ -66,7 +66,7 @@ export class APIChain extends BaseChain implements APIChainInput {
const api_url = await this.apiRequestChain.predict(
{ question, api_docs: this.apiDocs },
runManager?.getChild()
runManager?.getChild("request")
);
const res = await fetch(api_url, { headers: this.headers });
@@ -74,7 +74,7 @@ export class APIChain extends BaseChain implements APIChainInput {
const answer = await this.apiAnswerChain.predict(
{ question, api_docs: this.apiDocs, api_url, api_response },
runManager?.getChild()
runManager?.getChild("response")
);
return { [this.outputKey]: answer };
+7 -1
View File
@@ -105,7 +105,11 @@ export abstract class BaseChain extends BaseLangChain implements ChainInputs {
*
* Wraps _call and handles memory.
*/
async call(values: ChainValues, callbacks?: Callbacks): Promise<ChainValues> {
async call(
values: ChainValues,
callbacks?: Callbacks,
tags?: string[]
): Promise<ChainValues> {
const fullValues = { ...values } as typeof values;
if (!(this.memory == null)) {
const newValues = await this.memory.loadMemoryVariables(values);
@@ -116,6 +120,8 @@ export abstract class BaseChain extends BaseLangChain implements ChainInputs {
const callbackManager_ = await CallbackManager.configure(
callbacks,
this.callbacks,
tags,
this.tags,
{ verbose: this.verbose }
);
const runManager = await callbackManager_?.handleChainStart(
+2 -2
View File
@@ -96,7 +96,7 @@ export class ChatVectorDBQAChain
question,
chat_history: chatHistory,
},
runManager?.getChild()
runManager?.getChild("question_generator")
);
const keys = Object.keys(result);
console.log("_call", values, keys);
@@ -116,7 +116,7 @@ export class ChatVectorDBQAChain
};
const result = await this.combineDocumentsChain.call(
inputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
if (this.returnSourceDocuments) {
return {
+7 -5
View File
@@ -70,7 +70,7 @@ export class StuffDocumentsChain
...rest,
[this.documentVariableName]: text,
},
runManager?.getChild()
runManager?.getChild("combine_documents")
);
return result;
}
@@ -201,7 +201,9 @@ export class MapReduceDocumentsChain
// If we have a runManager, then we need to create a child for each input
// so that we can track the progress of each input.
runManager
? Array.from({ length: inputs.length }, () => runManager.getChild())
? Array.from({ length: inputs.length }, (_, i) =>
runManager.getChild(`map_${i + 1}`)
)
: undefined
);
const { outputKey } = this.llmChain;
@@ -224,7 +226,7 @@ export class MapReduceDocumentsChain
const newInputs = { input_documents: currentDocs, ...rest };
const result = await this.combineDocumentChain.call(
newInputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
// Return the intermediate steps results if the flag is set
@@ -389,7 +391,7 @@ export class RefineDocumentsChain
);
let res = await this.llmChain.predict(
{ ...initialInputs },
runManager?.getChild()
runManager?.getChild("answer")
);
const refineSteps = [res];
@@ -402,7 +404,7 @@ export class RefineDocumentsChain
const inputs = { ...refineInputs, ...rest };
res = await this.refineLLMChain.predict(
{ ...inputs },
runManager?.getChild()
runManager?.getChild("refine")
);
refineSteps.push(res);
}
@@ -38,7 +38,7 @@ export class ConstitutionalChain
}
constructor(fields: ConstitutionalChainInput) {
super(fields.memory, fields.verbose, fields.callbackManager);
super(fields);
this.chain = fields.chain;
this.constitutionalPrinciples = fields.constitutionalPrinciples;
this.critiqueChain = fields.critiqueChain;
@@ -51,7 +51,7 @@ export class ConstitutionalChain
): Promise<ChainValues> {
let { [this.chain.outputKey]: response } = await this.chain.call(
values,
runManager?.getChild()
runManager?.getChild("original")
);
const inputPrompt = await this.chain.prompt.format(values);
@@ -63,7 +63,7 @@ export class ConstitutionalChain
output_from_model: response,
critique_request: this.constitutionalPrinciples[i].critiqueRequest,
},
runManager?.getChild()
runManager?.getChild("critique")
);
const critique = ConstitutionalChain._parseCritique(rawCritique);
@@ -77,7 +77,7 @@ export class ConstitutionalChain
critique,
revision_request: this.constitutionalPrinciples[i].revisionRequest,
},
runManager?.getChild()
runManager?.getChild("revision")
);
response = revisionRaw;
}
@@ -105,7 +105,7 @@ export class ConversationalRetrievalQAChain
question,
chat_history: chatHistory,
},
runManager?.getChild()
runManager?.getChild("question_generator")
);
const keys = Object.keys(result);
if (keys.length === 1) {
@@ -124,7 +124,7 @@ export class ConversationalRetrievalQAChain
};
const result = await this.combineDocumentsChain.call(
inputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
if (this.returnSourceDocuments) {
return {
+1 -1
View File
@@ -62,7 +62,7 @@ export class RetrievalQAChain
const inputs = { question, input_documents: docs };
const result = await this.combineDocumentsChain.call(
inputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
if (this.returnSourceDocuments) {
return {
+10 -7
View File
@@ -131,8 +131,13 @@ export class SequentialChain extends BaseChain implements SequentialChainInput {
): Promise<ChainValues> {
let input: ChainValues = {};
const allChainValues: ChainValues = values;
let i = 0;
for (const chain of this.chains) {
input = await chain.call(allChainValues, runManager?.getChild());
i += 1;
input = await chain.call(
allChainValues,
runManager?.getChild(`step_${i}`)
);
for (const key of Object.keys(input)) {
allChainValues[key] = input[key];
}
@@ -239,11 +244,7 @@ export class SimpleSequentialChain
}
constructor(fields: SimpleSequentialChainInput) {
super(
fields.memory,
fields.verbose,
fields.callbacks ?? fields.callbackManager
);
super(fields);
this.chains = fields.chains;
this.trimOutputs = fields.trimOutputs ?? false;
this._validateChains();
@@ -275,8 +276,10 @@ export class SimpleSequentialChain
runManager?: CallbackManagerForChainRun
): Promise<ChainValues> {
let input: string = values[this.inputKey];
let i = 0;
for (const chain of this.chains) {
input = await chain.run(input, runManager?.getChild());
i += 1;
input = await chain.run(input, runManager?.getChild(`step_${i}`));
if (this.trimOutputs) {
input = input.trim();
}
+2 -2
View File
@@ -90,7 +90,7 @@ export class SqlDatabaseChain extends BaseChain {
const sqlCommand = await llmChain.predict(
llmInputs,
runManager?.getChild()
runManager?.getChild("sql_generation")
);
let queryResult = "";
try {
@@ -110,7 +110,7 @@ export class SqlDatabaseChain extends BaseChain {
finalResult = {
[this.outputKey]: await llmChain.predict(
llmInputs,
runManager?.getChild()
runManager?.getChild("result_generation")
),
};
}
+1 -1
View File
@@ -65,7 +65,7 @@ export class VectorDBQAChain extends BaseChain implements VectorDBQAChainInput {
const inputs = { question, input_documents: docs };
const result = await this.combineDocumentsChain.call(
inputs,
runManager?.getChild()
runManager?.getChild("combine_documents")
);
if (this.returnSourceDocuments) {
return {
+2
View File
@@ -72,6 +72,8 @@ export abstract class BaseChatModel extends BaseLanguageModel {
const callbackManager_ = await CallbackManager.configure(
callbacks,
this.callbacks,
parsedOptions.tags,
this.tags,
{ verbose: this.verbose }
);
const extra = {
@@ -3,7 +3,7 @@
import { test } from "@jest/globals";
import { FigmaFileLoader } from "../web/figma.js";
test("Test FigmaFileLoader", async () => {
test.skip("Test FigmaFileLoader", async () => {
const loader = new FigmaFileLoader({
accessToken: process.env.FIGMA_ACCESS_TOKEN!,
nodeIds: (process.env.FIGMA_NODE_IDS ?? "").split(","),
@@ -4,7 +4,7 @@ import { test } from "@jest/globals";
import { NotionDBLoader } from "../web/notiondb.js";
test("Test NotionDBLoader", async () => {
test.skip("Test NotionDBLoader", async () => {
const loader = new NotionDBLoader({
pageSizeLimit: 10,
notionApiVersion: "2022-06-28",
+285
View File
@@ -0,0 +1,285 @@
import { LLM, BaseLLMParams } from "./base.js";
import { getEnvironmentVariable } from "../util/env.js";
export interface AlephAlphaInput extends BaseLLMParams {
model: string;
maximum_tokens: number;
minimum_tokens?: number;
echo?: boolean;
temperature?: number;
top_k?: number;
top_p?: number;
presence_penalty?: number;
frequency_penalty?: number;
sequence_penalty?: number;
sequence_penalty_min_length?: number;
repetition_penalties_include_prompt?: boolean;
repetition_penalties_include_completion?: boolean;
use_multiplicative_presence_penalty?: boolean;
use_multiplicative_frequency_penalty?: boolean;
use_multiplicative_sequence_penalty?: boolean;
penalty_bias?: string;
penalty_exceptions?: string[];
penalty_exceptions_include_stop_sequences?: boolean;
best_of?: number;
n?: number;
logit_bias?: object;
log_probs?: number;
tokens?: boolean;
raw_completion: boolean;
disable_optimizations?: boolean;
completion_bias_inclusion?: string[];
completion_bias_inclusion_first_token_only: boolean;
completion_bias_exclusion?: string[];
completion_bias_exclusion_first_token_only: boolean;
contextual_control_threshold?: number;
control_log_additive: boolean;
stop?: string[];
aleph_alpha_api_key?: string;
base_url: string;
}
export class AlephAlpha extends LLM implements AlephAlphaInput {
model = "luminous-base";
maximum_tokens = 64;
minimum_tokens = 0;
echo: boolean;
temperature = 0.0;
top_k: number;
top_p = 0.0;
presence_penalty?: number;
frequency_penalty?: number;
sequence_penalty?: number;
sequence_penalty_min_length?: number;
repetition_penalties_include_prompt?: boolean;
repetition_penalties_include_completion?: boolean;
use_multiplicative_presence_penalty?: boolean;
use_multiplicative_frequency_penalty?: boolean;
use_multiplicative_sequence_penalty?: boolean;
penalty_bias?: string;
penalty_exceptions?: string[];
penalty_exceptions_include_stop_sequences?: boolean;
best_of?: number;
n?: number;
logit_bias?: object;
log_probs?: number;
tokens?: boolean;
raw_completion: boolean;
disable_optimizations?: boolean;
completion_bias_inclusion?: string[];
completion_bias_inclusion_first_token_only: boolean;
completion_bias_exclusion?: string[];
completion_bias_exclusion_first_token_only: boolean;
contextual_control_threshold?: number;
control_log_additive: boolean;
aleph_alpha_api_key? = getEnvironmentVariable("ALEPH_ALPHA_API_KEY");
stop?: string[];
base_url = "https://api.aleph-alpha.com/complete";
constructor(fields: Partial<AlephAlpha>) {
super(fields ?? {});
this.model = fields?.model ?? this.model;
this.temperature = fields?.temperature ?? this.temperature;
this.maximum_tokens = fields?.maximum_tokens ?? this.maximum_tokens;
this.minimum_tokens = fields?.minimum_tokens ?? this.minimum_tokens;
this.top_k = fields?.top_k ?? this.top_k;
this.top_p = fields?.top_p ?? this.top_p;
this.presence_penalty = fields?.presence_penalty ?? this.presence_penalty;
this.frequency_penalty =
fields?.frequency_penalty ?? this.frequency_penalty;
this.sequence_penalty = fields?.sequence_penalty ?? this.sequence_penalty;
this.sequence_penalty_min_length =
fields?.sequence_penalty_min_length ?? this.sequence_penalty_min_length;
this.repetition_penalties_include_prompt =
fields?.repetition_penalties_include_prompt ??
this.repetition_penalties_include_prompt;
this.repetition_penalties_include_completion =
fields?.repetition_penalties_include_completion ??
this.repetition_penalties_include_completion;
this.use_multiplicative_presence_penalty =
fields?.use_multiplicative_presence_penalty ??
this.use_multiplicative_presence_penalty;
this.use_multiplicative_frequency_penalty =
fields?.use_multiplicative_frequency_penalty ??
this.use_multiplicative_frequency_penalty;
this.use_multiplicative_sequence_penalty =
fields?.use_multiplicative_sequence_penalty ??
this.use_multiplicative_sequence_penalty;
this.penalty_bias = fields?.penalty_bias ?? this.penalty_bias;
this.penalty_exceptions =
fields?.penalty_exceptions ?? this.penalty_exceptions;
this.penalty_exceptions_include_stop_sequences =
fields?.penalty_exceptions_include_stop_sequences ??
this.penalty_exceptions_include_stop_sequences;
this.best_of = fields?.best_of ?? this.best_of;
this.n = fields?.n ?? this.n;
this.logit_bias = fields?.logit_bias ?? this.logit_bias;
this.log_probs = fields?.log_probs ?? this.log_probs;
this.tokens = fields?.tokens ?? this.tokens;
this.raw_completion = fields?.raw_completion ?? this.raw_completion;
this.disable_optimizations =
fields?.disable_optimizations ?? this.disable_optimizations;
this.completion_bias_inclusion =
fields?.completion_bias_inclusion ?? this.completion_bias_inclusion;
this.completion_bias_inclusion_first_token_only =
fields?.completion_bias_inclusion_first_token_only ??
this.completion_bias_inclusion_first_token_only;
this.completion_bias_exclusion =
fields?.completion_bias_exclusion ?? this.completion_bias_exclusion;
this.completion_bias_exclusion_first_token_only =
fields?.completion_bias_exclusion_first_token_only ??
this.completion_bias_exclusion_first_token_only;
this.contextual_control_threshold =
fields?.contextual_control_threshold ?? this.contextual_control_threshold;
this.control_log_additive =
fields?.control_log_additive ?? this.control_log_additive;
this.aleph_alpha_api_key =
fields?.aleph_alpha_api_key ?? this.aleph_alpha_api_key;
this.stop = fields?.stop ?? this.stop;
}
validateEnvironment() {
if (!this.aleph_alpha_api_key) {
throw new Error(
"Aleph Alpha API Key is missing in environment variables."
);
}
}
/** Get the default parameters for calling Aleph Alpha API. */
get defaultParams() {
return {
model: this.model,
temperature: this.temperature,
maximum_tokens: this.maximum_tokens,
minimum_tokens: this.minimum_tokens,
top_k: this.top_k,
top_p: this.top_p,
presence_penalty: this.presence_penalty,
frequency_penalty: this.frequency_penalty,
sequence_penalty: this.sequence_penalty,
sequence_penalty_min_length: this.sequence_penalty_min_length,
repetition_penalties_include_prompt:
this.repetition_penalties_include_prompt,
repetition_penalties_include_completion:
this.repetition_penalties_include_completion,
use_multiplicative_presence_penalty:
this.use_multiplicative_presence_penalty,
use_multiplicative_frequency_penalty:
this.use_multiplicative_frequency_penalty,
use_multiplicative_sequence_penalty:
this.use_multiplicative_sequence_penalty,
penalty_bias: this.penalty_bias,
penalty_exceptions: this.penalty_exceptions,
penalty_exceptions_include_stop_sequences:
this.penalty_exceptions_include_stop_sequences,
best_of: this.best_of,
n: this.n,
logit_bias: this.logit_bias,
log_probs: this.log_probs,
tokens: this.tokens,
raw_completion: this.raw_completion,
disable_optimizations: this.disable_optimizations,
completion_bias_inclusion: this.completion_bias_inclusion,
completion_bias_inclusion_first_token_only:
this.completion_bias_inclusion_first_token_only,
completion_bias_exclusion: this.completion_bias_exclusion,
completion_bias_exclusion_first_token_only:
this.completion_bias_exclusion_first_token_only,
contextual_control_threshold: this.contextual_control_threshold,
control_log_additive: this.control_log_additive,
};
}
/** Get the identifying parameters for this LLM. */
get identifyingParams() {
return { ...this.defaultParams };
}
/** Get the type of LLM. */
_llmType(): string {
return "aleph_alpha";
}
async _call(
prompt: string,
options: this["ParsedCallOptions"]
): Promise<string> {
let stop = options?.stop;
this.validateEnvironment();
if (this.stop && stop && this.stop.length > 0 && stop.length > 0) {
throw new Error("`stop` found in both the input and default params.");
}
stop = this.stop ?? stop ?? [];
const headers = {
Authorization: `Bearer ${this.aleph_alpha_api_key}`,
"Content-Type": "application/json",
Accept: "application/json",
};
const data = { prompt, stop_sequences: stop, ...this.defaultParams };
const responseData = await this.caller.call(async () => {
const response = await fetch(this.base_url, {
method: "POST",
headers,
body: JSON.stringify(data),
signal: options.signal,
});
if (!response.ok) {
// consume the response body to release the connection
// https://undici.nodejs.org/#/?id=garbage-collection
const text = await response.text();
const error = new Error(
`Aleph Alpha call failed with status ${response.status} and body ${text}`
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(error as any).response = response;
throw error;
}
return response.json();
});
if (
!responseData.completions ||
responseData.completions.length === 0 ||
!responseData.completions[0].completion
) {
throw new Error("No completions found in response");
}
return responseData.completions[0].completion ?? "";
}
}
+2
View File
@@ -96,6 +96,8 @@ export abstract class BaseLLM extends BaseLanguageModel {
const callbackManager_ = await CallbackManager.configure(
callbacks,
this.callbacks,
options.tags,
this.tags,
{ verbose: this.verbose }
);
const extra = { options, invocation_params: this?.invocationParams() };
@@ -0,0 +1,54 @@
import { test, describe, expect } from "@jest/globals";
import { AlephAlpha } from "../aleph_alpha.js";
describe("AI21", () => {
test("test call", async () => {
const aleph_alpha = new AlephAlpha({});
const result = await aleph_alpha.call(
"What is a good name for a company that makes colorful socks?"
);
console.log({ result });
});
test("test translation call", async () => {
const aleph_alpha = new AlephAlpha({});
const result = await aleph_alpha.call(
`Translate "I love programming" into German.`
);
console.log({ result });
});
test("test JSON output call", async () => {
const aleph_alpha = new AlephAlpha({});
const result = await aleph_alpha.call(
`Output a JSON object with three string fields: "name", "birthplace", "bio".`
);
console.log({ result });
});
test("should abort the request", async () => {
const aleph_alpha = new AlephAlpha({});
const controller = new AbortController();
await expect(() => {
const ret = aleph_alpha.call(
"Respond with an extremely verbose response",
{
signal: controller.signal,
}
);
controller.abort();
return ret;
}).rejects.toThrow("AbortError: This operation was aborted");
});
test("throws an error when response status is not ok", async () => {
const aleph_alpha = new AlephAlpha({
aleph_alpha_api_key: "BAD_KEY",
});
await expect(aleph_alpha.call("Test prompt")).rejects.toThrow(
'Aleph Alpha call failed with status 401 and body {"error":"InvalidToken","code":"UNAUTHENTICATED"}'
);
});
});
@@ -27,7 +27,7 @@ test.skip("Test Google Vertex generation", async () => {
console.log(JSON.stringify(res, null, 2));
});
test("Test Google Vertex Codey gecko model", async () => {
test.skip("Test Google Vertex Codey gecko model", async () => {
const model = new GoogleVertexAICode();
expect(model.model).toEqual("code-gecko");
@@ -35,7 +35,7 @@ test("Test Google Vertex Codey gecko model", async () => {
console.log(res);
});
test("Test Google Vertex Codey bison model", async () => {
test.skip("Test Google Vertex Codey bison model", async () => {
const model = new GoogleVertexAICode({
model: "code-bison",
maxOutputTokens: 2048,
+1
View File
@@ -71,6 +71,7 @@ export const optionalImportEntrypoints = [
"langchain/retrievers/self_query/functional",
"langchain/retrievers/self_query/pinecone",
"langchain/retrievers/self_query/supabase",
"langchain/retrievers/self_query/weaviate",
"langchain/cache/momento",
"langchain/cache/redis",
"langchain/stores/doc/gcs",
+1
View File
@@ -11,6 +11,7 @@ export * as embeddings__openai from "../embeddings/openai.js";
export * as llms__base from "../llms/base.js";
export * as llms__openai from "../llms/openai.js";
export * as llms__ai21 from "../llms/ai21.js";
export * as llms__aleph_alpha from "../llms/aleph_alpha.js";
export * as prompts from "../prompts/index.js";
export * as vectorstores__base from "../vectorstores/base.js";
export * as vectorstores__memory from "../vectorstores/memory.js";
+3
View File
@@ -211,6 +211,9 @@ export interface OptionalImportMap {
"langchain/retrievers/self_query/supabase"?:
| typeof import("../retrievers/self_query/supabase.js")
| Promise<typeof import("../retrievers/self_query/supabase.js")>;
"langchain/retrievers/self_query/weaviate"?:
| typeof import("../retrievers/self_query/weaviate.js")
| Promise<typeof import("../retrievers/self_query/weaviate.js")>;
"langchain/cache/momento"?:
| typeof import("../cache/momento.js")
| Promise<typeof import("../cache/momento.js")>;
+2 -1
View File
@@ -1,4 +1,5 @@
import { snakeCase, camelCase } from "case-anything";
import snakeCase from "decamelize";
import camelCase from "camelcase";
export interface SerializedFields {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -0,0 +1,116 @@
/* eslint-disable no-process-env */
import { test } from "@jest/globals";
import weaviate from "weaviate-ts-client";
import { Document } from "../../../document.js";
import { AttributeInfo } from "../../../schema/query_constructor.js";
import { OpenAIEmbeddings } from "../../../embeddings/openai.js";
import { SelfQueryRetriever } from "../index.js";
import { OpenAI } from "../../../llms/openai.js";
import { WeaviateStore } from "../../../vectorstores/weaviate.js";
import { WeaviateTranslator } from "../weaviate.js";
test("Weaviate Self Query Retriever Test", async () => {
const docs = [
new Document({
pageContent:
"A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata: { year: 1993, rating: 7.7, genre: "science fiction" },
}),
new Document({
pageContent:
"Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata: { year: 2010, director: "Christopher Nolan", rating: 8.2 },
}),
new Document({
pageContent:
"A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",
metadata: { year: 2006, director: "Satoshi Kon", rating: 8.6 },
}),
new Document({
pageContent:
"A bunch of normal-sized women are supremely wholesome and some men pine after them",
metadata: { year: 2019, director: "Greta Gerwig", rating: 8.3 },
}),
new Document({
pageContent: "Toys come alive and have a blast doing so",
metadata: { year: 1995, genre: "animated" },
}),
new Document({
pageContent:
"Three men walk into the Zone, three men walk out of the Zone",
metadata: {
year: 1979,
director: "Andrei Tarkovsky",
genre: "science fiction",
rating: 9.9,
},
}),
];
const attributeInfo: AttributeInfo[] = [
{
name: "genre",
description: "The genre of the movie",
type: "string or array of strings",
},
{
name: "year",
description: "The year the movie was released",
type: "number",
},
{
name: "director",
description: "The director of the movie",
type: "string",
},
{
name: "rating",
description: "The rating of the movie (1-10)",
type: "number",
},
{
name: "length",
description: "The length of the movie in minutes",
type: "number",
},
];
const embeddings = new OpenAIEmbeddings();
const llm = new OpenAI({
modelName: "gpt-3.5-turbo",
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const client = (weaviate as any).client({
scheme:
process.env.WEAVIATE_SCHEME ||
(process.env.WEAVIATE_HOST ? "https" : "http"),
host: process.env.WEAVIATE_HOST || "localhost:8080",
apiKey: process.env.WEAVIATE_API_KEY
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
new (weaviate as any).ApiKey(process.env.WEAVIATE_API_KEY)
: undefined,
});
const documentContents = "Brief summary of a movie";
const vectorStore = await WeaviateStore.fromDocuments(docs, embeddings, {
client,
indexName: "Test",
textKey: "text",
metadataKeys: ["year", "director", "rating", "genre"],
});
const selfQueryRetriever = await SelfQueryRetriever.fromLLM({
llm,
vectorStore,
documentContents,
attributeInfo,
structuredQueryTranslator: new WeaviateTranslator(),
});
const query2 = await selfQueryRetriever.getRelevantDocuments(
"Which movies are rated higher than 8.5?"
);
const query3 = await selfQueryRetriever.getRelevantDocuments(
"Which movies are directed by Greta Gerwig?"
);
console.log(query2, query3);
});
@@ -0,0 +1,156 @@
import {
Comparator,
Comparators,
Comparison,
NOT,
Operation,
Operator,
Operators,
StructuredQuery,
Visitor,
} from "../../chains/query_constructor/ir.js";
import { BaseTranslator } from "./base.js";
type AllowedOperator = Exclude<Operator, NOT>;
type WeaviateOperatorValues = {
valueText: string;
valueInt: number;
valueNumber: number;
valueBoolean: boolean;
};
type WeaviateOperatorKeys = keyof WeaviateOperatorValues;
type ExclusiveOperatorValue = {
[L in WeaviateOperatorKeys]: {
[key in L]: WeaviateOperatorValues[key];
} & Omit<{ [key in WeaviateOperatorKeys]?: never }, L>;
}[WeaviateOperatorKeys];
export type WeaviateVisitorResult =
| WeaviateOperationResult
| WeaviateComparisonResult
| WeaviateStructuredQueryResult;
export type WeaviateOperationResult = {
operator: string;
operands: WeaviateVisitorResult[];
};
export type WeaviateComparisonResult = {
path: [string];
operator: string;
} & ExclusiveOperatorValue;
export type WeaviateStructuredQueryResult = {
filter?:
| WeaviateComparisonResult
| WeaviateOperationResult
| WeaviateStructuredQueryResult;
};
export class WeaviateTranslator extends BaseTranslator {
declare VisitOperationOutput: WeaviateOperationResult;
declare VisitComparisonOutput: WeaviateComparisonResult;
declare VisitStructuredQueryOutput: WeaviateStructuredQueryResult;
allowedOperators: Operator[] = [Operators.and, Operators.or];
allowedComparators: Comparator[] = [
Comparators.eq,
Comparators.ne,
Comparators.lt,
Comparators.lte,
Comparators.gt,
Comparators.gte,
];
formatFunction(func: Operator | Comparator): string {
if (func in Comparators) {
if (
this.allowedComparators.length > 0 &&
this.allowedComparators.indexOf(func as Comparator) === -1
) {
throw new Error(
`Comparator ${func} not allowed. Allowed operators: ${this.allowedComparators.join(
", "
)}`
);
}
} else if (func in Operators) {
if (
this.allowedOperators.length > 0 &&
this.allowedOperators.indexOf(func as Operator) === -1
) {
throw new Error(
`Operator ${func} not allowed. Allowed operators: ${this.allowedOperators.join(
", "
)}`
);
}
} else {
throw new Error("Unknown comparator or operator");
}
const dict = {
and: "And",
or: "Or",
eq: "Equal",
ne: "NotEqual",
lt: "LessThan",
lte: "LessThanEqual",
gt: "GreaterThan",
gte: "GreaterThanEqual",
};
return dict[func as Comparator | AllowedOperator];
}
visitOperation(operation: Operation): this["VisitOperationOutput"] {
const args = operation.args?.map((arg) =>
arg.accept(this as Visitor)
) as WeaviateVisitorResult[];
return {
operator: this.formatFunction(operation.operator),
operands: args,
};
}
visitComparison(comparison: Comparison): this["VisitComparisonOutput"] {
if (typeof comparison.value === "string") {
return {
path: [comparison.attribute],
operator: this.formatFunction(comparison.comparator),
valueText: comparison.value,
};
}
if (typeof comparison.value === "number") {
if (Number.isInteger(comparison.value)) {
return {
path: [comparison.attribute],
operator: this.formatFunction(comparison.comparator),
valueInt: comparison.value,
};
} else {
return {
path: [comparison.attribute],
operator: this.formatFunction(comparison.comparator),
valueNumber: comparison.value,
};
}
}
throw new Error("Value type is not supported");
}
visitStructuredQuery(
query: StructuredQuery
): this["VisitStructuredQueryOutput"] {
let nextArg = {};
if (query.filter) {
nextArg = {
filter: { where: query.filter.accept(this as Visitor) },
};
}
return nextArg;
}
}
-6
View File
@@ -158,12 +158,6 @@ export type AgentStep = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ChainValues = Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type RunInputs = Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type RunOutputs = Record<string, any>;
/**
* Base Index class. All indexes should extend this class.
*/
@@ -2,7 +2,7 @@ import { describe, test, expect } from "@jest/globals";
import { GoogleCloudStorageDocstore } from "../gcs.js";
import { Document } from "../../../document.js";
describe("GoogleCloudStorageDocstore", () => {
describe.skip("GoogleCloudStorageDocstore", () => {
const bucket = "INSERT_BUCKET_HERE";
test("save", async () => {
@@ -2,7 +2,7 @@
/* eslint-disable no-process-env */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { test, expect } from "@jest/globals";
import { test, expect, describe } from "@jest/globals";
import { UpstashRedisChatMessageHistory } from "../message/upstash_redis.js";
import { HumanChatMessage, AIChatMessage } from "../../schema/index.js";
@@ -15,119 +15,123 @@ const config = {
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
};
test("Test Redis Upstash history store", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
});
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
});
test("Test clear Redis Upstash history store", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
});
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
await chatHistory.clear();
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
});
test("Test Redis Upstash history with a TTL", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
sessionTTL: 5,
config,
});
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
await new Promise((resolve) => setTimeout(resolve, 5000));
const expiredResult = await chatHistory.getMessages();
expect(expiredResult).toStrictEqual([]);
});
test("Test Redis Upstash memory with Buffer Memory", async () => {
const memory = new BufferMemory({
returnMessages: true,
chatHistory: new UpstashRedisChatMessageHistory({
describe.skip("UpstashRedisChatMessageHistory", () => {
test("Test Redis Upstash history store", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
}),
});
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
});
await memory.saveContext(
{ input: "Who is the best vocalist?" },
{ response: "Ozzy Osbourne" }
);
const expectedHistory = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const result2 = await memory.loadMemoryVariables({});
expect(result2).toStrictEqual({ history: expectedHistory });
});
test("Test Redis Upstash memory with LLM Chain", async () => {
const memory = new BufferMemory({
chatHistory: new UpstashRedisChatMessageHistory({
test("Test clear Redis Upstash history store", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
}),
});
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
await chatHistory.clear();
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
});
const model = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
temperature: 0,
test("Test Redis Upstash history with a TTL", async () => {
const chatHistory = new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
sessionTTL: 5,
config,
});
const blankResult = await chatHistory.getMessages();
expect(blankResult).toStrictEqual([]);
await chatHistory.addUserMessage("Who is the best vocalist?");
await chatHistory.addAIChatMessage("Ozzy Osbourne");
const expectedMessages = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const resultWithHistory = await chatHistory.getMessages();
expect(resultWithHistory).toEqual(expectedMessages);
await new Promise((resolve) => setTimeout(resolve, 5000));
const expiredResult = await chatHistory.getMessages();
expect(expiredResult).toStrictEqual([]);
});
const chain = new ConversationChain({ llm: model, memory });
const res1 = await chain.call({ input: "Hi! I'm Jim." });
console.log({ res1 });
test("Test Redis Upstash memory with Buffer Memory", async () => {
const memory = new BufferMemory({
returnMessages: true,
chatHistory: new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
}),
});
const res2 = await chain.call({ input: "What did I just say my name was?" });
console.log({ res2 });
await memory.saveContext(
{ input: "Who is the best vocalist?" },
{ response: "Ozzy Osbourne" }
);
expect(res2.response).toContain("Jim");
const expectedHistory = [
new HumanChatMessage("Who is the best vocalist?"),
new AIChatMessage("Ozzy Osbourne"),
];
const result2 = await memory.loadMemoryVariables({});
expect(result2).toStrictEqual({ history: expectedHistory });
});
test("Test Redis Upstash memory with LLM Chain", async () => {
const memory = new BufferMemory({
chatHistory: new UpstashRedisChatMessageHistory({
sessionId: new Date().toISOString(),
config,
}),
});
const model = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
temperature: 0,
});
const chain = new ConversationChain({ llm: model, memory });
const res1 = await chain.call({ input: "Hi! I'm Jim." });
console.log({ res1 });
const res2 = await chain.call({
input: "What did I just say my name was?",
});
console.log({ res2 });
expect(res2.response).toContain("Jim");
});
});
@@ -287,3 +287,32 @@ test("Rust code splitter", async () => {
"}",
]);
});
test("Solidity code splitter", async () => {
const splitter = RecursiveCharacterTextSplitter.fromLanguage("sol", {
chunkSize: 16,
chunkOverlap: 0,
});
const code = `pragma solidity ^0.8.20;
contract HelloWorld {
function add(uint a, uint b) pure public returns(uint) {
return a + b;
}
}
`;
const chunks = await splitter.splitText(code);
expect(chunks).toStrictEqual([
"pragma solidity",
"^0.8.20;",
"contract",
"HelloWorld {",
"function",
"add(uint a,",
"uint b) pure",
"public",
"returns(uint) {",
"return a",
"+ b;",
"}\n }",
]);
});
+31
View File
@@ -222,6 +222,7 @@ export const SupportedTextSplitterLanguages = [
"markdown",
"latex",
"html",
"sol",
] as const;
export type SupportedTextSplitterLanguage =
@@ -617,6 +618,36 @@ export class RecursiveCharacterTextSplitter
" ",
"",
];
} else if (language === "sol") {
return [
// Split along compiler informations definitions
"\npragma ",
"\nusing ",
// Split along contract definitions
"\ncontract ",
"\ninterface ",
"\nlibrary ",
// Split along method definitions
"\nconstructor ",
"\ntype ",
"\nfunction ",
"\nevent ",
"\nmodifier ",
"\nerror ",
"\nstruct ",
"\nenum ",
// Split along control flow statements
"\nif ",
"\nfor ",
"\nwhile ",
"\ndo while ",
"\nassembly ",
// Split by the normal type of lines
"\n\n",
"\n",
" ",
"",
];
} else {
throw new Error(`Language ${language} is not supported.`);
}
+4 -1
View File
@@ -32,12 +32,15 @@ export abstract class StructuredTool<
async call(
arg: (z.output<T> extends string ? string : never) | z.input<T>,
callbacks?: Callbacks
callbacks?: Callbacks,
tags?: string[]
): Promise<string> {
const parsed = await this.schema.parseAsync(arg);
const callbackManager_ = await CallbackManager.configure(
callbacks,
this.callbacks,
tags,
this.tags,
{ verbose: this.verbose }
);
const runManager = await callbackManager_?.handleToolStart(
@@ -1,7 +1,7 @@
import { test } from "@jest/globals";
import { BraveSearch } from "../brave_search.js";
test("BraveSearchTool", async () => {
test.skip("BraveSearchTool", async () => {
const tool = new BraveSearch();
const result = await tool.call("What is Langchain?");
@@ -1,7 +1,7 @@
import { test } from "@jest/globals";
import { GoogleCustomSearch } from "../google_custom_search.js";
test("GoogleCustomSearchTool", async () => {
test.skip("GoogleCustomSearchTool", async () => {
const tool = new GoogleCustomSearch();
const result = await tool.call("What is Langchain?");
@@ -111,7 +111,7 @@ describe("webbrowser Test suite", () => {
// other urls that have done this too
// "https://wsimag.com/economy-and-politics/15473-power-and-money",
// "https://thriveglobal.com/stories/sleep-what-to-do-what-not-to-do",
test("get a summary of a page that redirects too many times", async () => {
test.skip("get a summary of a page that redirects too many times", async () => {
const model = new ChatOpenAI({ temperature: 0 });
const embeddings = new OpenAIEmbeddings();
@@ -6,7 +6,7 @@ import { OpenAIEmbeddings } from "../../embeddings/openai.js";
import { SingleStoreVectorStore } from "../singlestore.js";
import { Document } from "../../document.js";
test("SingleStoreVectorStore", async () => {
test.skip("SingleStoreVectorStore", async () => {
expect(process.env.SINGLESTORE_HOST).toBeDefined();
expect(process.env.SINGLESTORE_PORT).toBeDefined();
expect(process.env.SINGLESTORE_USERNAME).toBeDefined();
@@ -5,16 +5,18 @@ import { WeaviateStore } from "../weaviate.js";
import { OpenAIEmbeddings } from "../../embeddings/openai.js";
import { Document } from "../../document.js";
test.skip("WeaviateStore", async () => {
test("WeaviateStore", async () => {
// Something wrong with the weaviate-ts-client types, so we need to disable
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const client = (weaviate as any).client({
scheme: process.env.WEAVIATE_SCHEME || "https",
host: process.env.WEAVIATE_HOST || "localhost",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
apiKey: new (weaviate as any).ApiKey(
process.env.WEAVIATE_API_KEY || "default"
),
scheme:
process.env.WEAVIATE_SCHEME ||
(process.env.WEAVIATE_HOST ? "https" : "http"),
host: process.env.WEAVIATE_HOST || "localhost:8080",
apiKey: process.env.WEAVIATE_API_KEY
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
new (weaviate as any).ApiKey(process.env.WEAVIATE_API_KEY)
: undefined,
});
const store = await WeaviateStore.fromTexts(
["hello world", "hi there", "how are you", "bye now"],
@@ -62,7 +64,7 @@ test.skip("WeaviateStore", async () => {
client,
indexName: "DocumentTest",
textKey: "text",
metadataKeys: ["deep.string", "deep.deepdeep.string"],
metadataKeys: ["deep_string", "deep_deepdeep_string"],
}
);
@@ -72,7 +74,7 @@ test.skip("WeaviateStore", async () => {
{
where: {
operator: "Equal",
path: ["deep.string"],
path: ["deep_string"],
valueText: "deep string",
},
}
@@ -81,8 +83,8 @@ test.skip("WeaviateStore", async () => {
new Document({
pageContent: "this is the deep document world!",
metadata: {
"deep.string": "deep string",
"deep.deepdeep.string": "even a deeper string",
deep_string: "deep string",
deep_deepdeep_string: "even a deeper string",
},
}),
]);
+16 -1
View File
@@ -89,7 +89,22 @@ export class WeaviateStore extends VectorStore {
this.queryAttrs = [this.textKey];
if (args.metadataKeys) {
this.queryAttrs = this.queryAttrs.concat(args.metadataKeys);
this.queryAttrs = [
...new Set([
...this.queryAttrs,
...args.metadataKeys.filter((k) => {
// https://spec.graphql.org/June2018/#sec-Names
// queryAttrs need to be valid GraphQL Names
const keyIsValid = /^[_A-Za-z][_0-9A-Za-z]*$/.test(k);
if (!keyIsValid) {
console.warn(
`Skipping metadata key ${k} as it is not a valid GraphQL Name`
);
}
return keyIsValid;
}),
]),
];
}
}
+2
View File
@@ -56,6 +56,7 @@
"src/llms/base.ts",
"src/llms/openai.ts",
"src/llms/ai21.ts",
"src/llms/aleph_alpha.ts",
"src/llms/cohere.ts",
"src/llms/hf.ts",
"src/llms/replicate.ts",
@@ -137,6 +138,7 @@
"src/retrievers/self_query/functional.ts",
"src/retrievers/self_query/pinecone.ts",
"src/retrievers/self_query/supabase.ts",
"src/retrievers/self_query/weaviate.ts",
"src/retrievers/vespa.ts",
"src/cache/index.ts",
"src/cache/momento.ts",
+1 -1
View File
@@ -35,7 +35,7 @@
"test:int:deps": "docker compose -f test-int-deps-docker-compose.yml up -d",
"test:int:deps:down": "docker compose -f test-int-deps-docker-compose.yml down",
"test:exports:docker": "docker compose up",
"publish": "bash scripts/release-branch.sh && turbo run build lint test test:integration && yarn run test:exports:docker && yarn workspace langchain run release && echo '🔗 Open https://github.com/hwchase17/langchainjs/compare/release?expand=1 and merge the release PR'",
"publish": "bash scripts/release-branch.sh && turbo run --filter langchain build lint test test:integration && yarn run test:exports:docker && yarn workspace langchain run release && echo '🔗 Open https://github.com/hwchase17/langchainjs/compare/release?expand=1 and merge the release PR'",
"example": "yarn workspace examples start",
"prepare": "husky install",
"precommit": "turbo run precommit",
+1
View File
@@ -10,6 +10,7 @@ export * from "langchain/embeddings/openai";
export * from "langchain/llms/base";
export * from "langchain/llms/openai";
export * from "langchain/llms/ai21";
export * from "langchain/llms/aleph_alpha";
export * from "langchain/prompts";
export * from "langchain/vectorstores/base";
export * from "langchain/vectorstores/memory";
+1
View File
@@ -10,6 +10,7 @@ const embeddings_openai = require("langchain/embeddings/openai");
const llms_base = require("langchain/llms/base");
const llms_openai = require("langchain/llms/openai");
const llms_ai21 = require("langchain/llms/ai21");
const llms_aleph_alpha = require("langchain/llms/aleph_alpha");
const prompts = require("langchain/prompts");
const vectorstores_base = require("langchain/vectorstores/base");
const vectorstores_memory = require("langchain/vectorstores/memory");
+1
View File
@@ -10,6 +10,7 @@ export * from "langchain/embeddings/openai";
export * from "langchain/llms/base";
export * from "langchain/llms/openai";
export * from "langchain/llms/ai21";
export * from "langchain/llms/aleph_alpha";
export * from "langchain/prompts";
export * from "langchain/vectorstores/base";
export * from "langchain/vectorstores/memory";
+1
View File
@@ -10,6 +10,7 @@ import * as embeddings_openai from "langchain/embeddings/openai";
import * as llms_base from "langchain/llms/base";
import * as llms_openai from "langchain/llms/openai";
import * as llms_ai21 from "langchain/llms/ai21";
import * as llms_aleph_alpha from "langchain/llms/aleph_alpha";
import * as prompts from "langchain/prompts";
import * as vectorstores_base from "langchain/vectorstores/base";
import * as vectorstores_memory from "langchain/vectorstores/memory";
+1
View File
@@ -10,6 +10,7 @@ import * as embeddings_openai from "langchain/embeddings/openai";
import * as llms_base from "langchain/llms/base";
import * as llms_openai from "langchain/llms/openai";
import * as llms_ai21 from "langchain/llms/ai21";
import * as llms_aleph_alpha from "langchain/llms/aleph_alpha";
import * as prompts from "langchain/prompts";
import * as vectorstores_base from "langchain/vectorstores/base";
import * as vectorstores_memory from "langchain/vectorstores/memory";
+1
View File
@@ -10,6 +10,7 @@ export * from "langchain/embeddings/openai";
export * from "langchain/llms/base";
export * from "langchain/llms/openai";
export * from "langchain/llms/ai21";
export * from "langchain/llms/aleph_alpha";
export * from "langchain/prompts";
export * from "langchain/vectorstores/base";
export * from "langchain/vectorstores/memory";
+1
View File
@@ -10,6 +10,7 @@ export * from "langchain/embeddings/openai";
export * from "langchain/llms/base";
export * from "langchain/llms/openai";
export * from "langchain/llms/ai21";
export * from "langchain/llms/aleph_alpha";
export * from "langchain/prompts";
export * from "langchain/vectorstores/base";
export * from "langchain/vectorstores/memory";
+12 -7
View File
@@ -1,14 +1,19 @@
version: '3.8'
services:
cache:
redis:
image: redis:6.2-alpine
restart: always
ports:
- '6379:6379'
command: redis-server --save 20 1 --loglevel warning
volumes:
- cache:/data
volumes:
cache:
driver: local
weaviate:
image: semitechnologies/weaviate:1.19.7
ports:
- 8080:8080
restart: on-failure:0
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
CLUSTER_HOSTNAME: 'node1'
+152 -33
View File
@@ -5475,6 +5475,20 @@ __metadata:
languageName: node
linkType: hard
"@isaacs/cliui@npm:^8.0.2":
version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2"
dependencies:
string-width: ^5.1.2
string-width-cjs: "npm:string-width@^4.2.0"
strip-ansi: ^7.0.1
strip-ansi-cjs: "npm:strip-ansi@^6.0.1"
wrap-ansi: ^8.1.0
wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0"
checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb
languageName: node
linkType: hard
"@istanbuljs/load-nyc-config@npm:^1.0.0":
version: 1.1.0
resolution: "@istanbuljs/load-nyc-config@npm:1.1.0"
@@ -6653,6 +6667,13 @@ __metadata:
languageName: node
linkType: hard
"@pkgjs/parseargs@npm:^0.11.0":
version: 0.11.0
resolution: "@pkgjs/parseargs@npm:0.11.0"
checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f
languageName: node
linkType: hard
"@pkgr/utils@npm:^2.3.1":
version: 2.3.1
resolution: "@pkgr/utils@npm:2.3.1"
@@ -8478,13 +8499,20 @@ __metadata:
languageName: node
linkType: hard
"@types/uuid@npm:^9, @types/uuid@npm:^9.0.1":
"@types/uuid@npm:^9":
version: 9.0.1
resolution: "@types/uuid@npm:9.0.1"
checksum: c472b8a77cbeded4bc529220b8611afa39bd64677f507838f8083d8aac8033b1f88cb9ddaa2f8589e0dcd2317291d0f6e1379f82d5ceebd6f74f3b4825288e00
languageName: node
linkType: hard
"@types/uuid@npm:^9.0.1":
version: 9.0.2
resolution: "@types/uuid@npm:9.0.2"
checksum: 1754bcf3444e1e3aeadd6e774fc328eb53bc956665e2e8fb6ec127aa8e1f43d9a224c3d22a9a6233dca8dd81a12dc7fed4d84b8876dd5ec82d40f574f7ff8b68
languageName: node
linkType: hard
"@types/webgl-ext@npm:0.0.30":
version: 0.0.30
resolution: "@types/webgl-ext@npm:0.0.30"
@@ -10706,6 +10734,13 @@ __metadata:
languageName: node
linkType: hard
"camelcase@npm:6, camelcase@npm:^6.2.0, camelcase@npm:^6.2.1":
version: 6.3.0
resolution: "camelcase@npm:6.3.0"
checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d
languageName: node
linkType: hard
"camelcase@npm:^5.3.1":
version: 5.3.1
resolution: "camelcase@npm:5.3.1"
@@ -10713,13 +10748,6 @@ __metadata:
languageName: node
linkType: hard
"camelcase@npm:^6.2.0, camelcase@npm:^6.2.1":
version: 6.3.0
resolution: "camelcase@npm:6.3.0"
checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d
languageName: node
linkType: hard
"camelcase@npm:^7.0.0":
version: 7.0.1
resolution: "camelcase@npm:7.0.1"
@@ -10753,13 +10781,6 @@ __metadata:
languageName: node
linkType: hard
"case-anything@npm:^2.1.13":
version: 2.1.13
resolution: "case-anything@npm:2.1.13"
checksum: c39c69d7e418337b6006a9692f13c2b257e907e867149a102e9beb7e9d2d52da14e754da1f4e4ce82a866d86d93047e522f64360bda54e7d7c308f4cdd736c3d
languageName: node
linkType: hard
"case-sensitive-paths-webpack-plugin@npm:^2.4.0":
version: 2.4.0
resolution: "case-sensitive-paths-webpack-plugin@npm:2.4.0"
@@ -11664,7 +11685,7 @@ __metadata:
languageName: node
linkType: hard
"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
dependencies:
@@ -12145,6 +12166,13 @@ __metadata:
languageName: node
linkType: hard
"decamelize@npm:5":
version: 5.0.1
resolution: "decamelize@npm:5.0.1"
checksum: 7c3b1ed4b3e60e7fbc00a35fb248298527c1cdfe603e41dfcf05e6c4a8cb9efbee60630deb677ed428908fb4e74e322966c687a094d1478ddc9c3a74e9dc7140
languageName: node
linkType: hard
"decimal.js@npm:^10.2.1, decimal.js@npm:^10.3.1":
version: 10.4.3
resolution: "decimal.js@npm:10.4.3"
@@ -12559,6 +12587,7 @@ __metadata:
process: ^0.11.10
react: ^17.0.2
react-dom: ^17.0.2
rimraf: ^5.0.1
swc-loader: ^0.2.3
typedoc: ^0.24.4
typedoc-plugin-markdown: next
@@ -14238,7 +14267,6 @@ __metadata:
graphql: ^16.6.0
js-yaml: ^4.1.0
langchain: "workspace:*"
langchainplus-sdk: ">=0.0.11"
ml-distance: ^4.0.0
mongodb: ^5.2.0
mysql2: ^3.3.3
@@ -14823,6 +14851,16 @@ __metadata:
languageName: node
linkType: hard
"foreground-child@npm:^3.1.0":
version: 3.1.1
resolution: "foreground-child@npm:3.1.1"
dependencies:
cross-spawn: ^7.0.0
signal-exit: ^4.0.1
checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5
languageName: node
linkType: hard
"fork-ts-checker-webpack-plugin@npm:^6.5.0":
version: 6.5.3
resolution: "fork-ts-checker-webpack-plugin@npm:6.5.3"
@@ -15309,6 +15347,21 @@ __metadata:
languageName: node
linkType: hard
"glob@npm:^10.2.5":
version: 10.2.7
resolution: "glob@npm:10.2.7"
dependencies:
foreground-child: ^3.1.0
jackspeak: ^2.0.3
minimatch: ^9.0.1
minipass: ^5.0.0 || ^6.0.2
path-scurry: ^1.7.0
bin:
glob: dist/cjs/src/bin.js
checksum: 555205a74607d6f8d9874ba888924b305b5ea1abfaa2e9ccb11ac713d040aac7edbf7d8702a2f4a1cd81b2d7666412170ce7ef061d33cddde189dae8c1a1a054
languageName: node
linkType: hard
"glob@npm:^7.0.0, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
version: 7.2.3
resolution: "glob@npm:7.2.3"
@@ -17072,6 +17125,19 @@ __metadata:
languageName: node
linkType: hard
"jackspeak@npm:^2.0.3":
version: 2.2.1
resolution: "jackspeak@npm:2.2.1"
dependencies:
"@isaacs/cliui": ^8.0.2
"@pkgjs/parseargs": ^0.11.0
dependenciesMeta:
"@pkgjs/parseargs":
optional: true
checksum: e29291c0d0f280a063fa18fbd1e891ab8c2d7519fd34052c0ebde38538a15c603140d60c2c7f432375ff7ee4c5f1c10daa8b2ae19a97c3d4affe308c8360c1df
languageName: node
linkType: hard
"jake@npm:^10.8.5":
version: 10.8.5
resolution: "jake@npm:10.8.5"
@@ -18562,11 +18628,12 @@ __metadata:
apify-client: ^2.7.1
axios: ^0.26.0
binary-extensions: ^2.2.0
case-anything: ^2.1.13
camelcase: 6
cheerio: ^1.0.0-rc.12
chromadb: ^1.5.2
cohere-ai: ^5.0.2
d3-dsv: ^2.0.0
decamelize: 5
dotenv: ^16.0.3
dpdm: ^3.12.0
epub2: ^3.0.1
@@ -18587,7 +18654,7 @@ __metadata:
jest: ^29.5.0
js-tiktoken: ^1.0.6
jsonpointer: ^5.0.1
langchainplus-sdk: ">=0.0.11"
langchainplus-sdk: ^0.0.11
mammoth: ^1.5.1
ml-distance: ^4.0.0
mongodb: ^5.2.0
@@ -18606,6 +18673,7 @@ __metadata:
redis: ^4.6.6
release-it: ^15.10.1
replicate: ^0.9.0
rimraf: ^5.0.1
rollup: ^3.19.1
sqlite3: ^5.1.4
srt-parser-2: ^1.2.2
@@ -18777,7 +18845,7 @@ __metadata:
languageName: unknown
linkType: soft
"langchainplus-sdk@npm:>=0.0.11":
"langchainplus-sdk@npm:^0.0.11":
version: 0.0.11
resolution: "langchainplus-sdk@npm:0.0.11"
dependencies:
@@ -19249,6 +19317,13 @@ __metadata:
languageName: node
linkType: hard
"lru-cache@npm:^9.1.1":
version: 9.1.2
resolution: "lru-cache@npm:9.1.2"
checksum: d3415634be3908909081fc4c56371a8d562d9081eba70543d86871b978702fffd0e9e362b83921b27a29ae2b37b90f55675aad770a54ac83bb3e4de5049d4b15
languageName: node
linkType: hard
"lunr@npm:^2.3.9":
version: 2.3.9
resolution: "lunr@npm:2.3.9"
@@ -19702,6 +19777,15 @@ __metadata:
languageName: node
linkType: hard
"minimatch@npm:^9.0.1":
version: 9.0.1
resolution: "minimatch@npm:9.0.1"
dependencies:
brace-expansion: ^2.0.1
checksum: 97f5f5284bb57dc65b9415dec7f17a0f6531a33572193991c60ff18450dcfad5c2dad24ffeaf60b5261dccd63aae58cc3306e2209d57e7f88c51295a532d8ec3
languageName: node
linkType: hard
"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
@@ -19791,6 +19875,13 @@ __metadata:
languageName: node
linkType: hard
"minipass@npm:^5.0.0 || ^6.0.2":
version: 6.0.2
resolution: "minipass@npm:6.0.2"
checksum: d140b91f4ab2e5ce5a9b6c468c0e82223504acc89114c1a120d4495188b81fedf8cade72a9f4793642b4e66672f990f1e0d902dd858485216a07cd3c8a62fac9
languageName: node
linkType: hard
"minizlib@npm:^2.0.0, minizlib@npm:^2.1.1, minizlib@npm:^2.1.2":
version: 2.1.2
resolution: "minizlib@npm:2.1.2"
@@ -21194,6 +21285,16 @@ __metadata:
languageName: node
linkType: hard
"path-scurry@npm:^1.7.0":
version: 1.9.2
resolution: "path-scurry@npm:1.9.2"
dependencies:
lru-cache: ^9.1.1
minipass: ^5.0.0 || ^6.0.2
checksum: 92888dfb68e285043c6d3291c8e971d5d2bc2f5082f4d7b5392896f34be47024c9d0a8b688dd7ae6d125acc424699195474927cb4f00049a9b1ec7c4256fa8e0
languageName: node
linkType: hard
"path-to-regexp@npm:0.1.7":
version: 0.1.7
resolution: "path-to-regexp@npm:0.1.7"
@@ -23978,6 +24079,17 @@ __metadata:
languageName: node
linkType: hard
"rimraf@npm:^5.0.1":
version: 5.0.1
resolution: "rimraf@npm:5.0.1"
dependencies:
glob: ^10.2.5
bin:
rimraf: dist/cjs/src/bin.js
checksum: bafce85391349a2d960847980bf9b5caa2a8887f481af630f1ea27e08288217293cec72d75e9a2ba35495c212789f66a7f3d23366ba6197026ab71c535126857
languageName: node
linkType: hard
"rollup-plugin-inject@npm:^3.0.0":
version: 3.0.2
resolution: "rollup-plugin-inject@npm:3.0.2"
@@ -24620,6 +24732,13 @@ __metadata:
languageName: node
linkType: hard
"signal-exit@npm:^4.0.1":
version: 4.0.2
resolution: "signal-exit@npm:4.0.2"
checksum: 41f5928431cc6e91087bf0343db786a6313dd7c6fd7e551dbc141c95bb5fb26663444fd9df8ea47c5d7fc202f60aa7468c3162a9365cbb0615fc5e1b1328fe31
languageName: node
linkType: hard
"simple-concat@npm:^1.0.0":
version: 1.0.1
resolution: "simple-concat@npm:1.0.1"
@@ -25126,7 +25245,7 @@ __metadata:
languageName: node
linkType: hard
"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3":
"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3":
version: 4.2.3
resolution: "string-width@npm:4.2.3"
dependencies:
@@ -25233,7 +25352,7 @@ __metadata:
languageName: node
linkType: hard
"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
version: 6.0.1
resolution: "strip-ansi@npm:6.0.1"
dependencies:
@@ -28209,6 +28328,17 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
dependencies:
ansi-styles: ^4.0.0
string-width: ^4.1.0
strip-ansi: ^6.0.0
checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b
languageName: node
linkType: hard
"wrap-ansi@npm:^6.2.0":
version: 6.2.0
resolution: "wrap-ansi@npm:6.2.0"
@@ -28220,17 +28350,6 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
dependencies:
ansi-styles: ^4.0.0
string-width: ^4.1.0
strip-ansi: ^6.0.0
checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b
languageName: node
linkType: hard
"wrap-ansi@npm:^8.0.1, wrap-ansi@npm:^8.1.0":
version: 8.1.0
resolution: "wrap-ansi@npm:8.1.0"