@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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/callbacks/manager.d.ts +0 -5
  3. package/dist/chat_history.d.ts +1 -0
  4. package/dist/language_models/base.d.ts +2 -0
  5. package/dist/output_parsers/index.cjs +1 -0
  6. package/dist/output_parsers/index.d.ts +1 -0
  7. package/dist/output_parsers/index.js +1 -0
  8. package/dist/output_parsers/json.cjs +137 -0
  9. package/dist/output_parsers/json.d.ts +17 -0
  10. package/dist/output_parsers/json.js +131 -0
  11. package/dist/output_parsers/list.cjs +121 -2
  12. package/dist/output_parsers/list.d.ts +21 -2
  13. package/dist/output_parsers/list.js +119 -2
  14. package/dist/prompt_values.cjs +3 -0
  15. package/dist/prompt_values.d.ts +1 -0
  16. package/dist/prompt_values.js +3 -0
  17. package/dist/prompts/chat.cjs +22 -2
  18. package/dist/prompts/chat.d.ts +4 -2
  19. package/dist/prompts/chat.js +22 -2
  20. package/dist/runnables/base.cjs +290 -31
  21. package/dist/runnables/base.d.ts +72 -20
  22. package/dist/runnables/base.js +289 -32
  23. package/dist/runnables/config.cjs +7 -3
  24. package/dist/runnables/config.d.ts +13 -2
  25. package/dist/runnables/config.js +5 -1
  26. package/dist/runnables/history.cjs +3 -3
  27. package/dist/runnables/history.d.ts +5 -6
  28. package/dist/runnables/history.js +3 -3
  29. package/dist/runnables/index.cjs +5 -2
  30. package/dist/runnables/index.d.ts +3 -3
  31. package/dist/runnables/index.js +3 -2
  32. package/dist/runnables/passthrough.cjs +5 -31
  33. package/dist/runnables/passthrough.d.ts +3 -11
  34. package/dist/runnables/passthrough.js +4 -29
  35. package/dist/utils/stream.cjs +113 -1
  36. package/dist/utils/stream.d.ts +13 -0
  37. package/dist/utils/stream.js +109 -0
  38. package/dist/utils/testing/index.cjs +14 -1
  39. package/dist/utils/testing/index.d.ts +5 -0
  40. package/dist/utils/testing/index.js +14 -1
  41. package/package.json +1 -1
@@ -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];
@@ -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>, variableName: Extract<keyof RunInput, string>): input is BaseMessage[];
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
  /**
@@ -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];
@@ -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.getCallbackMangerForConfig)(options);
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.getCallbackMangerForConfig));
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.getCallbackMangerForConfig)(options);
205
- let runManager;
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 inputGenerator) {
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 = finalInput.concat(chunk);
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(wrappedInputGenerator, runManager, options);
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 = finalOutput.concat(chunk);
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 = finalChunk.concat(chunk);
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
- return this.constructor({
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
- return this.constructor({
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
- return this.constructor({
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.getCallbackMangerForConfig)(options);
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.getCallbackMangerForConfig));
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.getCallbackMangerForConfig)(options);
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 = finalOutput.concat(chunk);
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.getCallbackMangerForConfig)(options);
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
- output = await output.invoke(input, this._patchConfig(config, runManager?.getChild()));
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;