@langchain/core 0.1.4 → 0.1.6
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/README.md +1 -1
- package/dist/callbacks/manager.d.ts +0 -5
- package/dist/chat_history.d.ts +1 -0
- package/dist/language_models/base.d.ts +2 -0
- package/dist/output_parsers/index.cjs +1 -0
- package/dist/output_parsers/index.d.ts +1 -0
- package/dist/output_parsers/index.js +1 -0
- package/dist/output_parsers/json.cjs +137 -0
- package/dist/output_parsers/json.d.ts +17 -0
- package/dist/output_parsers/json.js +131 -0
- package/dist/output_parsers/list.cjs +121 -2
- package/dist/output_parsers/list.d.ts +21 -2
- package/dist/output_parsers/list.js +119 -2
- package/dist/prompt_values.cjs +3 -0
- package/dist/prompt_values.d.ts +1 -0
- package/dist/prompt_values.js +3 -0
- package/dist/prompts/chat.cjs +22 -2
- package/dist/prompts/chat.d.ts +4 -2
- package/dist/prompts/chat.js +22 -2
- package/dist/runnables/base.cjs +290 -31
- package/dist/runnables/base.d.ts +72 -20
- package/dist/runnables/base.js +289 -32
- package/dist/runnables/config.cjs +7 -3
- package/dist/runnables/config.d.ts +13 -2
- package/dist/runnables/config.js +5 -1
- package/dist/runnables/history.cjs +3 -3
- package/dist/runnables/history.d.ts +5 -6
- package/dist/runnables/history.js +3 -3
- package/dist/runnables/index.cjs +5 -2
- package/dist/runnables/index.d.ts +3 -3
- package/dist/runnables/index.js +3 -2
- package/dist/runnables/passthrough.cjs +5 -31
- package/dist/runnables/passthrough.d.ts +3 -11
- package/dist/runnables/passthrough.js +4 -29
- package/dist/utils/stream.cjs +113 -1
- package/dist/utils/stream.d.ts +13 -0
- package/dist/utils/stream.js +109 -0
- package/dist/utils/testing/index.cjs +14 -1
- package/dist/utils/testing/index.d.ts +5 -0
- package/dist/utils/testing/index.js +14 -1
- package/package.json +1 -1
package/dist/prompts/chat.cjs
CHANGED
|
@@ -60,12 +60,27 @@ class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
|
|
60
60
|
writable: true,
|
|
61
61
|
value: void 0
|
|
62
62
|
});
|
|
63
|
+
Object.defineProperty(this, "optional", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: void 0
|
|
68
|
+
});
|
|
63
69
|
this.variableName = fields.variableName;
|
|
70
|
+
this.optional = fields.optional ?? false;
|
|
64
71
|
}
|
|
65
72
|
get inputVariables() {
|
|
66
73
|
return [this.variableName];
|
|
67
74
|
}
|
|
68
75
|
validateInputOrThrow(input, variableName) {
|
|
76
|
+
if (this.optional && !input) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
else if (!input) {
|
|
80
|
+
const error = new Error(`Error: Field "${variableName}" in prompt uses a MessagesPlaceholder, which expects an array of BaseMessages as an input value. Received: undefined`);
|
|
81
|
+
error.name = "InputFormatError";
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
69
84
|
let isInputBaseMessage = false;
|
|
70
85
|
if (Array.isArray(input)) {
|
|
71
86
|
isInputBaseMessage = input.every((message) => (0, index_js_1.isBaseMessage)(message));
|
|
@@ -83,7 +98,7 @@ class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
|
|
83
98
|
}
|
|
84
99
|
async formatMessages(values) {
|
|
85
100
|
this.validateInputOrThrow(values[this.variableName], this.variableName);
|
|
86
|
-
return values[this.variableName];
|
|
101
|
+
return values[this.variableName] ?? [];
|
|
87
102
|
}
|
|
88
103
|
}
|
|
89
104
|
exports.MessagesPlaceholder = MessagesPlaceholder;
|
|
@@ -255,6 +270,10 @@ function _coerceMessagePromptTemplateLike(messagePromptTemplateLike) {
|
|
|
255
270
|
throw new Error(`Could not coerce message prompt template from input. Received message type: "${message._getType()}".`);
|
|
256
271
|
}
|
|
257
272
|
}
|
|
273
|
+
function isMessagesPlaceholder(x) {
|
|
274
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
275
|
+
return x.constructor.lc_name() === "MessagesPlaceholder";
|
|
276
|
+
}
|
|
258
277
|
/**
|
|
259
278
|
* Class that represents a chat prompt. It extends the
|
|
260
279
|
* BaseChatPromptTemplate and uses an array of BaseMessagePromptTemplate
|
|
@@ -357,7 +376,8 @@ class ChatPromptTemplate extends BaseChatPromptTemplate {
|
|
|
357
376
|
}
|
|
358
377
|
else {
|
|
359
378
|
const inputValues = promptMessage.inputVariables.reduce((acc, inputVariable) => {
|
|
360
|
-
if (!(inputVariable in allValues)
|
|
379
|
+
if (!(inputVariable in allValues) &&
|
|
380
|
+
!(isMessagesPlaceholder(promptMessage) && promptMessage.optional)) {
|
|
361
381
|
throw new Error(`Missing value for input variable \`${inputVariable.toString()}\``);
|
|
362
382
|
}
|
|
363
383
|
acc[inputVariable] = allValues[inputVariable];
|
package/dist/prompts/chat.d.ts
CHANGED
|
@@ -35,18 +35,20 @@ export declare abstract class BaseMessagePromptTemplate<RunInput extends InputVa
|
|
|
35
35
|
*/
|
|
36
36
|
export interface MessagesPlaceholderFields<T extends string> {
|
|
37
37
|
variableName: T;
|
|
38
|
+
optional?: boolean;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Class that represents a placeholder for messages in a chat prompt. It
|
|
41
42
|
* extends the BaseMessagePromptTemplate.
|
|
42
43
|
*/
|
|
43
|
-
export declare class MessagesPlaceholder<RunInput extends InputValues = any> extends BaseMessagePromptTemplate<RunInput> {
|
|
44
|
+
export declare class MessagesPlaceholder<RunInput extends InputValues = any> extends BaseMessagePromptTemplate<RunInput> implements MessagesPlaceholderFields<Extract<keyof RunInput, string>> {
|
|
44
45
|
static lc_name(): string;
|
|
45
46
|
variableName: Extract<keyof RunInput, string>;
|
|
47
|
+
optional: boolean;
|
|
46
48
|
constructor(variableName: Extract<keyof RunInput, string>);
|
|
47
49
|
constructor(fields: MessagesPlaceholderFields<Extract<keyof RunInput, string>>);
|
|
48
50
|
get inputVariables(): Extract<keyof RunInput, string>[];
|
|
49
|
-
validateInputOrThrow(input: Array<unknown
|
|
51
|
+
validateInputOrThrow(input: Array<unknown> | undefined, variableName: Extract<keyof RunInput, string>): input is BaseMessage[];
|
|
50
52
|
formatMessages(values: TypedPromptInputValues<RunInput>): Promise<BaseMessage[]>;
|
|
51
53
|
}
|
|
52
54
|
/**
|
package/dist/prompts/chat.js
CHANGED
|
@@ -56,12 +56,27 @@ export class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
|
|
56
56
|
writable: true,
|
|
57
57
|
value: void 0
|
|
58
58
|
});
|
|
59
|
+
Object.defineProperty(this, "optional", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: void 0
|
|
64
|
+
});
|
|
59
65
|
this.variableName = fields.variableName;
|
|
66
|
+
this.optional = fields.optional ?? false;
|
|
60
67
|
}
|
|
61
68
|
get inputVariables() {
|
|
62
69
|
return [this.variableName];
|
|
63
70
|
}
|
|
64
71
|
validateInputOrThrow(input, variableName) {
|
|
72
|
+
if (this.optional && !input) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
else if (!input) {
|
|
76
|
+
const error = new Error(`Error: Field "${variableName}" in prompt uses a MessagesPlaceholder, which expects an array of BaseMessages as an input value. Received: undefined`);
|
|
77
|
+
error.name = "InputFormatError";
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
65
80
|
let isInputBaseMessage = false;
|
|
66
81
|
if (Array.isArray(input)) {
|
|
67
82
|
isInputBaseMessage = input.every((message) => isBaseMessage(message));
|
|
@@ -79,7 +94,7 @@ export class MessagesPlaceholder extends BaseMessagePromptTemplate {
|
|
|
79
94
|
}
|
|
80
95
|
async formatMessages(values) {
|
|
81
96
|
this.validateInputOrThrow(values[this.variableName], this.variableName);
|
|
82
|
-
return values[this.variableName];
|
|
97
|
+
return values[this.variableName] ?? [];
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
100
|
/**
|
|
@@ -244,6 +259,10 @@ function _coerceMessagePromptTemplateLike(messagePromptTemplateLike) {
|
|
|
244
259
|
throw new Error(`Could not coerce message prompt template from input. Received message type: "${message._getType()}".`);
|
|
245
260
|
}
|
|
246
261
|
}
|
|
262
|
+
function isMessagesPlaceholder(x) {
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
264
|
+
return x.constructor.lc_name() === "MessagesPlaceholder";
|
|
265
|
+
}
|
|
247
266
|
/**
|
|
248
267
|
* Class that represents a chat prompt. It extends the
|
|
249
268
|
* BaseChatPromptTemplate and uses an array of BaseMessagePromptTemplate
|
|
@@ -346,7 +365,8 @@ export class ChatPromptTemplate extends BaseChatPromptTemplate {
|
|
|
346
365
|
}
|
|
347
366
|
else {
|
|
348
367
|
const inputValues = promptMessage.inputVariables.reduce((acc, inputVariable) => {
|
|
349
|
-
if (!(inputVariable in allValues)
|
|
368
|
+
if (!(inputVariable in allValues) &&
|
|
369
|
+
!(isMessagesPlaceholder(promptMessage) && promptMessage.optional)) {
|
|
350
370
|
throw new Error(`Missing value for input variable \`${inputVariable.toString()}\``);
|
|
351
371
|
}
|
|
352
372
|
acc[inputVariable] = allValues[inputVariable];
|
package/dist/runnables/base.cjs
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports._coerceToRunnable = exports.RunnableWithFallbacks = exports.RunnableParallel = exports.RunnableLambda = exports.RunnableMap = exports.RunnableSequence = exports.RunnableRetry = exports.RunnableEach = exports.RunnableBinding = exports.Runnable = void 0;
|
|
6
|
+
exports.RunnablePick = exports.RunnableAssign = exports._coerceToRunnable = exports.RunnableWithFallbacks = exports.RunnableParallel = exports.RunnableLambda = exports.RunnableMap = exports.RunnableSequence = exports.RunnableRetry = exports.RunnableEach = exports.RunnableBinding = exports.Runnable = void 0;
|
|
7
7
|
const p_retry_1 = __importDefault(require("p-retry"));
|
|
8
8
|
const manager_js_1 = require("../callbacks/manager.cjs");
|
|
9
9
|
const log_stream_js_1 = require("../tracers/log_stream.cjs");
|
|
@@ -31,6 +31,18 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
31
31
|
writable: true,
|
|
32
32
|
value: true
|
|
33
33
|
});
|
|
34
|
+
Object.defineProperty(this, "name", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true,
|
|
38
|
+
value: void 0
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
getName(suffix) {
|
|
42
|
+
const name =
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
this.name ?? this.constructor.lc_name() ?? this.constructor.name;
|
|
45
|
+
return suffix ? `${name}${suffix}` : name;
|
|
34
46
|
}
|
|
35
47
|
/**
|
|
36
48
|
* Bind arguments to a Runnable, returning a new Runnable.
|
|
@@ -145,17 +157,19 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
145
157
|
tags: options.tags,
|
|
146
158
|
metadata: options.metadata,
|
|
147
159
|
runName: options.runName,
|
|
160
|
+
configurable: options.configurable,
|
|
148
161
|
};
|
|
149
162
|
const callOptions = { ...options };
|
|
150
163
|
delete callOptions.callbacks;
|
|
151
164
|
delete callOptions.tags;
|
|
152
165
|
delete callOptions.metadata;
|
|
153
166
|
delete callOptions.runName;
|
|
167
|
+
delete callOptions.configurable;
|
|
154
168
|
return [runnableConfig, callOptions];
|
|
155
169
|
}
|
|
156
170
|
async _callWithConfig(func, input, options) {
|
|
157
|
-
const callbackManager_ = await (0, config_js_1.
|
|
158
|
-
const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, options?.runType, undefined, undefined, options?.runName);
|
|
171
|
+
const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
|
|
172
|
+
const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName());
|
|
159
173
|
let output;
|
|
160
174
|
try {
|
|
161
175
|
output = await func.bind(this)(input, options, runManager);
|
|
@@ -178,8 +192,8 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
178
192
|
*/
|
|
179
193
|
async _batchWithConfig(func, inputs, options, batchOptions) {
|
|
180
194
|
const optionsList = this._getOptionsList(options ?? {}, inputs.length);
|
|
181
|
-
const callbackManagers = await Promise.all(optionsList.map(config_js_1.
|
|
182
|
-
const runManagers = await Promise.all(callbackManagers.map((callbackManager, i) => callbackManager?.handleChainStart(this.toJSON(), _coerceToDict(inputs[i], "input"), undefined, optionsList[i].runType, undefined, undefined, optionsList[i].runName)));
|
|
195
|
+
const callbackManagers = await Promise.all(optionsList.map(config_js_1.getCallbackManagerForConfig));
|
|
196
|
+
const runManagers = await Promise.all(callbackManagers.map((callbackManager, i) => callbackManager?.handleChainStart(this.toJSON(), _coerceToDict(inputs[i], "input"), undefined, optionsList[i].runType, undefined, undefined, optionsList[i].runName ?? this.getName())));
|
|
183
197
|
let outputs;
|
|
184
198
|
try {
|
|
185
199
|
outputs = await func(inputs, optionsList, runManagers, batchOptions);
|
|
@@ -201,16 +215,10 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
201
215
|
let finalInputSupported = true;
|
|
202
216
|
let finalOutput;
|
|
203
217
|
let finalOutputSupported = true;
|
|
204
|
-
const callbackManager_ = await (0, config_js_1.
|
|
205
|
-
|
|
206
|
-
const serializedRepresentation = this.toJSON();
|
|
218
|
+
const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
|
|
219
|
+
const inputGeneratorWithSetup = new stream_js_1.AsyncGeneratorWithSetup(inputGenerator, async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName()));
|
|
207
220
|
async function* wrapInputForTracing() {
|
|
208
|
-
for await (const chunk of
|
|
209
|
-
if (!runManager) {
|
|
210
|
-
// Start the run manager AFTER the iterator starts to preserve
|
|
211
|
-
// tracing order
|
|
212
|
-
runManager = await callbackManager_?.handleChainStart(serializedRepresentation, { input: "" }, undefined, options?.runType, undefined, undefined, options?.runName);
|
|
213
|
-
}
|
|
221
|
+
for await (const chunk of inputGeneratorWithSetup) {
|
|
214
222
|
if (finalInputSupported) {
|
|
215
223
|
if (finalInput === undefined) {
|
|
216
224
|
finalInput = chunk;
|
|
@@ -218,7 +226,7 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
218
226
|
else {
|
|
219
227
|
try {
|
|
220
228
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
221
|
-
finalInput =
|
|
229
|
+
finalInput = (0, stream_js_1.concat)(finalInput, chunk);
|
|
222
230
|
}
|
|
223
231
|
catch {
|
|
224
232
|
finalInput = undefined;
|
|
@@ -229,9 +237,8 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
229
237
|
yield chunk;
|
|
230
238
|
}
|
|
231
239
|
}
|
|
232
|
-
const wrappedInputGenerator = wrapInputForTracing();
|
|
233
240
|
try {
|
|
234
|
-
const outputIterator = transformer(
|
|
241
|
+
const outputIterator = transformer(wrapInputForTracing(), inputGeneratorWithSetup.setup, options);
|
|
235
242
|
for await (const chunk of outputIterator) {
|
|
236
243
|
yield chunk;
|
|
237
244
|
if (finalOutputSupported) {
|
|
@@ -241,7 +248,7 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
241
248
|
else {
|
|
242
249
|
try {
|
|
243
250
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
244
|
-
finalOutput =
|
|
251
|
+
finalOutput = (0, stream_js_1.concat)(finalOutput, chunk);
|
|
245
252
|
}
|
|
246
253
|
catch {
|
|
247
254
|
finalOutput = undefined;
|
|
@@ -252,14 +259,16 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
252
259
|
}
|
|
253
260
|
}
|
|
254
261
|
catch (e) {
|
|
262
|
+
const runManager = await inputGeneratorWithSetup.setup;
|
|
255
263
|
await runManager?.handleChainError(e, undefined, undefined, undefined, {
|
|
256
264
|
inputs: _coerceToDict(finalInput, "input"),
|
|
257
265
|
});
|
|
258
266
|
throw e;
|
|
259
267
|
}
|
|
268
|
+
const runManager = await inputGeneratorWithSetup.setup;
|
|
260
269
|
await runManager?.handleChainEnd(finalOutput ?? {}, undefined, undefined, undefined, { inputs: _coerceToDict(finalInput, "input") });
|
|
261
270
|
}
|
|
262
|
-
_patchConfig(config = {}, callbackManager = undefined) {
|
|
271
|
+
_patchConfig(config = {}, callbackManager = undefined, recursionLimit = undefined) {
|
|
263
272
|
const newConfig = { ...config };
|
|
264
273
|
if (callbackManager !== undefined) {
|
|
265
274
|
/**
|
|
@@ -269,6 +278,9 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
269
278
|
delete newConfig.runName;
|
|
270
279
|
return { ...newConfig, callbacks: callbackManager };
|
|
271
280
|
}
|
|
281
|
+
if (recursionLimit !== undefined) {
|
|
282
|
+
newConfig.recursionLimit = recursionLimit;
|
|
283
|
+
}
|
|
272
284
|
return newConfig;
|
|
273
285
|
}
|
|
274
286
|
/**
|
|
@@ -284,6 +296,23 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
284
296
|
last: _coerceToRunnable(coerceable),
|
|
285
297
|
});
|
|
286
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Pick keys from the dict output of this runnable. Returns a new runnable.
|
|
301
|
+
*/
|
|
302
|
+
pick(keys) {
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
304
|
+
return this.pipe(new RunnablePick(keys));
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Assigns new fields to the dict output of this runnable. Returns a new runnable.
|
|
308
|
+
*/
|
|
309
|
+
assign(mapping) {
|
|
310
|
+
return this.pipe(
|
|
311
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
312
|
+
new RunnableAssign(
|
|
313
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
314
|
+
new RunnableMap({ steps: mapping })));
|
|
315
|
+
}
|
|
287
316
|
/**
|
|
288
317
|
* Default implementation of transform, which buffers input and then calls stream.
|
|
289
318
|
* Subclasses should override this method if they can start producing output while
|
|
@@ -301,7 +330,7 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
301
330
|
// Make a best effort to gather, for any type that supports concat.
|
|
302
331
|
// This method should throw an error if gathering fails.
|
|
303
332
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
304
|
-
finalChunk =
|
|
333
|
+
finalChunk = (0, stream_js_1.concat)(finalChunk, chunk);
|
|
305
334
|
}
|
|
306
335
|
}
|
|
307
336
|
yield* this._streamIterator(finalChunk, options);
|
|
@@ -451,6 +480,9 @@ class RunnableBinding extends Runnable {
|
|
|
451
480
|
this.config = fields.config;
|
|
452
481
|
this.configFactories = fields.configFactories;
|
|
453
482
|
}
|
|
483
|
+
getName(suffix) {
|
|
484
|
+
return this.bound.getName(suffix);
|
|
485
|
+
}
|
|
454
486
|
async _mergeConfig(
|
|
455
487
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
456
488
|
options) {
|
|
@@ -460,21 +492,24 @@ class RunnableBinding extends Runnable {
|
|
|
460
492
|
: []));
|
|
461
493
|
}
|
|
462
494
|
bind(kwargs) {
|
|
463
|
-
|
|
495
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
496
|
+
return new this.constructor({
|
|
464
497
|
bound: this.bound,
|
|
465
498
|
kwargs: { ...this.kwargs, ...kwargs },
|
|
466
499
|
config: this.config,
|
|
467
500
|
});
|
|
468
501
|
}
|
|
469
502
|
withConfig(config) {
|
|
470
|
-
|
|
503
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
504
|
+
return new this.constructor({
|
|
471
505
|
bound: this.bound,
|
|
472
506
|
kwargs: this.kwargs,
|
|
473
507
|
config: { ...this.config, ...config },
|
|
474
508
|
});
|
|
475
509
|
}
|
|
476
510
|
withRetry(fields) {
|
|
477
|
-
|
|
511
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
512
|
+
return new this.constructor({
|
|
478
513
|
bound: this.bound.withRetry(fields),
|
|
479
514
|
kwargs: this.kwargs,
|
|
480
515
|
config: this.config,
|
|
@@ -776,12 +811,13 @@ class RunnableSequence extends Runnable {
|
|
|
776
811
|
this.first = fields.first;
|
|
777
812
|
this.middle = fields.middle ?? this.middle;
|
|
778
813
|
this.last = fields.last;
|
|
814
|
+
this.name = fields.name;
|
|
779
815
|
}
|
|
780
816
|
get steps() {
|
|
781
817
|
return [this.first, ...this.middle, this.last];
|
|
782
818
|
}
|
|
783
819
|
async invoke(input, options) {
|
|
784
|
-
const callbackManager_ = await (0, config_js_1.
|
|
820
|
+
const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
|
|
785
821
|
const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, undefined, undefined, undefined, options?.runName);
|
|
786
822
|
let nextStepInput = input;
|
|
787
823
|
let finalOutput;
|
|
@@ -803,7 +839,7 @@ class RunnableSequence extends Runnable {
|
|
|
803
839
|
}
|
|
804
840
|
async batch(inputs, options, batchOptions) {
|
|
805
841
|
const configList = this._getOptionsList(options ?? {}, inputs.length);
|
|
806
|
-
const callbackManagers = await Promise.all(configList.map(config_js_1.
|
|
842
|
+
const callbackManagers = await Promise.all(configList.map(config_js_1.getCallbackManagerForConfig));
|
|
807
843
|
const runManagers = await Promise.all(callbackManagers.map((callbackManager, i) => callbackManager?.handleChainStart(this.toJSON(), _coerceToDict(inputs[i], "input"), undefined, undefined, undefined, undefined, configList[i].runName)));
|
|
808
844
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
809
845
|
let nextStepInputs = inputs;
|
|
@@ -824,7 +860,7 @@ class RunnableSequence extends Runnable {
|
|
|
824
860
|
return finalOutputs;
|
|
825
861
|
}
|
|
826
862
|
async *_streamIterator(input, options) {
|
|
827
|
-
const callbackManager_ = await (0, config_js_1.
|
|
863
|
+
const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
|
|
828
864
|
const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, undefined, undefined, undefined, options?.runName);
|
|
829
865
|
const steps = [this.first, ...this.middle, this.last];
|
|
830
866
|
let concatSupported = true;
|
|
@@ -847,7 +883,7 @@ class RunnableSequence extends Runnable {
|
|
|
847
883
|
else {
|
|
848
884
|
try {
|
|
849
885
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
850
|
-
finalOutput =
|
|
886
|
+
finalOutput = (0, stream_js_1.concat)(finalOutput, chunk);
|
|
851
887
|
}
|
|
852
888
|
catch (e) {
|
|
853
889
|
finalOutput = undefined;
|
|
@@ -873,6 +909,7 @@ class RunnableSequence extends Runnable {
|
|
|
873
909
|
...coerceable.middle,
|
|
874
910
|
]),
|
|
875
911
|
last: coerceable.last,
|
|
912
|
+
name: this.name ?? coerceable.name,
|
|
876
913
|
});
|
|
877
914
|
}
|
|
878
915
|
else {
|
|
@@ -880,6 +917,7 @@ class RunnableSequence extends Runnable {
|
|
|
880
917
|
first: this.first,
|
|
881
918
|
middle: [...this.middle, this.last],
|
|
882
919
|
last: _coerceToRunnable(coerceable),
|
|
920
|
+
name: this.name,
|
|
883
921
|
});
|
|
884
922
|
}
|
|
885
923
|
}
|
|
@@ -888,11 +926,12 @@ class RunnableSequence extends Runnable {
|
|
|
888
926
|
return Array.isArray(thing.middle) && Runnable.isRunnable(thing);
|
|
889
927
|
}
|
|
890
928
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
891
|
-
static from([first, ...runnables]) {
|
|
929
|
+
static from([first, ...runnables], name) {
|
|
892
930
|
return new RunnableSequence({
|
|
893
931
|
first: _coerceToRunnable(first),
|
|
894
932
|
middle: runnables.slice(0, -1).map(_coerceToRunnable),
|
|
895
933
|
last: _coerceToRunnable(runnables[runnables.length - 1]),
|
|
934
|
+
name,
|
|
896
935
|
});
|
|
897
936
|
}
|
|
898
937
|
}
|
|
@@ -949,7 +988,7 @@ class RunnableMap extends Runnable {
|
|
|
949
988
|
return new RunnableMap({ steps });
|
|
950
989
|
}
|
|
951
990
|
async invoke(input, options) {
|
|
952
|
-
const callbackManager_ = await (0, config_js_1.
|
|
991
|
+
const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
|
|
953
992
|
const runManager = await callbackManager_?.handleChainStart(this.toJSON(), {
|
|
954
993
|
input,
|
|
955
994
|
}, undefined, undefined, undefined, undefined, options?.runName);
|
|
@@ -957,7 +996,7 @@ class RunnableMap extends Runnable {
|
|
|
957
996
|
const output = {};
|
|
958
997
|
try {
|
|
959
998
|
await Promise.all(Object.entries(this.steps).map(async ([key, runnable]) => {
|
|
960
|
-
output[key] = await runnable.invoke(input, this._patchConfig(options, runManager?.getChild(key)));
|
|
999
|
+
output[key] = await runnable.invoke(input, this._patchConfig(options, runManager?.getChild(`map:key:${key}`)));
|
|
961
1000
|
}));
|
|
962
1001
|
}
|
|
963
1002
|
catch (e) {
|
|
@@ -967,6 +1006,38 @@ class RunnableMap extends Runnable {
|
|
|
967
1006
|
await runManager?.handleChainEnd(output);
|
|
968
1007
|
return output;
|
|
969
1008
|
}
|
|
1009
|
+
async *_transform(generator, runManagerPromise, options) {
|
|
1010
|
+
// shallow copy steps to ignore changes while iterating
|
|
1011
|
+
const steps = { ...this.steps };
|
|
1012
|
+
// each step gets a copy of the input iterator
|
|
1013
|
+
const inputCopies = (0, stream_js_1.atee)(generator, Object.keys(steps).length);
|
|
1014
|
+
const runManager = await runManagerPromise;
|
|
1015
|
+
// start the first iteration of each output iterator
|
|
1016
|
+
const tasks = new Map(Object.entries(steps).map(([key, runnable], i) => {
|
|
1017
|
+
const gen = runnable.transform(inputCopies[i], this._patchConfig(options, runManager?.getChild(`map:key:${key}`)));
|
|
1018
|
+
return [key, gen.next().then((result) => ({ key, gen, result }))];
|
|
1019
|
+
}));
|
|
1020
|
+
// yield chunks as they become available,
|
|
1021
|
+
// starting new iterations as needed,
|
|
1022
|
+
// until all iterators are done
|
|
1023
|
+
while (tasks.size) {
|
|
1024
|
+
const { key, result, gen } = await Promise.race(tasks.values());
|
|
1025
|
+
tasks.delete(key);
|
|
1026
|
+
if (!result.done) {
|
|
1027
|
+
yield { [key]: result.value };
|
|
1028
|
+
tasks.set(key, gen.next().then((result) => ({ key, gen, result })));
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
transform(generator, options) {
|
|
1033
|
+
return this._transformStreamWithConfig(generator, this._transform.bind(this), options);
|
|
1034
|
+
}
|
|
1035
|
+
async stream(input, options) {
|
|
1036
|
+
async function* generator() {
|
|
1037
|
+
yield input;
|
|
1038
|
+
}
|
|
1039
|
+
return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
|
|
1040
|
+
}
|
|
970
1041
|
}
|
|
971
1042
|
exports.RunnableMap = RunnableMap;
|
|
972
1043
|
/**
|
|
@@ -1000,13 +1071,57 @@ class RunnableLambda extends Runnable {
|
|
|
1000
1071
|
async _invoke(input, config, runManager) {
|
|
1001
1072
|
let output = await this.func(input, { config });
|
|
1002
1073
|
if (output && Runnable.isRunnable(output)) {
|
|
1003
|
-
|
|
1074
|
+
if (config?.recursionLimit === 0) {
|
|
1075
|
+
throw new Error("Recursion limit reached.");
|
|
1076
|
+
}
|
|
1077
|
+
output = await output.invoke(input, this._patchConfig(config, runManager?.getChild(), (config?.recursionLimit ?? config_js_1.DEFAULT_RECURSION_LIMIT) - 1));
|
|
1004
1078
|
}
|
|
1005
1079
|
return output;
|
|
1006
1080
|
}
|
|
1007
1081
|
async invoke(input, options) {
|
|
1008
1082
|
return this._callWithConfig(this._invoke, input, options);
|
|
1009
1083
|
}
|
|
1084
|
+
async *_transform(generator, runManagerPromise, config) {
|
|
1085
|
+
let finalChunk;
|
|
1086
|
+
for await (const chunk of generator) {
|
|
1087
|
+
if (finalChunk === undefined) {
|
|
1088
|
+
finalChunk = chunk;
|
|
1089
|
+
}
|
|
1090
|
+
else {
|
|
1091
|
+
// Make a best effort to gather, for any type that supports concat.
|
|
1092
|
+
try {
|
|
1093
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1094
|
+
finalChunk = (0, stream_js_1.concat)(finalChunk, chunk);
|
|
1095
|
+
}
|
|
1096
|
+
catch (e) {
|
|
1097
|
+
finalChunk = chunk;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
const output = await this.func(finalChunk, { config });
|
|
1102
|
+
if (output && Runnable.isRunnable(output)) {
|
|
1103
|
+
if (config?.recursionLimit === 0) {
|
|
1104
|
+
throw new Error("Recursion limit reached.");
|
|
1105
|
+
}
|
|
1106
|
+
const runManager = await runManagerPromise;
|
|
1107
|
+
const stream = await output.stream(finalChunk, this._patchConfig(config, runManager?.getChild(), (config?.recursionLimit ?? config_js_1.DEFAULT_RECURSION_LIMIT) - 1));
|
|
1108
|
+
for await (const chunk of stream) {
|
|
1109
|
+
yield chunk;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
yield output;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
transform(generator, options) {
|
|
1117
|
+
return this._transformStreamWithConfig(generator, this._transform.bind(this), options);
|
|
1118
|
+
}
|
|
1119
|
+
async stream(input, options) {
|
|
1120
|
+
async function* generator() {
|
|
1121
|
+
yield input;
|
|
1122
|
+
}
|
|
1123
|
+
return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
|
|
1124
|
+
}
|
|
1010
1125
|
}
|
|
1011
1126
|
exports.RunnableLambda = RunnableLambda;
|
|
1012
1127
|
class RunnableParallel extends RunnableMap {
|
|
@@ -1127,3 +1242,147 @@ function _coerceToRunnable(coerceable) {
|
|
|
1127
1242
|
}
|
|
1128
1243
|
}
|
|
1129
1244
|
exports._coerceToRunnable = _coerceToRunnable;
|
|
1245
|
+
/**
|
|
1246
|
+
* A runnable that assigns key-value pairs to inputs of type `Record<string, unknown>`.
|
|
1247
|
+
*/
|
|
1248
|
+
class RunnableAssign extends Runnable {
|
|
1249
|
+
static lc_name() {
|
|
1250
|
+
return "RunnableAssign";
|
|
1251
|
+
}
|
|
1252
|
+
constructor(fields) {
|
|
1253
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
1254
|
+
if (fields instanceof RunnableMap) {
|
|
1255
|
+
// eslint-disable-next-line no-param-reassign
|
|
1256
|
+
fields = { mapper: fields };
|
|
1257
|
+
}
|
|
1258
|
+
super(fields);
|
|
1259
|
+
Object.defineProperty(this, "lc_namespace", {
|
|
1260
|
+
enumerable: true,
|
|
1261
|
+
configurable: true,
|
|
1262
|
+
writable: true,
|
|
1263
|
+
value: ["langchain_core", "runnables"]
|
|
1264
|
+
});
|
|
1265
|
+
Object.defineProperty(this, "lc_serializable", {
|
|
1266
|
+
enumerable: true,
|
|
1267
|
+
configurable: true,
|
|
1268
|
+
writable: true,
|
|
1269
|
+
value: true
|
|
1270
|
+
});
|
|
1271
|
+
Object.defineProperty(this, "mapper", {
|
|
1272
|
+
enumerable: true,
|
|
1273
|
+
configurable: true,
|
|
1274
|
+
writable: true,
|
|
1275
|
+
value: void 0
|
|
1276
|
+
});
|
|
1277
|
+
this.mapper = fields.mapper;
|
|
1278
|
+
}
|
|
1279
|
+
async invoke(input, options) {
|
|
1280
|
+
const mapperResult = await this.mapper.invoke(input, options);
|
|
1281
|
+
return {
|
|
1282
|
+
...input,
|
|
1283
|
+
...mapperResult,
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
async *_transform(generator, runManagerPromise, options) {
|
|
1287
|
+
// collect mapper keys
|
|
1288
|
+
const mapperKeys = this.mapper.getStepsKeys();
|
|
1289
|
+
// create two input gens, one for the mapper, one for the input
|
|
1290
|
+
const [forPassthrough, forMapper] = (0, stream_js_1.atee)(generator);
|
|
1291
|
+
const runManager = await runManagerPromise;
|
|
1292
|
+
// create mapper output gen
|
|
1293
|
+
const mapperOutput = this.mapper.transform(forMapper, this._patchConfig(options, runManager?.getChild()));
|
|
1294
|
+
// start the mapper
|
|
1295
|
+
const firstMapperChunkPromise = mapperOutput.next();
|
|
1296
|
+
// yield the passthrough
|
|
1297
|
+
for await (const chunk of forPassthrough) {
|
|
1298
|
+
if (typeof chunk !== "object" || Array.isArray(chunk)) {
|
|
1299
|
+
throw new Error(`RunnableAssign can only be used with objects as input, got ${typeof chunk}`);
|
|
1300
|
+
}
|
|
1301
|
+
const filtered = Object.fromEntries(Object.entries(chunk).filter(([key]) => !mapperKeys.includes(key)));
|
|
1302
|
+
if (Object.keys(filtered).length > 0) {
|
|
1303
|
+
yield filtered;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
// yield the mapper output
|
|
1307
|
+
yield (await firstMapperChunkPromise).value;
|
|
1308
|
+
for await (const chunk of mapperOutput) {
|
|
1309
|
+
yield chunk;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
transform(generator, options) {
|
|
1313
|
+
return this._transformStreamWithConfig(generator, this._transform.bind(this), options);
|
|
1314
|
+
}
|
|
1315
|
+
async stream(input, options) {
|
|
1316
|
+
async function* generator() {
|
|
1317
|
+
yield input;
|
|
1318
|
+
}
|
|
1319
|
+
return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
exports.RunnableAssign = RunnableAssign;
|
|
1323
|
+
/**
|
|
1324
|
+
* A runnable that assigns key-value pairs to inputs of type `Record<string, unknown>`.
|
|
1325
|
+
*/
|
|
1326
|
+
class RunnablePick extends Runnable {
|
|
1327
|
+
static lc_name() {
|
|
1328
|
+
return "RunnablePick";
|
|
1329
|
+
}
|
|
1330
|
+
constructor(fields) {
|
|
1331
|
+
if (typeof fields === "string" || Array.isArray(fields)) {
|
|
1332
|
+
// eslint-disable-next-line no-param-reassign
|
|
1333
|
+
fields = { keys: fields };
|
|
1334
|
+
}
|
|
1335
|
+
super(fields);
|
|
1336
|
+
Object.defineProperty(this, "lc_namespace", {
|
|
1337
|
+
enumerable: true,
|
|
1338
|
+
configurable: true,
|
|
1339
|
+
writable: true,
|
|
1340
|
+
value: ["langchain_core", "runnables"]
|
|
1341
|
+
});
|
|
1342
|
+
Object.defineProperty(this, "lc_serializable", {
|
|
1343
|
+
enumerable: true,
|
|
1344
|
+
configurable: true,
|
|
1345
|
+
writable: true,
|
|
1346
|
+
value: true
|
|
1347
|
+
});
|
|
1348
|
+
Object.defineProperty(this, "keys", {
|
|
1349
|
+
enumerable: true,
|
|
1350
|
+
configurable: true,
|
|
1351
|
+
writable: true,
|
|
1352
|
+
value: void 0
|
|
1353
|
+
});
|
|
1354
|
+
this.keys = fields.keys;
|
|
1355
|
+
}
|
|
1356
|
+
async _pick(input) {
|
|
1357
|
+
if (typeof this.keys === "string") {
|
|
1358
|
+
return input[this.keys];
|
|
1359
|
+
}
|
|
1360
|
+
else {
|
|
1361
|
+
const picked = this.keys
|
|
1362
|
+
.map((key) => [key, input[key]])
|
|
1363
|
+
.filter((v) => v[1] !== undefined);
|
|
1364
|
+
return picked.length === 0 ? undefined : Object.fromEntries(picked);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
async invoke(input, options) {
|
|
1368
|
+
return this._callWithConfig(this._pick.bind(this), input, options);
|
|
1369
|
+
}
|
|
1370
|
+
async *_transform(generator) {
|
|
1371
|
+
for await (const chunk of generator) {
|
|
1372
|
+
const picked = await this._pick(chunk);
|
|
1373
|
+
if (picked !== undefined) {
|
|
1374
|
+
yield picked;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
transform(generator, options) {
|
|
1379
|
+
return this._transformStreamWithConfig(generator, this._transform.bind(this), options);
|
|
1380
|
+
}
|
|
1381
|
+
async stream(input, options) {
|
|
1382
|
+
async function* generator() {
|
|
1383
|
+
yield input;
|
|
1384
|
+
}
|
|
1385
|
+
return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
exports.RunnablePick = RunnablePick;
|