langchain 0.0.63 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/initialize.cjs +1 -1
- package/dist/agents/initialize.d.ts +1 -1
- package/dist/agents/initialize.js +1 -1
- package/dist/base_language/index.d.ts +4 -1
- package/dist/chains/analyze_documents_chain.cjs +2 -2
- package/dist/chains/analyze_documents_chain.d.ts +2 -1
- package/dist/chains/analyze_documents_chain.js +2 -2
- package/dist/chains/base.cjs +5 -1
- package/dist/chains/base.js +5 -1
- package/dist/chains/chat_vector_db_chain.cjs +3 -3
- package/dist/chains/chat_vector_db_chain.d.ts +2 -1
- package/dist/chains/chat_vector_db_chain.js +3 -3
- package/dist/chains/combine_docs_chain.cjs +8 -8
- package/dist/chains/combine_docs_chain.d.ts +4 -3
- package/dist/chains/combine_docs_chain.js +8 -8
- package/dist/chains/conversational_retrieval_chain.cjs +3 -3
- package/dist/chains/conversational_retrieval_chain.d.ts +2 -1
- package/dist/chains/conversational_retrieval_chain.js +3 -3
- package/dist/chains/index.cjs +4 -3
- package/dist/chains/index.d.ts +2 -2
- package/dist/chains/index.js +1 -1
- package/dist/chains/retrieval_qa.cjs +2 -2
- package/dist/chains/retrieval_qa.d.ts +2 -1
- package/dist/chains/retrieval_qa.js +2 -2
- package/dist/chains/sequential_chain.cjs +262 -0
- package/dist/chains/{simple_sequential_chain.d.ts → sequential_chain.d.ts} +31 -2
- package/dist/chains/sequential_chain.js +257 -0
- package/dist/chains/serde.d.ts +7 -1
- package/dist/chains/sql_db/sql_db_chain.cjs +6 -4
- package/dist/chains/sql_db/sql_db_chain.d.ts +2 -1
- package/dist/chains/sql_db/sql_db_chain.js +6 -4
- package/dist/chains/vector_db_qa.cjs +2 -2
- package/dist/chains/vector_db_qa.d.ts +2 -1
- package/dist/chains/vector_db_qa.js +2 -2
- package/dist/chat_models/base.d.ts +10 -8
- package/dist/chat_models/openai.cjs +9 -5
- package/dist/chat_models/openai.d.ts +14 -5
- package/dist/chat_models/openai.js +10 -6
- package/dist/experimental/babyagi/agent.cjs +194 -0
- package/dist/experimental/babyagi/agent.d.ts +47 -0
- package/dist/experimental/babyagi/agent.js +190 -0
- package/dist/experimental/babyagi/index.cjs +11 -0
- package/dist/experimental/babyagi/index.d.ts +4 -0
- package/dist/experimental/babyagi/index.js +4 -0
- package/dist/experimental/babyagi/task_creation.cjs +29 -0
- package/dist/experimental/babyagi/task_creation.d.ts +5 -0
- package/dist/experimental/babyagi/task_creation.js +25 -0
- package/dist/experimental/babyagi/task_execution.cjs +20 -0
- package/dist/experimental/babyagi/task_execution.d.ts +5 -0
- package/dist/experimental/babyagi/task_execution.js +16 -0
- package/dist/experimental/babyagi/task_prioritization.cjs +23 -0
- package/dist/experimental/babyagi/task_prioritization.d.ts +5 -0
- package/dist/experimental/babyagi/task_prioritization.js +19 -0
- package/dist/llms/base.cjs +0 -9
- package/dist/llms/base.d.ts +11 -12
- package/dist/llms/base.js +0 -9
- package/dist/llms/openai-chat.cjs +9 -5
- package/dist/llms/openai-chat.d.ts +16 -7
- package/dist/llms/openai-chat.js +9 -5
- package/dist/llms/openai.cjs +9 -5
- package/dist/llms/openai.d.ts +15 -12
- package/dist/llms/openai.js +10 -6
- package/dist/memory/base.d.ts +1 -0
- package/dist/memory/buffer_memory.cjs +3 -0
- package/dist/memory/buffer_memory.d.ts +1 -0
- package/dist/memory/buffer_memory.js +3 -0
- package/dist/memory/buffer_window_memory.cjs +3 -0
- package/dist/memory/buffer_window_memory.d.ts +1 -0
- package/dist/memory/buffer_window_memory.js +3 -0
- package/dist/memory/motorhead_memory.cjs +3 -0
- package/dist/memory/motorhead_memory.d.ts +1 -0
- package/dist/memory/motorhead_memory.js +3 -0
- package/dist/memory/summary.cjs +3 -0
- package/dist/memory/summary.d.ts +1 -0
- package/dist/memory/summary.js +3 -0
- package/dist/retrievers/supabase.cjs +2 -2
- package/dist/retrievers/supabase.js +2 -2
- package/dist/tools/webbrowser.cjs +1 -1
- package/dist/tools/webbrowser.js +1 -1
- package/dist/util/async_caller.cjs +9 -0
- package/dist/util/async_caller.js +9 -0
- package/dist/util/axios-fetch-adapter.cjs +6 -0
- package/dist/util/axios-fetch-adapter.js +6 -0
- package/dist/util/axios-types.d.ts +3 -1
- package/dist/util/set.cjs +41 -0
- package/dist/util/set.d.ts +15 -0
- package/dist/util/set.js +35 -0
- package/dist/vectorstores/supabase.cjs +1 -1
- package/dist/vectorstores/supabase.js +1 -1
- package/experimental/babyagi.cjs +1 -0
- package/experimental/babyagi.d.ts +1 -0
- package/experimental/babyagi.js +1 -0
- package/package.json +11 -3
- package/dist/chains/simple_sequential_chain.cjs +0 -124
- package/dist/chains/simple_sequential_chain.js +0 -120
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SimpleSequentialChain = exports.SequentialChain = void 0;
|
|
4
|
+
const base_js_1 = require("./base.cjs");
|
|
5
|
+
const set_js_1 = require("../util/set.cjs");
|
|
6
|
+
function formatSet(input) {
|
|
7
|
+
return Array.from(input)
|
|
8
|
+
.map((i) => `"${i}"`)
|
|
9
|
+
.join(", ");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Chain where the outputs of one chain feed directly into next.
|
|
13
|
+
*/
|
|
14
|
+
class SequentialChain extends base_js_1.BaseChain {
|
|
15
|
+
get inputKeys() {
|
|
16
|
+
return this.inputVariables;
|
|
17
|
+
}
|
|
18
|
+
get outputKeys() {
|
|
19
|
+
return this.outputVariables;
|
|
20
|
+
}
|
|
21
|
+
constructor(fields) {
|
|
22
|
+
super(fields.memory, fields.verbose, fields.callbackManager);
|
|
23
|
+
Object.defineProperty(this, "chains", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "inputVariables", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "outputVariables", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: void 0
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "returnAll", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
47
|
+
this.chains = fields.chains;
|
|
48
|
+
this.inputVariables = fields.inputVariables;
|
|
49
|
+
this.outputVariables = fields.outputVariables ?? [];
|
|
50
|
+
if (this.outputVariables.length > 0 && fields.returnAll) {
|
|
51
|
+
throw new Error("Either specify variables to return using `outputVariables` or use `returnAll` param. Cannot apply both conditions at the same time.");
|
|
52
|
+
}
|
|
53
|
+
this.returnAll = fields.returnAll ?? false;
|
|
54
|
+
this._validateChains();
|
|
55
|
+
}
|
|
56
|
+
/** @ignore */
|
|
57
|
+
_validateChains() {
|
|
58
|
+
if (this.chains.length === 0) {
|
|
59
|
+
throw new Error("Sequential chain must have at least one chain.");
|
|
60
|
+
}
|
|
61
|
+
const memoryKeys = this.memory?.memoryKeys ?? [];
|
|
62
|
+
const inputKeysSet = new Set(this.inputKeys);
|
|
63
|
+
const memoryKeysSet = new Set(memoryKeys);
|
|
64
|
+
const keysIntersection = (0, set_js_1.intersection)(inputKeysSet, memoryKeysSet);
|
|
65
|
+
if (keysIntersection.size > 0) {
|
|
66
|
+
throw new Error(`The following keys: ${formatSet(keysIntersection)} are overlapping between memory and input keys of the chain variables. This can lead to unexpected behaviour. Please use input and memory keys that don't overlap.`);
|
|
67
|
+
}
|
|
68
|
+
const availableKeys = (0, set_js_1.union)(inputKeysSet, memoryKeysSet);
|
|
69
|
+
for (const chain of this.chains) {
|
|
70
|
+
const missingKeys = (0, set_js_1.difference)(new Set(chain.inputKeys), availableKeys);
|
|
71
|
+
if (missingKeys.size > 0) {
|
|
72
|
+
throw new Error(`Missing variables for chain "${chain._chainType()}": ${formatSet(missingKeys)}. Only got the following variables: ${formatSet(availableKeys)}.`);
|
|
73
|
+
}
|
|
74
|
+
const outputKeysSet = new Set(chain.outputKeys);
|
|
75
|
+
const overlappinOutputKeys = (0, set_js_1.intersection)(availableKeys, outputKeysSet);
|
|
76
|
+
if (overlappinOutputKeys.size > 0) {
|
|
77
|
+
throw new Error(`The following output variables for chain "${chain._chainType()}" are overlapping: ${formatSet(overlappinOutputKeys)}. This can lead to unexpected behaviour.`);
|
|
78
|
+
}
|
|
79
|
+
for (const outputKey of outputKeysSet) {
|
|
80
|
+
availableKeys.add(outputKey);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (this.outputVariables.length === 0) {
|
|
84
|
+
if (this.returnAll) {
|
|
85
|
+
const outputKeys = (0, set_js_1.difference)(availableKeys, inputKeysSet);
|
|
86
|
+
this.outputVariables = Array.from(outputKeys);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.outputVariables = this.chains[this.chains.length - 1].outputKeys;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const missingKeys = (0, set_js_1.difference)(new Set(this.outputVariables), new Set(availableKeys));
|
|
94
|
+
if (missingKeys.size > 0) {
|
|
95
|
+
throw new Error(`The following output variables were expected to be in the final chain output but were not found: ${formatSet(missingKeys)}.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** @ignore */
|
|
100
|
+
async _call(values, runManager) {
|
|
101
|
+
let input = values;
|
|
102
|
+
const allChainValues = {};
|
|
103
|
+
for (const chain of this.chains) {
|
|
104
|
+
input = await chain.call(input, runManager?.getChild());
|
|
105
|
+
for (const key of Object.keys(input)) {
|
|
106
|
+
allChainValues[key] = input[key];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const output = {};
|
|
110
|
+
for (const key of this.outputVariables) {
|
|
111
|
+
output[key] = allChainValues[key];
|
|
112
|
+
}
|
|
113
|
+
return output;
|
|
114
|
+
}
|
|
115
|
+
_chainType() {
|
|
116
|
+
return "sequential_chain";
|
|
117
|
+
}
|
|
118
|
+
static async deserialize(data) {
|
|
119
|
+
const chains = [];
|
|
120
|
+
const inputVariables = data.input_variables;
|
|
121
|
+
const outputVariables = data.output_variables;
|
|
122
|
+
const serializedChains = data.chains;
|
|
123
|
+
for (const serializedChain of serializedChains) {
|
|
124
|
+
const deserializedChain = await base_js_1.BaseChain.deserialize(serializedChain);
|
|
125
|
+
chains.push(deserializedChain);
|
|
126
|
+
}
|
|
127
|
+
return new SequentialChain({ chains, inputVariables, outputVariables });
|
|
128
|
+
}
|
|
129
|
+
serialize() {
|
|
130
|
+
const chains = [];
|
|
131
|
+
for (const chain of this.chains) {
|
|
132
|
+
chains.push(chain.serialize());
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
_type: this._chainType(),
|
|
136
|
+
input_variables: this.inputVariables,
|
|
137
|
+
output_variables: this.outputVariables,
|
|
138
|
+
chains,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.SequentialChain = SequentialChain;
|
|
143
|
+
/**
|
|
144
|
+
* Simple chain where a single string output of one chain is fed directly into the next.
|
|
145
|
+
* @augments BaseChain
|
|
146
|
+
* @augments SimpleSequentialChainInput
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { SimpleSequentialChain, LLMChain } from "langchain/chains";
|
|
151
|
+
* import { OpenAI } from "langchain/llms/openai";
|
|
152
|
+
* import { PromptTemplate } from "langchain/prompts";
|
|
153
|
+
*
|
|
154
|
+
* // This is an LLMChain to write a synopsis given a title of a play.
|
|
155
|
+
* const llm = new OpenAI({ temperature: 0 });
|
|
156
|
+
* const template = `You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
|
|
157
|
+
*
|
|
158
|
+
* Title: {title}
|
|
159
|
+
* Playwright: This is a synopsis for the above play:`
|
|
160
|
+
* const promptTemplate = new PromptTemplate({ template, inputVariables: ["title"] });
|
|
161
|
+
* const synopsisChain = new LLMChain({ llm, prompt: promptTemplate });
|
|
162
|
+
*
|
|
163
|
+
*
|
|
164
|
+
* // This is an LLMChain to write a review of a play given a synopsis.
|
|
165
|
+
* const reviewLLM = new OpenAI({ temperature: 0 })
|
|
166
|
+
* const reviewTemplate = `You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.
|
|
167
|
+
*
|
|
168
|
+
* Play Synopsis:
|
|
169
|
+
* {synopsis}
|
|
170
|
+
* Review from a New York Times play critic of the above play:`
|
|
171
|
+
* const reviewPromptTempalte = new PromptTemplate({ template: reviewTemplate, inputVariables: ["synopsis"] });
|
|
172
|
+
* const reviewChain = new LLMChain({ llm: reviewLLM, prompt: reviewPromptTempalte });
|
|
173
|
+
*
|
|
174
|
+
* const overallChain = new SimpleSequentialChain({chains: [synopsisChain, reviewChain], verbose:true})
|
|
175
|
+
* const review = await overallChain.run("Tragedy at sunset on the beach")
|
|
176
|
+
* // the variable review contains resulting play review.
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
class SimpleSequentialChain extends base_js_1.BaseChain {
|
|
180
|
+
get inputKeys() {
|
|
181
|
+
return [this.inputKey];
|
|
182
|
+
}
|
|
183
|
+
get outputKeys() {
|
|
184
|
+
return [this.outputKey];
|
|
185
|
+
}
|
|
186
|
+
constructor(fields) {
|
|
187
|
+
super(fields.memory, fields.verbose, fields.callbacks ?? fields.callbackManager);
|
|
188
|
+
Object.defineProperty(this, "chains", {
|
|
189
|
+
enumerable: true,
|
|
190
|
+
configurable: true,
|
|
191
|
+
writable: true,
|
|
192
|
+
value: void 0
|
|
193
|
+
});
|
|
194
|
+
Object.defineProperty(this, "inputKey", {
|
|
195
|
+
enumerable: true,
|
|
196
|
+
configurable: true,
|
|
197
|
+
writable: true,
|
|
198
|
+
value: "input"
|
|
199
|
+
});
|
|
200
|
+
Object.defineProperty(this, "outputKey", {
|
|
201
|
+
enumerable: true,
|
|
202
|
+
configurable: true,
|
|
203
|
+
writable: true,
|
|
204
|
+
value: "output"
|
|
205
|
+
});
|
|
206
|
+
Object.defineProperty(this, "trimOutputs", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
configurable: true,
|
|
209
|
+
writable: true,
|
|
210
|
+
value: void 0
|
|
211
|
+
});
|
|
212
|
+
this.chains = fields.chains;
|
|
213
|
+
this.trimOutputs = fields.trimOutputs ?? false;
|
|
214
|
+
this._validateChains();
|
|
215
|
+
}
|
|
216
|
+
/** @ignore */
|
|
217
|
+
_validateChains() {
|
|
218
|
+
for (const chain of this.chains) {
|
|
219
|
+
if (chain.inputKeys.length !== 1) {
|
|
220
|
+
throw new Error(`Chains used in SimpleSequentialChain should all have one input, got ${chain.inputKeys.length} for ${chain._chainType()}.`);
|
|
221
|
+
}
|
|
222
|
+
if (chain.outputKeys.length !== 1) {
|
|
223
|
+
throw new Error(`Chains used in SimpleSequentialChain should all have one output, got ${chain.outputKeys.length} for ${chain._chainType()}.`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/** @ignore */
|
|
228
|
+
async _call(values, runManager) {
|
|
229
|
+
let input = values[this.inputKey];
|
|
230
|
+
for (const chain of this.chains) {
|
|
231
|
+
input = await chain.run(input, runManager?.getChild());
|
|
232
|
+
if (this.trimOutputs) {
|
|
233
|
+
input = input.trim();
|
|
234
|
+
}
|
|
235
|
+
await runManager?.handleText(input);
|
|
236
|
+
}
|
|
237
|
+
return { [this.outputKey]: input };
|
|
238
|
+
}
|
|
239
|
+
_chainType() {
|
|
240
|
+
return "simple_sequential_chain";
|
|
241
|
+
}
|
|
242
|
+
static async deserialize(data) {
|
|
243
|
+
const chains = [];
|
|
244
|
+
const serializedChains = data.chains;
|
|
245
|
+
for (const serializedChain of serializedChains) {
|
|
246
|
+
const deserializedChain = await base_js_1.BaseChain.deserialize(serializedChain);
|
|
247
|
+
chains.push(deserializedChain);
|
|
248
|
+
}
|
|
249
|
+
return new SimpleSequentialChain({ chains });
|
|
250
|
+
}
|
|
251
|
+
serialize() {
|
|
252
|
+
const chains = [];
|
|
253
|
+
for (const chain of this.chains) {
|
|
254
|
+
chains.push(chain.serialize());
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
_type: this._chainType(),
|
|
258
|
+
chains,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
exports.SimpleSequentialChain = SimpleSequentialChain;
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
import { BaseChain, ChainInputs } from "./base.js";
|
|
2
2
|
import { ChainValues } from "../schema/index.js";
|
|
3
|
-
import { SerializedSimpleSequentialChain } from "./serde.js";
|
|
3
|
+
import { SerializedSequentialChain, SerializedSimpleSequentialChain } from "./serde.js";
|
|
4
4
|
import { CallbackManagerForChainRun } from "../callbacks/manager.js";
|
|
5
|
+
export interface SequentialChainInput extends ChainInputs {
|
|
6
|
+
/** Array of chains to run as a sequence. The chains are run in order they appear in the array. */
|
|
7
|
+
chains: BaseChain[];
|
|
8
|
+
/** Defines which variables should be passed as initial input to the first chain. */
|
|
9
|
+
inputVariables: string[];
|
|
10
|
+
/** Which variables should be returned as a result of executing the chain. If not specified, output of the last of the chains is used. */
|
|
11
|
+
outputVariables?: string[];
|
|
12
|
+
/** Whether or not to return all intermediate outputs and variables (excluding initial input variables). */
|
|
13
|
+
returnAll?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Chain where the outputs of one chain feed directly into next.
|
|
17
|
+
*/
|
|
18
|
+
export declare class SequentialChain extends BaseChain implements SequentialChainInput {
|
|
19
|
+
chains: BaseChain[];
|
|
20
|
+
inputVariables: string[];
|
|
21
|
+
outputVariables: string[];
|
|
22
|
+
returnAll?: boolean | undefined;
|
|
23
|
+
get inputKeys(): string[];
|
|
24
|
+
get outputKeys(): string[];
|
|
25
|
+
constructor(fields: SequentialChainInput);
|
|
26
|
+
/** @ignore */
|
|
27
|
+
_validateChains(): void;
|
|
28
|
+
/** @ignore */
|
|
29
|
+
_call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
|
|
30
|
+
_chainType(): "sequential_chain";
|
|
31
|
+
static deserialize(data: SerializedSequentialChain): Promise<SequentialChain>;
|
|
32
|
+
serialize(): SerializedSequentialChain;
|
|
33
|
+
}
|
|
5
34
|
export interface SimpleSequentialChainInput extends ChainInputs {
|
|
6
35
|
/** Array of chains to run as a sequence. The chains are run in order they appear in the array. */
|
|
7
36
|
chains: Array<BaseChain>;
|
|
@@ -55,7 +84,7 @@ export declare class SimpleSequentialChain extends BaseChain implements SimpleSe
|
|
|
55
84
|
/** @ignore */
|
|
56
85
|
_validateChains(): void;
|
|
57
86
|
/** @ignore */
|
|
58
|
-
_call(values: ChainValues, runManager
|
|
87
|
+
_call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
|
|
59
88
|
_chainType(): "simple_sequential_chain";
|
|
60
89
|
static deserialize(data: SerializedSimpleSequentialChain): Promise<SimpleSequentialChain>;
|
|
61
90
|
serialize(): SerializedSimpleSequentialChain;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { BaseChain } from "./base.js";
|
|
2
|
+
import { intersection, union, difference } from "../util/set.js";
|
|
3
|
+
function formatSet(input) {
|
|
4
|
+
return Array.from(input)
|
|
5
|
+
.map((i) => `"${i}"`)
|
|
6
|
+
.join(", ");
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Chain where the outputs of one chain feed directly into next.
|
|
10
|
+
*/
|
|
11
|
+
export class SequentialChain extends BaseChain {
|
|
12
|
+
get inputKeys() {
|
|
13
|
+
return this.inputVariables;
|
|
14
|
+
}
|
|
15
|
+
get outputKeys() {
|
|
16
|
+
return this.outputVariables;
|
|
17
|
+
}
|
|
18
|
+
constructor(fields) {
|
|
19
|
+
super(fields.memory, fields.verbose, fields.callbackManager);
|
|
20
|
+
Object.defineProperty(this, "chains", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: void 0
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "inputVariables", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "outputVariables", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "returnAll", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: void 0
|
|
43
|
+
});
|
|
44
|
+
this.chains = fields.chains;
|
|
45
|
+
this.inputVariables = fields.inputVariables;
|
|
46
|
+
this.outputVariables = fields.outputVariables ?? [];
|
|
47
|
+
if (this.outputVariables.length > 0 && fields.returnAll) {
|
|
48
|
+
throw new Error("Either specify variables to return using `outputVariables` or use `returnAll` param. Cannot apply both conditions at the same time.");
|
|
49
|
+
}
|
|
50
|
+
this.returnAll = fields.returnAll ?? false;
|
|
51
|
+
this._validateChains();
|
|
52
|
+
}
|
|
53
|
+
/** @ignore */
|
|
54
|
+
_validateChains() {
|
|
55
|
+
if (this.chains.length === 0) {
|
|
56
|
+
throw new Error("Sequential chain must have at least one chain.");
|
|
57
|
+
}
|
|
58
|
+
const memoryKeys = this.memory?.memoryKeys ?? [];
|
|
59
|
+
const inputKeysSet = new Set(this.inputKeys);
|
|
60
|
+
const memoryKeysSet = new Set(memoryKeys);
|
|
61
|
+
const keysIntersection = intersection(inputKeysSet, memoryKeysSet);
|
|
62
|
+
if (keysIntersection.size > 0) {
|
|
63
|
+
throw new Error(`The following keys: ${formatSet(keysIntersection)} are overlapping between memory and input keys of the chain variables. This can lead to unexpected behaviour. Please use input and memory keys that don't overlap.`);
|
|
64
|
+
}
|
|
65
|
+
const availableKeys = union(inputKeysSet, memoryKeysSet);
|
|
66
|
+
for (const chain of this.chains) {
|
|
67
|
+
const missingKeys = difference(new Set(chain.inputKeys), availableKeys);
|
|
68
|
+
if (missingKeys.size > 0) {
|
|
69
|
+
throw new Error(`Missing variables for chain "${chain._chainType()}": ${formatSet(missingKeys)}. Only got the following variables: ${formatSet(availableKeys)}.`);
|
|
70
|
+
}
|
|
71
|
+
const outputKeysSet = new Set(chain.outputKeys);
|
|
72
|
+
const overlappinOutputKeys = intersection(availableKeys, outputKeysSet);
|
|
73
|
+
if (overlappinOutputKeys.size > 0) {
|
|
74
|
+
throw new Error(`The following output variables for chain "${chain._chainType()}" are overlapping: ${formatSet(overlappinOutputKeys)}. This can lead to unexpected behaviour.`);
|
|
75
|
+
}
|
|
76
|
+
for (const outputKey of outputKeysSet) {
|
|
77
|
+
availableKeys.add(outputKey);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (this.outputVariables.length === 0) {
|
|
81
|
+
if (this.returnAll) {
|
|
82
|
+
const outputKeys = difference(availableKeys, inputKeysSet);
|
|
83
|
+
this.outputVariables = Array.from(outputKeys);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.outputVariables = this.chains[this.chains.length - 1].outputKeys;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const missingKeys = difference(new Set(this.outputVariables), new Set(availableKeys));
|
|
91
|
+
if (missingKeys.size > 0) {
|
|
92
|
+
throw new Error(`The following output variables were expected to be in the final chain output but were not found: ${formatSet(missingKeys)}.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** @ignore */
|
|
97
|
+
async _call(values, runManager) {
|
|
98
|
+
let input = values;
|
|
99
|
+
const allChainValues = {};
|
|
100
|
+
for (const chain of this.chains) {
|
|
101
|
+
input = await chain.call(input, runManager?.getChild());
|
|
102
|
+
for (const key of Object.keys(input)) {
|
|
103
|
+
allChainValues[key] = input[key];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const output = {};
|
|
107
|
+
for (const key of this.outputVariables) {
|
|
108
|
+
output[key] = allChainValues[key];
|
|
109
|
+
}
|
|
110
|
+
return output;
|
|
111
|
+
}
|
|
112
|
+
_chainType() {
|
|
113
|
+
return "sequential_chain";
|
|
114
|
+
}
|
|
115
|
+
static async deserialize(data) {
|
|
116
|
+
const chains = [];
|
|
117
|
+
const inputVariables = data.input_variables;
|
|
118
|
+
const outputVariables = data.output_variables;
|
|
119
|
+
const serializedChains = data.chains;
|
|
120
|
+
for (const serializedChain of serializedChains) {
|
|
121
|
+
const deserializedChain = await BaseChain.deserialize(serializedChain);
|
|
122
|
+
chains.push(deserializedChain);
|
|
123
|
+
}
|
|
124
|
+
return new SequentialChain({ chains, inputVariables, outputVariables });
|
|
125
|
+
}
|
|
126
|
+
serialize() {
|
|
127
|
+
const chains = [];
|
|
128
|
+
for (const chain of this.chains) {
|
|
129
|
+
chains.push(chain.serialize());
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
_type: this._chainType(),
|
|
133
|
+
input_variables: this.inputVariables,
|
|
134
|
+
output_variables: this.outputVariables,
|
|
135
|
+
chains,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Simple chain where a single string output of one chain is fed directly into the next.
|
|
141
|
+
* @augments BaseChain
|
|
142
|
+
* @augments SimpleSequentialChainInput
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* import { SimpleSequentialChain, LLMChain } from "langchain/chains";
|
|
147
|
+
* import { OpenAI } from "langchain/llms/openai";
|
|
148
|
+
* import { PromptTemplate } from "langchain/prompts";
|
|
149
|
+
*
|
|
150
|
+
* // This is an LLMChain to write a synopsis given a title of a play.
|
|
151
|
+
* const llm = new OpenAI({ temperature: 0 });
|
|
152
|
+
* const template = `You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
|
|
153
|
+
*
|
|
154
|
+
* Title: {title}
|
|
155
|
+
* Playwright: This is a synopsis for the above play:`
|
|
156
|
+
* const promptTemplate = new PromptTemplate({ template, inputVariables: ["title"] });
|
|
157
|
+
* const synopsisChain = new LLMChain({ llm, prompt: promptTemplate });
|
|
158
|
+
*
|
|
159
|
+
*
|
|
160
|
+
* // This is an LLMChain to write a review of a play given a synopsis.
|
|
161
|
+
* const reviewLLM = new OpenAI({ temperature: 0 })
|
|
162
|
+
* const reviewTemplate = `You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.
|
|
163
|
+
*
|
|
164
|
+
* Play Synopsis:
|
|
165
|
+
* {synopsis}
|
|
166
|
+
* Review from a New York Times play critic of the above play:`
|
|
167
|
+
* const reviewPromptTempalte = new PromptTemplate({ template: reviewTemplate, inputVariables: ["synopsis"] });
|
|
168
|
+
* const reviewChain = new LLMChain({ llm: reviewLLM, prompt: reviewPromptTempalte });
|
|
169
|
+
*
|
|
170
|
+
* const overallChain = new SimpleSequentialChain({chains: [synopsisChain, reviewChain], verbose:true})
|
|
171
|
+
* const review = await overallChain.run("Tragedy at sunset on the beach")
|
|
172
|
+
* // the variable review contains resulting play review.
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export class SimpleSequentialChain extends BaseChain {
|
|
176
|
+
get inputKeys() {
|
|
177
|
+
return [this.inputKey];
|
|
178
|
+
}
|
|
179
|
+
get outputKeys() {
|
|
180
|
+
return [this.outputKey];
|
|
181
|
+
}
|
|
182
|
+
constructor(fields) {
|
|
183
|
+
super(fields.memory, fields.verbose, fields.callbacks ?? fields.callbackManager);
|
|
184
|
+
Object.defineProperty(this, "chains", {
|
|
185
|
+
enumerable: true,
|
|
186
|
+
configurable: true,
|
|
187
|
+
writable: true,
|
|
188
|
+
value: void 0
|
|
189
|
+
});
|
|
190
|
+
Object.defineProperty(this, "inputKey", {
|
|
191
|
+
enumerable: true,
|
|
192
|
+
configurable: true,
|
|
193
|
+
writable: true,
|
|
194
|
+
value: "input"
|
|
195
|
+
});
|
|
196
|
+
Object.defineProperty(this, "outputKey", {
|
|
197
|
+
enumerable: true,
|
|
198
|
+
configurable: true,
|
|
199
|
+
writable: true,
|
|
200
|
+
value: "output"
|
|
201
|
+
});
|
|
202
|
+
Object.defineProperty(this, "trimOutputs", {
|
|
203
|
+
enumerable: true,
|
|
204
|
+
configurable: true,
|
|
205
|
+
writable: true,
|
|
206
|
+
value: void 0
|
|
207
|
+
});
|
|
208
|
+
this.chains = fields.chains;
|
|
209
|
+
this.trimOutputs = fields.trimOutputs ?? false;
|
|
210
|
+
this._validateChains();
|
|
211
|
+
}
|
|
212
|
+
/** @ignore */
|
|
213
|
+
_validateChains() {
|
|
214
|
+
for (const chain of this.chains) {
|
|
215
|
+
if (chain.inputKeys.length !== 1) {
|
|
216
|
+
throw new Error(`Chains used in SimpleSequentialChain should all have one input, got ${chain.inputKeys.length} for ${chain._chainType()}.`);
|
|
217
|
+
}
|
|
218
|
+
if (chain.outputKeys.length !== 1) {
|
|
219
|
+
throw new Error(`Chains used in SimpleSequentialChain should all have one output, got ${chain.outputKeys.length} for ${chain._chainType()}.`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** @ignore */
|
|
224
|
+
async _call(values, runManager) {
|
|
225
|
+
let input = values[this.inputKey];
|
|
226
|
+
for (const chain of this.chains) {
|
|
227
|
+
input = await chain.run(input, runManager?.getChild());
|
|
228
|
+
if (this.trimOutputs) {
|
|
229
|
+
input = input.trim();
|
|
230
|
+
}
|
|
231
|
+
await runManager?.handleText(input);
|
|
232
|
+
}
|
|
233
|
+
return { [this.outputKey]: input };
|
|
234
|
+
}
|
|
235
|
+
_chainType() {
|
|
236
|
+
return "simple_sequential_chain";
|
|
237
|
+
}
|
|
238
|
+
static async deserialize(data) {
|
|
239
|
+
const chains = [];
|
|
240
|
+
const serializedChains = data.chains;
|
|
241
|
+
for (const serializedChain of serializedChains) {
|
|
242
|
+
const deserializedChain = await BaseChain.deserialize(serializedChain);
|
|
243
|
+
chains.push(deserializedChain);
|
|
244
|
+
}
|
|
245
|
+
return new SimpleSequentialChain({ chains });
|
|
246
|
+
}
|
|
247
|
+
serialize() {
|
|
248
|
+
const chains = [];
|
|
249
|
+
for (const chain of this.chains) {
|
|
250
|
+
chains.push(chain.serialize());
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
_type: this._chainType(),
|
|
254
|
+
chains,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
package/dist/chains/serde.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ export type SerializedLLMChain = {
|
|
|
6
6
|
llm?: SerializedLLM;
|
|
7
7
|
prompt?: SerializedBasePromptTemplate;
|
|
8
8
|
};
|
|
9
|
+
export type SerializedSequentialChain = {
|
|
10
|
+
_type: "sequential_chain";
|
|
11
|
+
input_variables: string[];
|
|
12
|
+
output_variables: string[];
|
|
13
|
+
chains: SerializedBaseChain[];
|
|
14
|
+
};
|
|
9
15
|
export type SerializedSimpleSequentialChain = {
|
|
10
16
|
_type: "simple_sequential_chain";
|
|
11
17
|
chains: Array<SerializedBaseChain>;
|
|
@@ -44,4 +50,4 @@ export type SerializedAnalyzeDocumentChain = {
|
|
|
44
50
|
_type: "analyze_document_chain";
|
|
45
51
|
combine_document_chain?: SerializedBaseChain;
|
|
46
52
|
};
|
|
47
|
-
export type SerializedBaseChain = SerializedLLMChain | SerializedSimpleSequentialChain | SerializedVectorDBQAChain | SerializedStuffDocumentsChain | SerializedSqlDatabaseChain | SerializedChatVectorDBQAChain | SerializedMapReduceDocumentsChain | SerializedAnalyzeDocumentChain | SerializedRefineDocumentsChain;
|
|
53
|
+
export type SerializedBaseChain = SerializedLLMChain | SerializedSequentialChain | SerializedSimpleSequentialChain | SerializedVectorDBQAChain | SerializedStuffDocumentsChain | SerializedSqlDatabaseChain | SerializedChatVectorDBQAChain | SerializedMapReduceDocumentsChain | SerializedAnalyzeDocumentChain | SerializedRefineDocumentsChain;
|
|
@@ -63,8 +63,8 @@ class SqlDatabaseChain extends base_js_1.BaseChain {
|
|
|
63
63
|
this.outputKey = fields.outputKey ?? this.outputKey;
|
|
64
64
|
}
|
|
65
65
|
/** @ignore */
|
|
66
|
-
async _call(values) {
|
|
67
|
-
const
|
|
66
|
+
async _call(values, runManager) {
|
|
67
|
+
const llmChain = new llm_chain_js_1.LLMChain({
|
|
68
68
|
prompt: this.prompt,
|
|
69
69
|
llm: this.llm,
|
|
70
70
|
outputKey: this.outputKey,
|
|
@@ -86,7 +86,7 @@ class SqlDatabaseChain extends base_js_1.BaseChain {
|
|
|
86
86
|
};
|
|
87
87
|
await this.verifyNumberOfTokens(inputText, tableInfo);
|
|
88
88
|
const intermediateStep = [];
|
|
89
|
-
const sqlCommand = await
|
|
89
|
+
const sqlCommand = await llmChain.predict(llmInputs, runManager?.getChild());
|
|
90
90
|
intermediateStep.push(sqlCommand);
|
|
91
91
|
let queryResult = "";
|
|
92
92
|
try {
|
|
@@ -103,7 +103,9 @@ class SqlDatabaseChain extends base_js_1.BaseChain {
|
|
|
103
103
|
else {
|
|
104
104
|
inputText += `${+sqlCommand}\nSQLResult: ${JSON.stringify(queryResult)}\nAnswer:`;
|
|
105
105
|
llmInputs.input = inputText;
|
|
106
|
-
finalResult = {
|
|
106
|
+
finalResult = {
|
|
107
|
+
[this.outputKey]: await llmChain.predict(llmInputs, runManager?.getChild()),
|
|
108
|
+
};
|
|
107
109
|
}
|
|
108
110
|
return finalResult;
|
|
109
111
|
}
|
|
@@ -3,6 +3,7 @@ import type { SqlDatabase } from "../../sql_db.js";
|
|
|
3
3
|
import { ChainValues } from "../../schema/index.js";
|
|
4
4
|
import { SerializedSqlDatabaseChain } from "../serde.js";
|
|
5
5
|
import { BaseLanguageModel } from "../../base_language/index.js";
|
|
6
|
+
import { CallbackManagerForChainRun } from "../../callbacks/manager.js";
|
|
6
7
|
export interface SqlDatabaseChainInput extends ChainInputs {
|
|
7
8
|
llm: BaseLanguageModel;
|
|
8
9
|
database: SqlDatabase;
|
|
@@ -20,7 +21,7 @@ export declare class SqlDatabaseChain extends BaseChain {
|
|
|
20
21
|
returnDirect: boolean;
|
|
21
22
|
constructor(fields: SqlDatabaseChainInput);
|
|
22
23
|
/** @ignore */
|
|
23
|
-
_call(values: ChainValues): Promise<ChainValues>;
|
|
24
|
+
_call(values: ChainValues, runManager?: CallbackManagerForChainRun): Promise<ChainValues>;
|
|
24
25
|
_chainType(): "sql_database_chain";
|
|
25
26
|
get inputKeys(): string[];
|
|
26
27
|
get outputKeys(): string[];
|
|
@@ -60,8 +60,8 @@ export class SqlDatabaseChain extends BaseChain {
|
|
|
60
60
|
this.outputKey = fields.outputKey ?? this.outputKey;
|
|
61
61
|
}
|
|
62
62
|
/** @ignore */
|
|
63
|
-
async _call(values) {
|
|
64
|
-
const
|
|
63
|
+
async _call(values, runManager) {
|
|
64
|
+
const llmChain = new LLMChain({
|
|
65
65
|
prompt: this.prompt,
|
|
66
66
|
llm: this.llm,
|
|
67
67
|
outputKey: this.outputKey,
|
|
@@ -83,7 +83,7 @@ export class SqlDatabaseChain extends BaseChain {
|
|
|
83
83
|
};
|
|
84
84
|
await this.verifyNumberOfTokens(inputText, tableInfo);
|
|
85
85
|
const intermediateStep = [];
|
|
86
|
-
const sqlCommand = await
|
|
86
|
+
const sqlCommand = await llmChain.predict(llmInputs, runManager?.getChild());
|
|
87
87
|
intermediateStep.push(sqlCommand);
|
|
88
88
|
let queryResult = "";
|
|
89
89
|
try {
|
|
@@ -100,7 +100,9 @@ export class SqlDatabaseChain extends BaseChain {
|
|
|
100
100
|
else {
|
|
101
101
|
inputText += `${+sqlCommand}\nSQLResult: ${JSON.stringify(queryResult)}\nAnswer:`;
|
|
102
102
|
llmInputs.input = inputText;
|
|
103
|
-
finalResult = {
|
|
103
|
+
finalResult = {
|
|
104
|
+
[this.outputKey]: await llmChain.predict(llmInputs, runManager?.getChild()),
|
|
105
|
+
};
|
|
104
106
|
}
|
|
105
107
|
return finalResult;
|
|
106
108
|
}
|
|
@@ -50,14 +50,14 @@ class VectorDBQAChain extends base_js_1.BaseChain {
|
|
|
50
50
|
fields.returnSourceDocuments ?? this.returnSourceDocuments;
|
|
51
51
|
}
|
|
52
52
|
/** @ignore */
|
|
53
|
-
async _call(values) {
|
|
53
|
+
async _call(values, runManager) {
|
|
54
54
|
if (!(this.inputKey in values)) {
|
|
55
55
|
throw new Error(`Question key ${this.inputKey} not found.`);
|
|
56
56
|
}
|
|
57
57
|
const question = values[this.inputKey];
|
|
58
58
|
const docs = await this.vectorstore.similaritySearch(question, this.k);
|
|
59
59
|
const inputs = { question, input_documents: docs };
|
|
60
|
-
const result = await this.combineDocumentsChain.call(inputs);
|
|
60
|
+
const result = await this.combineDocumentsChain.call(inputs, runManager?.getChild());
|
|
61
61
|
if (this.returnSourceDocuments) {
|
|
62
62
|
return {
|
|
63
63
|
...result,
|