mirror of
https://github.com/Mintplex-Labs/langchainjs.git
synced 2026-07-01 12:17:38 -04:00
Implement new serialization format, currently working for all llms, chat models and prompts, and some chains
Serialization improvements
This commit is contained in:
@@ -58,6 +58,9 @@ module.exports = {
|
||||
"no-return-await": 0,
|
||||
"consistent-return": 0,
|
||||
"no-else-return": 0,
|
||||
"func-names": 0,
|
||||
"no-lonely-if": 0,
|
||||
"prefer-rest-params": 0,
|
||||
"new-cap": ["error", { properties: false, capIsNew: false }],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
load.cjs
|
||||
load.js
|
||||
load.d.ts
|
||||
agents.cjs
|
||||
agents.js
|
||||
agents.d.ts
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"dist/",
|
||||
"load.cjs",
|
||||
"load.js",
|
||||
"load.d.ts",
|
||||
"agents.cjs",
|
||||
"agents.js",
|
||||
"agents.d.ts",
|
||||
@@ -404,7 +407,7 @@
|
||||
"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 clean",
|
||||
"clean": "rm -rf 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",
|
||||
@@ -728,6 +731,11 @@
|
||||
"import": "./index.js",
|
||||
"require": "./index.cjs"
|
||||
},
|
||||
"./load": {
|
||||
"types": "./load.d.ts",
|
||||
"import": "./load.js",
|
||||
"require": "./load.cjs"
|
||||
},
|
||||
"./agents": {
|
||||
"types": "./agents.d.ts",
|
||||
"import": "./agents.js",
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as path from "path";
|
||||
// This is used to generate the `exports` field in package.json.
|
||||
// Order is not important.
|
||||
const entrypoints = {
|
||||
load: "load/index",
|
||||
// agents
|
||||
agents: "agents/index",
|
||||
"agents/load": "agents/load",
|
||||
@@ -373,10 +374,89 @@ const cleanGenerated = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// Tuple describing the auto-generated import map (used by langchain/load)
|
||||
// [package name, import statement, import map path]
|
||||
// This will not include entrypoints deprecated or requiring optional deps.
|
||||
const importMap = [
|
||||
"langchain",
|
||||
(k, p) => `export * as ${k.replace(/\//g, "__")} from "../${p}.js";`,
|
||||
"src/load/import_map.ts",
|
||||
];
|
||||
|
||||
const generateImportMap = () => {
|
||||
// Generate import map
|
||||
const entrypointsToInclude = Object.keys(entrypoints)
|
||||
.filter((key) => key !== "load")
|
||||
.filter((key) => !deprecatedNodeOnly.includes(key))
|
||||
.filter((key) => !requiresOptionalDependency.includes(key));
|
||||
const [pkg, importStatement, importMapPath] = importMap;
|
||||
const contents =
|
||||
entrypointsToInclude
|
||||
.map((key) => importStatement(key, entrypoints[key]))
|
||||
.join("\n") + "\n";
|
||||
fs.writeFileSync(
|
||||
`../${pkg}/${importMapPath}`,
|
||||
"// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.\n\n" +
|
||||
contents
|
||||
);
|
||||
};
|
||||
|
||||
const importTypes = [
|
||||
"langchain",
|
||||
(k) =>
|
||||
` "langchain/${k}"?:
|
||||
| typeof import("../${k}.js")
|
||||
| Promise<typeof import("../${k}.js")>;`,
|
||||
"src/load/import_type.d.ts",
|
||||
];
|
||||
|
||||
const generateImportTypes = () => {
|
||||
// Generate import types
|
||||
const entrypointsToInclude = Object.keys(entrypoints)
|
||||
.filter((key) => !deprecatedNodeOnly.includes(key))
|
||||
.filter((key) => requiresOptionalDependency.includes(key));
|
||||
const [pkg, importStatement, importTypesPath] = importTypes;
|
||||
const contents =
|
||||
entrypointsToInclude
|
||||
.map((key) => importStatement(key, entrypoints[key]))
|
||||
.join("\n") + "\n}\n";
|
||||
fs.writeFileSync(
|
||||
`../${pkg}/${importTypesPath}`,
|
||||
"// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.\n\nexport interface OptionalImportMap {\n" +
|
||||
contents
|
||||
);
|
||||
};
|
||||
|
||||
const importConstants = [
|
||||
"langchain",
|
||||
(k) => ` "langchain/${k}"`,
|
||||
"src/load/import_constants.ts",
|
||||
];
|
||||
|
||||
const generateImportConstants = () => {
|
||||
// Generate import constants
|
||||
const entrypointsToInclude = Object.keys(entrypoints)
|
||||
.filter((key) => !deprecatedNodeOnly.includes(key))
|
||||
.filter((key) => requiresOptionalDependency.includes(key));
|
||||
const [pkg, importStatement, importConstantsPath] = importConstants;
|
||||
const contents =
|
||||
entrypointsToInclude
|
||||
.map((key) => importStatement(key, entrypoints[key]))
|
||||
.join(",\n") + "\n]\n";
|
||||
fs.writeFileSync(
|
||||
`../${pkg}/${importConstantsPath}`,
|
||||
"// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.\n\nexport const optionalImportEntrypoints = [\n" +
|
||||
contents
|
||||
);
|
||||
};
|
||||
|
||||
const command = process.argv[2];
|
||||
|
||||
if (command === "clean") {
|
||||
if (command === "pre") {
|
||||
cleanGenerated();
|
||||
generateImportMap();
|
||||
generateImportTypes();
|
||||
generateImportConstants();
|
||||
} else {
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { CallbackManager, Callbacks } from "../callbacks/manager.js";
|
||||
import { AsyncCaller, AsyncCallerParams } from "../util/async_caller.js";
|
||||
import { getModelNameForTiktoken } from "./count_tokens.js";
|
||||
import { encodingForModel } from "../util/tiktoken.js";
|
||||
import { Serializable } from "../schema/load.js";
|
||||
|
||||
const getVerbosity = () => false;
|
||||
|
||||
@@ -25,7 +26,10 @@ export interface BaseLangChainParams {
|
||||
/**
|
||||
* Base class for language models, chains, tools.
|
||||
*/
|
||||
export abstract class BaseLangChain implements BaseLangChainParams {
|
||||
export abstract class BaseLangChain
|
||||
extends Serializable
|
||||
implements BaseLangChainParams
|
||||
{
|
||||
/**
|
||||
* Whether to print out response text.
|
||||
*/
|
||||
@@ -34,6 +38,7 @@ export abstract class BaseLangChain implements BaseLangChainParams {
|
||||
callbacks?: Callbacks;
|
||||
|
||||
constructor(params: BaseLangChainParams) {
|
||||
super(params);
|
||||
this.verbose = params.verbose ?? getVerbosity();
|
||||
this.callbacks = params.callbacks;
|
||||
}
|
||||
@@ -94,10 +99,14 @@ export abstract class BaseLanguageModel
|
||||
*/
|
||||
caller: AsyncCaller;
|
||||
|
||||
constructor(params: BaseLanguageModelParams) {
|
||||
constructor({
|
||||
callbacks,
|
||||
callbackManager,
|
||||
...params
|
||||
}: BaseLanguageModelParams) {
|
||||
super({
|
||||
verbose: params.verbose,
|
||||
callbacks: params.callbacks ?? params.callbackManager,
|
||||
callbacks: callbacks ?? callbackManager,
|
||||
...params,
|
||||
});
|
||||
this.caller = new AsyncCaller(params ?? {});
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
ChainValues,
|
||||
LLMResult,
|
||||
} from "../schema/index.js";
|
||||
import { Serializable, Serialized } from "../schema/load.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type Error = any;
|
||||
@@ -166,8 +167,16 @@ export type CallbackHandlerMethods = BaseCallbackHandlerMethodsClass;
|
||||
|
||||
export abstract class BaseCallbackHandler
|
||||
extends BaseCallbackHandlerMethodsClass
|
||||
implements BaseCallbackHandlerInput
|
||||
implements BaseCallbackHandlerInput, Serializable
|
||||
{
|
||||
lc_namespace = ["langchain", "callbacks"];
|
||||
|
||||
get lc_name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
lc_arguments: unknown[];
|
||||
|
||||
abstract name: string;
|
||||
|
||||
ignoreLLM = false;
|
||||
@@ -184,6 +193,7 @@ export abstract class BaseCallbackHandler
|
||||
|
||||
constructor(input?: BaseCallbackHandlerInput) {
|
||||
super();
|
||||
this.lc_arguments = [input];
|
||||
if (input) {
|
||||
this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
|
||||
this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
|
||||
@@ -197,6 +207,10 @@ export abstract class BaseCallbackHandler
|
||||
) => BaseCallbackHandler)(this);
|
||||
}
|
||||
|
||||
toJSON(): Serialized {
|
||||
return Serializable.prototype.toJSON.call(this);
|
||||
}
|
||||
|
||||
static fromMethods(methods: CallbackHandlerMethods) {
|
||||
class Handler extends BaseCallbackHandler {
|
||||
name = uuid.v4();
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
RunInputs,
|
||||
RunOutputs,
|
||||
} from "../../schema/index.js";
|
||||
import { BaseCallbackHandler } from "../base.js";
|
||||
import { BaseCallbackHandler, BaseCallbackHandlerInput } from "../base.js";
|
||||
|
||||
export type RunType = "llm" | "chain" | "tool";
|
||||
|
||||
@@ -40,8 +40,8 @@ export interface AgentRun extends Run {
|
||||
export abstract class BaseTracer extends BaseCallbackHandler {
|
||||
protected runMap: Map<string, Run> = new Map();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
constructor(_fields?: BaseCallbackHandlerInput) {
|
||||
super(...arguments);
|
||||
}
|
||||
|
||||
copy(): this {
|
||||
|
||||
@@ -5,8 +5,9 @@ import {
|
||||
getRuntimeEnvironment,
|
||||
} from "../../util/env.js";
|
||||
import { BaseTracer } from "./tracer.js";
|
||||
import { BaseCallbackHandlerInput } from "../base.js";
|
||||
|
||||
export interface LangChainTracerFields {
|
||||
export interface LangChainTracerFields extends BaseCallbackHandlerInput {
|
||||
exampleId?: string;
|
||||
sessionName?: string;
|
||||
client?: LangChainPlusClient;
|
||||
@@ -24,8 +25,9 @@ export class LangChainTracer
|
||||
|
||||
client: LangChainPlusClient;
|
||||
|
||||
constructor({ exampleId, sessionName, client }: LangChainTracerFields = {}) {
|
||||
super();
|
||||
constructor(fields: LangChainTracerFields = {}) {
|
||||
super(fields);
|
||||
const { exampleId, sessionName, client } = fields;
|
||||
|
||||
this.sessionName =
|
||||
sessionName ?? getEnvironmentVariable("LANGCHAIN_SESSION");
|
||||
|
||||
@@ -26,6 +26,14 @@ export interface ChainInputs extends BaseLangChainParams {
|
||||
export abstract class BaseChain extends BaseLangChain implements ChainInputs {
|
||||
declare memory?: BaseMemory;
|
||||
|
||||
get lc_namespace(): ["langchain", "chains"] {
|
||||
return ["langchain", "chains"];
|
||||
}
|
||||
|
||||
get lc_name(): string {
|
||||
return this._chainType();
|
||||
}
|
||||
|
||||
constructor(
|
||||
fields?: BaseMemory | ChainInputs,
|
||||
/** @deprecated */
|
||||
|
||||
@@ -41,6 +41,12 @@ export abstract class BaseChatModel extends BaseLanguageModel {
|
||||
|
||||
declare ParsedCallOptions: Omit<this["CallOptions"], "timeout">;
|
||||
|
||||
lc_namespace = ["langchain", "chat_models"];
|
||||
|
||||
get lc_name(): string {
|
||||
return this._llmType();
|
||||
}
|
||||
|
||||
constructor(fields: BaseChatModelParams) {
|
||||
super(fields);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ export abstract class BaseLLM extends BaseLanguageModel {
|
||||
|
||||
declare ParsedCallOptions: Omit<this["CallOptions"], "timeout">;
|
||||
|
||||
lc_namespace = ["langchain", "llms"];
|
||||
|
||||
get lc_name(): string {
|
||||
return this._llmType();
|
||||
}
|
||||
|
||||
cache?: BaseCache;
|
||||
|
||||
constructor({ cache, concurrency, ...rest }: BaseLLMParams) {
|
||||
|
||||
@@ -60,7 +60,7 @@ export class HuggingFaceInference extends LLM implements HFInput {
|
||||
}
|
||||
|
||||
_llmType() {
|
||||
return "huggingface_hub";
|
||||
return "hf";
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
|
||||
@@ -379,7 +379,7 @@ export class OpenAIChat
|
||||
}
|
||||
|
||||
_llmType() {
|
||||
return "openai";
|
||||
return "openai-chat";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.
|
||||
|
||||
export const optionalImportEntrypoints = [
|
||||
"langchain/agents/load",
|
||||
"langchain/tools/aws_lambda",
|
||||
"langchain/tools/calculator",
|
||||
"langchain/tools/webbrowser",
|
||||
"langchain/chains/load",
|
||||
"langchain/chains/query_constructor",
|
||||
"langchain/chains/query_constructor/ir",
|
||||
"langchain/embeddings/cohere",
|
||||
"langchain/embeddings/tensorflow",
|
||||
"langchain/embeddings/hf",
|
||||
"langchain/embeddings/googlevertexai",
|
||||
"langchain/llms/load",
|
||||
"langchain/llms/cohere",
|
||||
"langchain/llms/hf",
|
||||
"langchain/llms/replicate",
|
||||
"langchain/llms/googlevertexai",
|
||||
"langchain/llms/sagemaker_endpoint",
|
||||
"langchain/prompts/load",
|
||||
"langchain/vectorstores/chroma",
|
||||
"langchain/vectorstores/hnswlib",
|
||||
"langchain/vectorstores/faiss",
|
||||
"langchain/vectorstores/weaviate",
|
||||
"langchain/vectorstores/mongo",
|
||||
"langchain/vectorstores/pinecone",
|
||||
"langchain/vectorstores/qdrant",
|
||||
"langchain/vectorstores/supabase",
|
||||
"langchain/vectorstores/opensearch",
|
||||
"langchain/vectorstores/milvus",
|
||||
"langchain/vectorstores/myscale",
|
||||
"langchain/vectorstores/redis",
|
||||
"langchain/document_loaders/web/apify_dataset",
|
||||
"langchain/document_loaders/web/cheerio",
|
||||
"langchain/document_loaders/web/puppeteer",
|
||||
"langchain/document_loaders/web/playwright",
|
||||
"langchain/document_loaders/web/college_confidential",
|
||||
"langchain/document_loaders/web/gitbook",
|
||||
"langchain/document_loaders/web/hn",
|
||||
"langchain/document_loaders/web/imsdb",
|
||||
"langchain/document_loaders/web/github",
|
||||
"langchain/document_loaders/web/s3",
|
||||
"langchain/document_loaders/web/confluence",
|
||||
"langchain/document_loaders/fs/directory",
|
||||
"langchain/document_loaders/fs/buffer",
|
||||
"langchain/document_loaders/fs/text",
|
||||
"langchain/document_loaders/fs/json",
|
||||
"langchain/document_loaders/fs/srt",
|
||||
"langchain/document_loaders/fs/pdf",
|
||||
"langchain/document_loaders/fs/docx",
|
||||
"langchain/document_loaders/fs/epub",
|
||||
"langchain/document_loaders/fs/csv",
|
||||
"langchain/document_loaders/fs/notion",
|
||||
"langchain/document_loaders/fs/unstructured",
|
||||
"langchain/chat_models/googlevertexai",
|
||||
"langchain/sql_db",
|
||||
"langchain/output_parsers/expression",
|
||||
"langchain/retrievers/supabase",
|
||||
"langchain/retrievers/metal",
|
||||
"langchain/retrievers/self_query",
|
||||
"langchain/cache/redis",
|
||||
"langchain/stores/file/node",
|
||||
"langchain/stores/message/dynamodb",
|
||||
"langchain/stores/message/redis",
|
||||
"langchain/stores/message/upstash_redis"
|
||||
]
|
||||
@@ -0,0 +1,41 @@
|
||||
// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.
|
||||
|
||||
export * as agents from "../agents/index.js";
|
||||
export * as base_language from "../base_language/index.js";
|
||||
export * as tools from "../tools/index.js";
|
||||
export * as chains from "../chains/index.js";
|
||||
export * as embeddings__base from "../embeddings/base.js";
|
||||
export * as embeddings__fake from "../embeddings/fake.js";
|
||||
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 prompts from "../prompts/index.js";
|
||||
export * as vectorstores__base from "../vectorstores/base.js";
|
||||
export * as vectorstores__memory from "../vectorstores/memory.js";
|
||||
export * as vectorstores__prisma from "../vectorstores/prisma.js";
|
||||
export * as text_splitter from "../text_splitter.js";
|
||||
export * as memory from "../memory/index.js";
|
||||
export * as document from "../document.js";
|
||||
export * as docstore from "../docstore/index.js";
|
||||
export * as document_loaders__base from "../document_loaders/base.js";
|
||||
export * as chat_models__base from "../chat_models/base.js";
|
||||
export * as chat_models__openai from "../chat_models/openai.js";
|
||||
export * as chat_models__anthropic from "../chat_models/anthropic.js";
|
||||
export * as schema from "../schema/index.js";
|
||||
export * as schema__output_parser from "../schema/output_parser.js";
|
||||
export * as schema__query_constructor from "../schema/query_constructor.js";
|
||||
export * as callbacks from "../callbacks/index.js";
|
||||
export * as output_parsers from "../output_parsers/index.js";
|
||||
export * as retrievers__remote from "../retrievers/remote/index.js";
|
||||
export * as retrievers__databerry from "../retrievers/databerry.js";
|
||||
export * as retrievers__contextual_compression from "../retrievers/contextual_compression.js";
|
||||
export * as retrievers__document_compressors from "../retrievers/document_compressors/index.js";
|
||||
export * as retrievers__time_weighted from "../retrievers/time_weighted.js";
|
||||
export * as retrievers__document_compressors__chain_extract from "../retrievers/document_compressors/chain_extract.js";
|
||||
export * as retrievers__hyde from "../retrievers/hyde.js";
|
||||
export * as cache from "../cache/index.js";
|
||||
export * as stores__file__in_memory from "../stores/file/in_memory.js";
|
||||
export * as experimental__autogpt from "../experimental/autogpt/index.js";
|
||||
export * as experimental__babyagi from "../experimental/babyagi/index.js";
|
||||
export * as experimental__plan_and_execute from "../experimental/plan_and_execute/index.js";
|
||||
export * as client from "../client/index.js";
|
||||
Vendored
+193
@@ -0,0 +1,193 @@
|
||||
// Auto-generated by `scripts/create-entrypoints.js`. Do not edit manually.
|
||||
|
||||
export interface OptionalImportMap {
|
||||
"langchain/agents/load"?:
|
||||
| typeof import("../agents/load.js")
|
||||
| Promise<typeof import("../agents/load.js")>;
|
||||
"langchain/tools/aws_lambda"?:
|
||||
| typeof import("../tools/aws_lambda.js")
|
||||
| Promise<typeof import("../tools/aws_lambda.js")>;
|
||||
"langchain/tools/calculator"?:
|
||||
| typeof import("../tools/calculator.js")
|
||||
| Promise<typeof import("../tools/calculator.js")>;
|
||||
"langchain/tools/webbrowser"?:
|
||||
| typeof import("../tools/webbrowser.js")
|
||||
| Promise<typeof import("../tools/webbrowser.js")>;
|
||||
"langchain/chains/load"?:
|
||||
| typeof import("../chains/load.js")
|
||||
| Promise<typeof import("../chains/load.js")>;
|
||||
"langchain/chains/query_constructor"?:
|
||||
| typeof import("../chains/query_constructor.js")
|
||||
| Promise<typeof import("../chains/query_constructor.js")>;
|
||||
"langchain/chains/query_constructor/ir"?:
|
||||
| typeof import("../chains/query_constructor/ir.js")
|
||||
| Promise<typeof import("../chains/query_constructor/ir.js")>;
|
||||
"langchain/embeddings/cohere"?:
|
||||
| typeof import("../embeddings/cohere.js")
|
||||
| Promise<typeof import("../embeddings/cohere.js")>;
|
||||
"langchain/embeddings/tensorflow"?:
|
||||
| typeof import("../embeddings/tensorflow.js")
|
||||
| Promise<typeof import("../embeddings/tensorflow.js")>;
|
||||
"langchain/embeddings/hf"?:
|
||||
| typeof import("../embeddings/hf.js")
|
||||
| Promise<typeof import("../embeddings/hf.js")>;
|
||||
"langchain/embeddings/googlevertexai"?:
|
||||
| typeof import("../embeddings/googlevertexai.js")
|
||||
| Promise<typeof import("../embeddings/googlevertexai.js")>;
|
||||
"langchain/llms/load"?:
|
||||
| typeof import("../llms/load.js")
|
||||
| Promise<typeof import("../llms/load.js")>;
|
||||
"langchain/llms/cohere"?:
|
||||
| typeof import("../llms/cohere.js")
|
||||
| Promise<typeof import("../llms/cohere.js")>;
|
||||
"langchain/llms/hf"?:
|
||||
| typeof import("../llms/hf.js")
|
||||
| Promise<typeof import("../llms/hf.js")>;
|
||||
"langchain/llms/replicate"?:
|
||||
| typeof import("../llms/replicate.js")
|
||||
| Promise<typeof import("../llms/replicate.js")>;
|
||||
"langchain/llms/googlevertexai"?:
|
||||
| typeof import("../llms/googlevertexai.js")
|
||||
| Promise<typeof import("../llms/googlevertexai.js")>;
|
||||
"langchain/llms/sagemaker_endpoint"?:
|
||||
| typeof import("../llms/sagemaker_endpoint.js")
|
||||
| Promise<typeof import("../llms/sagemaker_endpoint.js")>;
|
||||
"langchain/prompts/load"?:
|
||||
| typeof import("../prompts/load.js")
|
||||
| Promise<typeof import("../prompts/load.js")>;
|
||||
"langchain/vectorstores/chroma"?:
|
||||
| typeof import("../vectorstores/chroma.js")
|
||||
| Promise<typeof import("../vectorstores/chroma.js")>;
|
||||
"langchain/vectorstores/hnswlib"?:
|
||||
| typeof import("../vectorstores/hnswlib.js")
|
||||
| Promise<typeof import("../vectorstores/hnswlib.js")>;
|
||||
"langchain/vectorstores/faiss"?:
|
||||
| typeof import("../vectorstores/faiss.js")
|
||||
| Promise<typeof import("../vectorstores/faiss.js")>;
|
||||
"langchain/vectorstores/weaviate"?:
|
||||
| typeof import("../vectorstores/weaviate.js")
|
||||
| Promise<typeof import("../vectorstores/weaviate.js")>;
|
||||
"langchain/vectorstores/mongo"?:
|
||||
| typeof import("../vectorstores/mongo.js")
|
||||
| Promise<typeof import("../vectorstores/mongo.js")>;
|
||||
"langchain/vectorstores/pinecone"?:
|
||||
| typeof import("../vectorstores/pinecone.js")
|
||||
| Promise<typeof import("../vectorstores/pinecone.js")>;
|
||||
"langchain/vectorstores/qdrant"?:
|
||||
| typeof import("../vectorstores/qdrant.js")
|
||||
| Promise<typeof import("../vectorstores/qdrant.js")>;
|
||||
"langchain/vectorstores/supabase"?:
|
||||
| typeof import("../vectorstores/supabase.js")
|
||||
| Promise<typeof import("../vectorstores/supabase.js")>;
|
||||
"langchain/vectorstores/opensearch"?:
|
||||
| typeof import("../vectorstores/opensearch.js")
|
||||
| Promise<typeof import("../vectorstores/opensearch.js")>;
|
||||
"langchain/vectorstores/milvus"?:
|
||||
| typeof import("../vectorstores/milvus.js")
|
||||
| Promise<typeof import("../vectorstores/milvus.js")>;
|
||||
"langchain/vectorstores/myscale"?:
|
||||
| typeof import("../vectorstores/myscale.js")
|
||||
| Promise<typeof import("../vectorstores/myscale.js")>;
|
||||
"langchain/vectorstores/redis"?:
|
||||
| typeof import("../vectorstores/redis.js")
|
||||
| Promise<typeof import("../vectorstores/redis.js")>;
|
||||
"langchain/document_loaders/web/apify_dataset"?:
|
||||
| typeof import("../document_loaders/web/apify_dataset.js")
|
||||
| Promise<typeof import("../document_loaders/web/apify_dataset.js")>;
|
||||
"langchain/document_loaders/web/cheerio"?:
|
||||
| typeof import("../document_loaders/web/cheerio.js")
|
||||
| Promise<typeof import("../document_loaders/web/cheerio.js")>;
|
||||
"langchain/document_loaders/web/puppeteer"?:
|
||||
| typeof import("../document_loaders/web/puppeteer.js")
|
||||
| Promise<typeof import("../document_loaders/web/puppeteer.js")>;
|
||||
"langchain/document_loaders/web/playwright"?:
|
||||
| typeof import("../document_loaders/web/playwright.js")
|
||||
| Promise<typeof import("../document_loaders/web/playwright.js")>;
|
||||
"langchain/document_loaders/web/college_confidential"?:
|
||||
| typeof import("../document_loaders/web/college_confidential.js")
|
||||
| Promise<typeof import("../document_loaders/web/college_confidential.js")>;
|
||||
"langchain/document_loaders/web/gitbook"?:
|
||||
| typeof import("../document_loaders/web/gitbook.js")
|
||||
| Promise<typeof import("../document_loaders/web/gitbook.js")>;
|
||||
"langchain/document_loaders/web/hn"?:
|
||||
| typeof import("../document_loaders/web/hn.js")
|
||||
| Promise<typeof import("../document_loaders/web/hn.js")>;
|
||||
"langchain/document_loaders/web/imsdb"?:
|
||||
| typeof import("../document_loaders/web/imsdb.js")
|
||||
| Promise<typeof import("../document_loaders/web/imsdb.js")>;
|
||||
"langchain/document_loaders/web/github"?:
|
||||
| typeof import("../document_loaders/web/github.js")
|
||||
| Promise<typeof import("../document_loaders/web/github.js")>;
|
||||
"langchain/document_loaders/web/s3"?:
|
||||
| typeof import("../document_loaders/web/s3.js")
|
||||
| Promise<typeof import("../document_loaders/web/s3.js")>;
|
||||
"langchain/document_loaders/web/confluence"?:
|
||||
| typeof import("../document_loaders/web/confluence.js")
|
||||
| Promise<typeof import("../document_loaders/web/confluence.js")>;
|
||||
"langchain/document_loaders/fs/directory"?:
|
||||
| typeof import("../document_loaders/fs/directory.js")
|
||||
| Promise<typeof import("../document_loaders/fs/directory.js")>;
|
||||
"langchain/document_loaders/fs/buffer"?:
|
||||
| typeof import("../document_loaders/fs/buffer.js")
|
||||
| Promise<typeof import("../document_loaders/fs/buffer.js")>;
|
||||
"langchain/document_loaders/fs/text"?:
|
||||
| typeof import("../document_loaders/fs/text.js")
|
||||
| Promise<typeof import("../document_loaders/fs/text.js")>;
|
||||
"langchain/document_loaders/fs/json"?:
|
||||
| typeof import("../document_loaders/fs/json.js")
|
||||
| Promise<typeof import("../document_loaders/fs/json.js")>;
|
||||
"langchain/document_loaders/fs/srt"?:
|
||||
| typeof import("../document_loaders/fs/srt.js")
|
||||
| Promise<typeof import("../document_loaders/fs/srt.js")>;
|
||||
"langchain/document_loaders/fs/pdf"?:
|
||||
| typeof import("../document_loaders/fs/pdf.js")
|
||||
| Promise<typeof import("../document_loaders/fs/pdf.js")>;
|
||||
"langchain/document_loaders/fs/docx"?:
|
||||
| typeof import("../document_loaders/fs/docx.js")
|
||||
| Promise<typeof import("../document_loaders/fs/docx.js")>;
|
||||
"langchain/document_loaders/fs/epub"?:
|
||||
| typeof import("../document_loaders/fs/epub.js")
|
||||
| Promise<typeof import("../document_loaders/fs/epub.js")>;
|
||||
"langchain/document_loaders/fs/csv"?:
|
||||
| typeof import("../document_loaders/fs/csv.js")
|
||||
| Promise<typeof import("../document_loaders/fs/csv.js")>;
|
||||
"langchain/document_loaders/fs/notion"?:
|
||||
| typeof import("../document_loaders/fs/notion.js")
|
||||
| Promise<typeof import("../document_loaders/fs/notion.js")>;
|
||||
"langchain/document_loaders/fs/unstructured"?:
|
||||
| typeof import("../document_loaders/fs/unstructured.js")
|
||||
| Promise<typeof import("../document_loaders/fs/unstructured.js")>;
|
||||
"langchain/chat_models/googlevertexai"?:
|
||||
| typeof import("../chat_models/googlevertexai.js")
|
||||
| Promise<typeof import("../chat_models/googlevertexai.js")>;
|
||||
"langchain/sql_db"?:
|
||||
| typeof import("../sql_db.js")
|
||||
| Promise<typeof import("../sql_db.js")>;
|
||||
"langchain/output_parsers/expression"?:
|
||||
| typeof import("../output_parsers/expression.js")
|
||||
| Promise<typeof import("../output_parsers/expression.js")>;
|
||||
"langchain/retrievers/supabase"?:
|
||||
| typeof import("../retrievers/supabase.js")
|
||||
| Promise<typeof import("../retrievers/supabase.js")>;
|
||||
"langchain/retrievers/metal"?:
|
||||
| typeof import("../retrievers/metal.js")
|
||||
| Promise<typeof import("../retrievers/metal.js")>;
|
||||
"langchain/retrievers/self_query"?:
|
||||
| typeof import("../retrievers/self_query.js")
|
||||
| Promise<typeof import("../retrievers/self_query.js")>;
|
||||
"langchain/cache/redis"?:
|
||||
| typeof import("../cache/redis.js")
|
||||
| Promise<typeof import("../cache/redis.js")>;
|
||||
"langchain/stores/file/node"?:
|
||||
| typeof import("../stores/file/node.js")
|
||||
| Promise<typeof import("../stores/file/node.js")>;
|
||||
"langchain/stores/message/dynamodb"?:
|
||||
| typeof import("../stores/message/dynamodb.js")
|
||||
| Promise<typeof import("../stores/message/dynamodb.js")>;
|
||||
"langchain/stores/message/redis"?:
|
||||
| typeof import("../stores/message/redis.js")
|
||||
| Promise<typeof import("../stores/message/redis.js")>;
|
||||
"langchain/stores/message/upstash_redis"?:
|
||||
| typeof import("../stores/message/upstash_redis.js")
|
||||
| Promise<typeof import("../stores/message/upstash_redis.js")>;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import { Serialized } from "../schema/load.js";
|
||||
import { optionalImportEntrypoints } from "./import_constants.js";
|
||||
import * as importMap from "./import_map.js";
|
||||
import { OptionalImportMap } from "./import_type.js";
|
||||
|
||||
async function reviver(
|
||||
this: OptionalImportMap,
|
||||
value: unknown
|
||||
): Promise<unknown> {
|
||||
if (
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
!Array.isArray(value) &&
|
||||
"v" in value &&
|
||||
"type" in value &&
|
||||
"identifier" in value &&
|
||||
"arguments" in value &&
|
||||
value.v === 1
|
||||
) {
|
||||
const serialized = value as Serialized;
|
||||
const str = JSON.stringify(serialized);
|
||||
const [name, ...namespaceReverse] = serialized.identifier.slice().reverse();
|
||||
const namespace = namespaceReverse.reverse();
|
||||
|
||||
let module:
|
||||
| (typeof importMap)[keyof typeof importMap]
|
||||
| OptionalImportMap[keyof OptionalImportMap];
|
||||
if (
|
||||
optionalImportEntrypoints.includes(namespace.join("/")) ||
|
||||
namespace.join("/") in this
|
||||
) {
|
||||
if (namespace.join("/") in this) {
|
||||
module = await this[namespace.join("/") as keyof typeof this];
|
||||
} else {
|
||||
throw new Error(
|
||||
`Missing key "${namespace.join("/")}" in 2nd argument to load()`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Currently, we only support langchain imports.
|
||||
if (namespace[0] === "langchain") {
|
||||
namespace.shift();
|
||||
} else {
|
||||
throw new Error(`Invalid namespace: ${str}`);
|
||||
}
|
||||
|
||||
// The root namespace "langchain" is not a valid import.
|
||||
if (namespace.length === 0) {
|
||||
throw new Error(`Invalid namespace: ${str}`);
|
||||
}
|
||||
|
||||
// Find the longest matching namespace.
|
||||
let importMapKey: string;
|
||||
do {
|
||||
importMapKey = namespace.join("__");
|
||||
if (importMapKey in importMap) {
|
||||
break;
|
||||
} else {
|
||||
namespace.pop();
|
||||
}
|
||||
} while (namespace.length > 0);
|
||||
|
||||
// If no matching namespace is found, throw an error.
|
||||
if (importMapKey in importMap) {
|
||||
module = importMap[importMapKey as keyof typeof importMap];
|
||||
} else {
|
||||
throw new Error(`Invalid namespace: ${str}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the builder from the import map.
|
||||
const builder = module[name as keyof typeof module];
|
||||
if (typeof builder !== "function") {
|
||||
throw new Error(`Invalid identifer: ${str}`);
|
||||
}
|
||||
|
||||
// Recurse on the arguments, which may be serialized objects themselves
|
||||
const args = await Promise.all(serialized.arguments.map(reviver, this));
|
||||
|
||||
// Construct the object
|
||||
if (serialized.type === "constructor") {
|
||||
// eslint-disable-next-line new-cap, @typescript-eslint/no-explicit-any
|
||||
const instance = new (builder as any)(...args);
|
||||
const fields = serialized.fields
|
||||
? await reviver.call(this, serialized.fields)
|
||||
: undefined;
|
||||
Object.assign(instance, fields);
|
||||
return instance;
|
||||
} else if (serialized.type === "function") {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (builder as any)(...args);
|
||||
} else {
|
||||
throw new Error(`Invalid type: ${str}`);
|
||||
}
|
||||
} else if (typeof value === "object" && value !== null) {
|
||||
if (Array.isArray(value)) {
|
||||
return Promise.all(value.map(reviver, this));
|
||||
} else {
|
||||
return Object.fromEntries(
|
||||
await Promise.all(
|
||||
Object.entries(value).map(async ([key, value]) => [
|
||||
key,
|
||||
await reviver.call(this, value),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function load<T>(
|
||||
text: string,
|
||||
optionalImportsMap: OptionalImportMap = {}
|
||||
): Promise<T> {
|
||||
const json = JSON.parse(text);
|
||||
return reviver.call(optionalImportsMap, json) as Promise<T>;
|
||||
}
|
||||
@@ -0,0 +1,580 @@
|
||||
import { test, expect } from "@jest/globals";
|
||||
|
||||
import { load } from "../index.js";
|
||||
import { OpenAI } from "../../llms/openai.js";
|
||||
import { PromptTemplate } from "../../prompts/prompt.js";
|
||||
import { LLMChain } from "../../chains/llm_chain.js";
|
||||
import { Cohere } from "../../llms/cohere.js";
|
||||
import {
|
||||
HumanMessagePromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
ChatPromptTemplate,
|
||||
} from "../../prompts/chat.js";
|
||||
import { ChatOpenAI } from "../../chat_models/openai.js";
|
||||
import { LangChainTracer } from "../../callbacks/index.js";
|
||||
import {
|
||||
FewShotPromptTemplate,
|
||||
LengthBasedExampleSelector,
|
||||
} from "../../prompts/index.js";
|
||||
|
||||
test("serialize + deserialize llm", async () => {
|
||||
const llm = new OpenAI({ temperature: 0.5, modelName: "davinci" });
|
||||
const str = JSON.stringify(llm, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"llms",
|
||||
"openai",
|
||||
"OpenAI"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"temperature": 0.5,
|
||||
"modelName": "davinci"
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const llm2 = await load<OpenAI>(str);
|
||||
expect(llm2).toBeInstanceOf(OpenAI);
|
||||
expect(JSON.stringify(llm2, null, 2)).toBe(str);
|
||||
});
|
||||
|
||||
test("serialize + deserialize llm with optional deps", async () => {
|
||||
const llm = new Cohere({ temperature: 0.5 });
|
||||
const str = JSON.stringify(llm, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"llms",
|
||||
"cohere",
|
||||
"Cohere"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"temperature": 0.5
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const llm2 = await load<Cohere>(str, {
|
||||
"langchain/llms/cohere": { Cohere },
|
||||
});
|
||||
expect(llm2).toBeInstanceOf(Cohere);
|
||||
expect(JSON.stringify(llm2, null, 2)).toBe(str);
|
||||
const llm3 = await load<Cohere>(str, {
|
||||
"langchain/llms/cohere": import("../../llms/cohere.js"),
|
||||
});
|
||||
expect(llm3).toBeInstanceOf(Cohere);
|
||||
expect(JSON.stringify(llm3, null, 2)).toBe(str);
|
||||
});
|
||||
|
||||
test("serialize + deserialize llm chain string prompt", async () => {
|
||||
const llm = new OpenAI({
|
||||
temperature: 0.5,
|
||||
modelName: "davinci",
|
||||
verbose: true,
|
||||
callbacks: [
|
||||
new LangChainTracer(),
|
||||
// This custom handler is not serialized
|
||||
{
|
||||
handleLLMEnd(output) {
|
||||
console.log(output);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const prompt = PromptTemplate.fromTemplate("Hello, {name}!");
|
||||
const chain = new LLMChain({ llm, prompt });
|
||||
const str = JSON.stringify(chain, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"chains",
|
||||
"llm_chain",
|
||||
"LLMChain"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"llm": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"llms",
|
||||
"openai",
|
||||
"OpenAI"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"callbacks": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"callbacks",
|
||||
"langchain_tracer",
|
||||
"LangChainTracer"
|
||||
],
|
||||
"arguments": [
|
||||
{}
|
||||
]
|
||||
},
|
||||
{}
|
||||
],
|
||||
"temperature": 0.5,
|
||||
"modelName": "davinci",
|
||||
"verbose": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"prompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"name"
|
||||
],
|
||||
"templateFormat": "f-string",
|
||||
"template": "Hello, {name}!"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const chain2 = await load<LLMChain>(str);
|
||||
expect(chain2).toBeInstanceOf(LLMChain);
|
||||
expect(JSON.stringify(chain2, null, 2)).toBe(str);
|
||||
});
|
||||
|
||||
test("serialize + deserialize llm chain chat prompt", async () => {
|
||||
const llm = new ChatOpenAI({
|
||||
temperature: 0.5,
|
||||
modelName: "gpt-4",
|
||||
streaming: true,
|
||||
prefixMessages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You're a nice assistant",
|
||||
},
|
||||
],
|
||||
});
|
||||
const prompt = ChatPromptTemplate.fromPromptMessages([
|
||||
SystemMessagePromptTemplate.fromTemplate("You are talking to {name}."),
|
||||
HumanMessagePromptTemplate.fromTemplate("Hello, nice model."),
|
||||
]);
|
||||
const chain = new LLMChain({ llm, prompt });
|
||||
const str = JSON.stringify(chain, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"chains",
|
||||
"llm_chain",
|
||||
"LLMChain"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"llm": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"chat_models",
|
||||
"openai",
|
||||
"ChatOpenAI"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"temperature": 0.5,
|
||||
"modelName": "gpt-4",
|
||||
"streaming": true,
|
||||
"prefixMessages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You're a nice assistant"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"prompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"chat",
|
||||
"ChatPromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"name"
|
||||
],
|
||||
"promptMessages": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"chat",
|
||||
"SystemMessagePromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"name"
|
||||
],
|
||||
"templateFormat": "f-string",
|
||||
"template": "You are talking to {name}."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"chat",
|
||||
"HumanMessagePromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [],
|
||||
"templateFormat": "f-string",
|
||||
"template": "Hello, nice model."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"partialVariables": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const chain2 = await load<LLMChain>(str);
|
||||
expect(chain2).toBeInstanceOf(LLMChain);
|
||||
expect(JSON.stringify(chain2, null, 2)).toBe(str);
|
||||
});
|
||||
|
||||
test("serialize + deserialize llm chain few shot prompt w/ examples", async () => {
|
||||
const llm = new OpenAI({
|
||||
temperature: 0.5,
|
||||
modelName: "davinci",
|
||||
callbacks: [new LangChainTracer()],
|
||||
});
|
||||
const prompt = new FewShotPromptTemplate({
|
||||
examples: [{ yo: "1" }, { yo: "2" }],
|
||||
prefix: "You are a nice assistant",
|
||||
examplePrompt: PromptTemplate.fromTemplate("An example about {yo}"),
|
||||
suffix: "My name is {name}",
|
||||
inputVariables: ["yo", "name"],
|
||||
});
|
||||
const chain = new LLMChain({ llm, prompt });
|
||||
const str = JSON.stringify(chain, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"chains",
|
||||
"llm_chain",
|
||||
"LLMChain"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"llm": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"llms",
|
||||
"openai",
|
||||
"OpenAI"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"callbacks": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"callbacks",
|
||||
"langchain_tracer",
|
||||
"LangChainTracer"
|
||||
],
|
||||
"arguments": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
],
|
||||
"temperature": 0.5,
|
||||
"modelName": "davinci"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"few_shot",
|
||||
"FewShotPromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"examples": [
|
||||
{
|
||||
"yo": "1"
|
||||
},
|
||||
{
|
||||
"yo": "2"
|
||||
}
|
||||
],
|
||||
"prefix": "You are a nice assistant",
|
||||
"examplePrompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"yo"
|
||||
],
|
||||
"templateFormat": "f-string",
|
||||
"template": "An example about {yo}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"suffix": "My name is {name}",
|
||||
"inputVariables": [
|
||||
"yo",
|
||||
"name"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const chain2 = await load<LLMChain>(str);
|
||||
expect(chain2).toBeInstanceOf(LLMChain);
|
||||
expect(JSON.stringify(chain2, null, 2)).toBe(str);
|
||||
});
|
||||
|
||||
test("serialize + deserialize llm chain few shot prompt w/ selector", async () => {
|
||||
const llm = new OpenAI({
|
||||
temperature: 0.5,
|
||||
modelName: "davinci",
|
||||
callbacks: [new LangChainTracer()],
|
||||
});
|
||||
const examplePrompt = PromptTemplate.fromTemplate("An example about {yo}");
|
||||
const prompt = new FewShotPromptTemplate({
|
||||
exampleSelector: await LengthBasedExampleSelector.fromExamples(
|
||||
[{ yo: "1" }, { yo: "2" }],
|
||||
{ examplePrompt }
|
||||
),
|
||||
prefix: "You are a nice assistant",
|
||||
examplePrompt,
|
||||
suffix: "My name is {name}",
|
||||
inputVariables: ["yo", "name"],
|
||||
});
|
||||
const chain = new LLMChain({ llm, prompt });
|
||||
const str = JSON.stringify(chain, null, 2);
|
||||
expect(str).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"chains",
|
||||
"llm_chain",
|
||||
"LLMChain"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"llm": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"llms",
|
||||
"openai",
|
||||
"OpenAI"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"callbacks": [
|
||||
{
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"callbacks",
|
||||
"langchain_tracer",
|
||||
"LangChainTracer"
|
||||
],
|
||||
"arguments": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
],
|
||||
"temperature": 0.5,
|
||||
"modelName": "davinci"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"few_shot",
|
||||
"FewShotPromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"exampleSelector": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"selectors",
|
||||
"LengthBasedExampleSelector"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"examplePrompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"yo"
|
||||
],
|
||||
"templateFormat": "f-string",
|
||||
"template": "An example about {yo}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"fields": {
|
||||
"examples": [
|
||||
{
|
||||
"yo": "1"
|
||||
},
|
||||
{
|
||||
"yo": "2"
|
||||
}
|
||||
],
|
||||
"exampleTextLengths": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
"prefix": "You are a nice assistant",
|
||||
"examplePrompt": {
|
||||
"v": 1,
|
||||
"type": "constructor",
|
||||
"identifier": [
|
||||
"langchain",
|
||||
"prompts",
|
||||
"prompt",
|
||||
"PromptTemplate"
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"inputVariables": [
|
||||
"yo"
|
||||
],
|
||||
"templateFormat": "f-string",
|
||||
"template": "An example about {yo}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"suffix": "My name is {name}",
|
||||
"inputVariables": [
|
||||
"yo",
|
||||
"name"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}"
|
||||
`);
|
||||
const chain2 = await load<LLMChain>(str);
|
||||
expect(chain2).toBeInstanceOf(LLMChain);
|
||||
expect(JSON.stringify(chain2, null, 2)).toBe(str);
|
||||
});
|
||||
@@ -6,13 +6,18 @@ import {
|
||||
PartialValues,
|
||||
} from "../schema/index.js";
|
||||
import { BaseOutputParser } from "../schema/output_parser.js";
|
||||
import { Serializable } from "../schema/load.js";
|
||||
import { SerializedBasePromptTemplate } from "./serde.js";
|
||||
|
||||
export class StringPromptValue extends BasePromptValue {
|
||||
lc_namespace = ["langchain", "prompts"];
|
||||
|
||||
lc_name = "base";
|
||||
|
||||
value: string;
|
||||
|
||||
constructor(value: string) {
|
||||
super();
|
||||
super(...arguments);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -47,9 +52,18 @@ export interface BasePromptTemplateInput {
|
||||
* Base class for prompt templates. Exposes a format method that returns a
|
||||
* string prompt given a set of input values.
|
||||
*/
|
||||
export abstract class BasePromptTemplate implements BasePromptTemplateInput {
|
||||
export abstract class BasePromptTemplate
|
||||
extends Serializable
|
||||
implements BasePromptTemplateInput
|
||||
{
|
||||
declare PromptValueReturnType: BasePromptValue;
|
||||
|
||||
lc_namespace = ["langchain", "prompts"];
|
||||
|
||||
get lc_name(): string {
|
||||
return this._getPromptType();
|
||||
}
|
||||
|
||||
inputVariables: string[];
|
||||
|
||||
outputParser?: BaseOutputParser;
|
||||
@@ -57,6 +71,7 @@ export abstract class BasePromptTemplate implements BasePromptTemplateInput {
|
||||
partialVariables?: InputValues;
|
||||
|
||||
constructor(input: BasePromptTemplateInput) {
|
||||
super(input);
|
||||
const { inputVariables } = input;
|
||||
if (inputVariables.includes("stop")) {
|
||||
throw new Error(
|
||||
@@ -151,7 +166,7 @@ export abstract class BasePromptTemplate implements BasePromptTemplateInput {
|
||||
}
|
||||
|
||||
export abstract class BaseStringPromptTemplate extends BasePromptTemplate {
|
||||
async formatPromptValue(values: InputValues): Promise<BasePromptValue> {
|
||||
async formatPromptValue(values: InputValues): Promise<StringPromptValue> {
|
||||
const formattedPrompt = await this.format(values);
|
||||
return new StringPromptValue(formattedPrompt);
|
||||
}
|
||||
@@ -160,7 +175,9 @@ export abstract class BaseStringPromptTemplate extends BasePromptTemplate {
|
||||
/**
|
||||
* Base class for example selectors.
|
||||
*/
|
||||
export abstract class BaseExampleSelector {
|
||||
export abstract class BaseExampleSelector extends Serializable {
|
||||
lc_namespace = ["langchain", "prompts"];
|
||||
|
||||
abstract addExample(example: Example): Promise<void | string>;
|
||||
|
||||
abstract selectExamples(input_variables: Example): Promise<Example[]>;
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
PartialValues,
|
||||
SystemChatMessage,
|
||||
} from "../schema/index.js";
|
||||
import { Serializable } from "../schema/load.js";
|
||||
import {
|
||||
BasePromptTemplate,
|
||||
BasePromptTemplateInput,
|
||||
@@ -19,7 +20,11 @@ import {
|
||||
SerializedMessagePromptTemplate,
|
||||
} from "./serde.js";
|
||||
|
||||
export abstract class BaseMessagePromptTemplate {
|
||||
export abstract class BaseMessagePromptTemplate extends Serializable {
|
||||
lc_namespace = ["langchain", "prompts"];
|
||||
|
||||
lc_name = "chat";
|
||||
|
||||
abstract inputVariables: string[];
|
||||
|
||||
abstract formatMessages(values: InputValues): Promise<BaseChatMessage[]>;
|
||||
@@ -33,10 +38,14 @@ export abstract class BaseMessagePromptTemplate {
|
||||
}
|
||||
|
||||
export class ChatPromptValue extends BasePromptValue {
|
||||
lc_namespace = ["langchain", "prompts"];
|
||||
|
||||
lc_name = "chat";
|
||||
|
||||
messages: BaseChatMessage[];
|
||||
|
||||
constructor(messages: BaseChatMessage[]) {
|
||||
super();
|
||||
super(...arguments);
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
@@ -53,7 +62,7 @@ export class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
||||
variableName: string;
|
||||
|
||||
constructor(variableName: string) {
|
||||
super();
|
||||
super(...arguments);
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
@@ -69,8 +78,8 @@ export class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
||||
export abstract class BaseMessageStringPromptTemplate extends BaseMessagePromptTemplate {
|
||||
prompt: BaseStringPromptTemplate;
|
||||
|
||||
protected constructor(prompt: BaseStringPromptTemplate) {
|
||||
super();
|
||||
protected constructor(prompt: BaseStringPromptTemplate, _role?: string) {
|
||||
super(...arguments);
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
@@ -112,7 +121,7 @@ export class ChatMessagePromptTemplate extends BaseMessageStringPromptTemplate {
|
||||
}
|
||||
|
||||
constructor(prompt: BaseStringPromptTemplate, role: string) {
|
||||
super(prompt);
|
||||
super(prompt, role);
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Example } from "../../schema/index.js";
|
||||
import type { BaseExampleSelector } from "../base.js";
|
||||
import { BaseExampleSelector } from "../base.js";
|
||||
import { PromptTemplate } from "../prompt.js";
|
||||
|
||||
function getLengthBased(text: string): number {
|
||||
@@ -12,7 +12,11 @@ export interface LengthBasedExampleSelectorInput {
|
||||
getTextLength?: (text: string) => number;
|
||||
}
|
||||
|
||||
export class LengthBasedExampleSelector implements BaseExampleSelector {
|
||||
export class LengthBasedExampleSelector extends BaseExampleSelector {
|
||||
lc_name = "selectors";
|
||||
|
||||
lc_fields = ["examples", "exampleTextLengths"];
|
||||
|
||||
protected examples: Example[] = [];
|
||||
|
||||
examplePrompt!: PromptTemplate;
|
||||
@@ -24,6 +28,7 @@ export class LengthBasedExampleSelector implements BaseExampleSelector {
|
||||
exampleTextLengths: number[] = [];
|
||||
|
||||
constructor(data: LengthBasedExampleSelectorInput) {
|
||||
super(data);
|
||||
this.examplePrompt = data.examplePrompt;
|
||||
this.maxLength = data.maxLength ?? 2048;
|
||||
this.getTextLength = data.getTextLength ?? getLengthBased;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Embeddings } from "../../embeddings/base.js";
|
||||
import { VectorStore } from "../../vectorstores/base.js";
|
||||
import { Document } from "../../document.js";
|
||||
import { Example } from "../../schema/index.js";
|
||||
import type { BaseExampleSelector } from "../base.js";
|
||||
import { BaseExampleSelector } from "../base.js";
|
||||
|
||||
function sortedValues<T>(values: Record<string, T>): T[] {
|
||||
return Object.keys(values)
|
||||
@@ -17,7 +17,9 @@ export interface SemanticSimilarityExampleSelectorInput {
|
||||
inputKeys?: string[];
|
||||
}
|
||||
|
||||
export class SemanticSimilarityExampleSelector implements BaseExampleSelector {
|
||||
export class SemanticSimilarityExampleSelector extends BaseExampleSelector {
|
||||
lc_name = "selectors";
|
||||
|
||||
vectorStore: VectorStore;
|
||||
|
||||
k = 4;
|
||||
@@ -27,6 +29,7 @@ export class SemanticSimilarityExampleSelector implements BaseExampleSelector {
|
||||
inputKeys?: string[];
|
||||
|
||||
constructor(data: SemanticSimilarityExampleSelectorInput) {
|
||||
super(data);
|
||||
this.vectorStore = data.vectorStore;
|
||||
this.k = data.k ?? 4;
|
||||
this.exampleKeys = data.exampleKeys;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Document } from "../document.js";
|
||||
import { Serializable } from "./load.js";
|
||||
|
||||
export const RUN_KEY = "__run";
|
||||
|
||||
@@ -132,7 +133,7 @@ export interface ChatResult {
|
||||
/**
|
||||
* Base PromptValue class. All prompt values should extend this class.
|
||||
*/
|
||||
export abstract class BasePromptValue {
|
||||
export abstract class BasePromptValue extends Serializable {
|
||||
abstract toString(): string;
|
||||
|
||||
abstract toChatMessages(): BaseChatMessage[];
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
export interface SerializedFields {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface Serialized {
|
||||
v: number;
|
||||
type: "constructor" | "function";
|
||||
identifier: string[];
|
||||
arguments: unknown[];
|
||||
fields?: SerializedFields;
|
||||
}
|
||||
|
||||
export abstract class Serializable {
|
||||
abstract lc_namespace: string[];
|
||||
|
||||
abstract lc_name: string;
|
||||
|
||||
lc_arguments: unknown[];
|
||||
|
||||
lc_fields?: string[];
|
||||
|
||||
constructor(...args: unknown[]) {
|
||||
this.lc_arguments = args;
|
||||
}
|
||||
|
||||
toJSON(): Serialized {
|
||||
return {
|
||||
v: 1,
|
||||
type: "constructor",
|
||||
identifier: [...this.lc_namespace, this.lc_name, this.constructor.name],
|
||||
arguments: this.lc_arguments,
|
||||
fields: this.lc_fields?.reduce((acc, key) => {
|
||||
acc[key] = this[key as keyof this];
|
||||
return acc;
|
||||
}, {} as SerializedFields),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,12 @@ export abstract class StructuredTool<
|
||||
> extends BaseLangChain {
|
||||
abstract schema: T | z.ZodEffects<T>;
|
||||
|
||||
lc_namespace = ["langchain", "tools"];
|
||||
|
||||
get lc_name(): string {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
constructor(fields?: ToolParams) {
|
||||
super(fields ?? {});
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
],
|
||||
"typedocOptions": {
|
||||
"entryPoints": [
|
||||
"src/load/index.ts",
|
||||
"src/agents/index.ts",
|
||||
"src/agents/load.ts",
|
||||
"src/base_language/index.ts",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "langchain/load";
|
||||
export * from "langchain/agents";
|
||||
export * from "langchain/base_language";
|
||||
export * from "langchain/tools";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const load = require("langchain/load");
|
||||
const agents = require("langchain/agents");
|
||||
const base_language = require("langchain/base_language");
|
||||
const tools = require("langchain/tools");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "langchain/load";
|
||||
export * from "langchain/agents";
|
||||
export * from "langchain/base_language";
|
||||
export * from "langchain/tools";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as load from "langchain/load";
|
||||
import * as agents from "langchain/agents";
|
||||
import * as base_language from "langchain/base_language";
|
||||
import * as tools from "langchain/tools";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as load from "langchain/load";
|
||||
import * as agents from "langchain/agents";
|
||||
import * as base_language from "langchain/base_language";
|
||||
import * as tools from "langchain/tools";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "langchain/load";
|
||||
export * from "langchain/agents";
|
||||
export * from "langchain/base_language";
|
||||
export * from "langchain/tools";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "langchain/load";
|
||||
export * from "langchain/agents";
|
||||
export * from "langchain/base_language";
|
||||
export * from "langchain/tools";
|
||||
|
||||
Reference in New Issue
Block a user