@langchain/core 0.1.15 → 0.1.17-rc.0

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.traceAsGroup = exports.TraceGroup = exports.CallbackManager = exports.CallbackManagerForToolRun = exports.CallbackManagerForChainRun = exports.CallbackManagerForLLMRun = exports.CallbackManagerForRetrieverRun = exports.BaseCallbackManager = exports.parseCallbackConfigArg = void 0;
3
+ exports.traceAsGroup = exports.TraceGroup = exports.ensureHandler = exports.CallbackManager = exports.CallbackManagerForToolRun = exports.CallbackManagerForChainRun = exports.CallbackManagerForLLMRun = exports.CallbackManagerForRetrieverRun = exports.BaseCallbackManager = exports.parseCallbackConfigArg = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const base_js_1 = require("./base.cjs");
6
6
  const console_js_1 = require("../tracers/console.cjs");
@@ -571,6 +571,7 @@ function ensureHandler(handler) {
571
571
  }
572
572
  return base_js_1.BaseCallbackHandler.fromMethods(handler);
573
573
  }
574
+ exports.ensureHandler = ensureHandler;
574
575
  /**
575
576
  * @example
576
577
  * ```typescript
@@ -115,7 +115,7 @@ export declare class CallbackManager extends BaseCallbackManager implements Base
115
115
  metadata: Record<string, unknown>;
116
116
  inheritableMetadata: Record<string, unknown>;
117
117
  name: string;
118
- private readonly _parentRunId?;
118
+ readonly _parentRunId?: string;
119
119
  constructor(parentRunId?: string, options?: {
120
120
  handlers?: BaseCallbackHandler[];
121
121
  inheritableHandlers?: BaseCallbackHandler[];
@@ -140,6 +140,7 @@ export declare class CallbackManager extends BaseCallbackManager implements Base
140
140
  static fromHandlers(handlers: CallbackHandlerMethods): CallbackManager;
141
141
  static configure(inheritableHandlers?: Callbacks, localHandlers?: Callbacks, inheritableTags?: string[], localTags?: string[], inheritableMetadata?: Record<string, unknown>, localMetadata?: Record<string, unknown>, options?: CallbackManagerOptions): Promise<CallbackManager | undefined>;
142
142
  }
143
+ export declare function ensureHandler(handler: BaseCallbackHandler | CallbackHandlerMethods): BaseCallbackHandler;
143
144
  /**
144
145
  * @example
145
146
  * ```typescript
@@ -555,7 +555,7 @@ export class CallbackManager extends BaseCallbackManager {
555
555
  return callbackManager;
556
556
  }
557
557
  }
558
- function ensureHandler(handler) {
558
+ export function ensureHandler(handler) {
559
559
  if ("name" in handler) {
560
560
  return handler;
561
561
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseRetriever = void 0;
4
4
  const manager_js_1 = require("./callbacks/manager.cjs");
5
5
  const base_js_1 = require("./runnables/base.cjs");
6
+ const config_js_1 = require("./runnables/config.cjs");
6
7
  /**
7
8
  * Abstract base class for a Document retrieval system. A retrieval system
8
9
  * is defined as something that can take string queries and return the
@@ -62,7 +63,7 @@ class BaseRetriever extends base_js_1.Runnable {
62
63
  * @returns A promise that resolves to an array of `Document` objects.
63
64
  */
64
65
  async getRelevantDocuments(query, config) {
65
- const parsedConfig = (0, manager_js_1.parseCallbackConfigArg)(config);
66
+ const parsedConfig = (0, config_js_1.ensureConfig)((0, manager_js_1.parseCallbackConfigArg)(config));
66
67
  const callbackManager_ = await manager_js_1.CallbackManager.configure(parsedConfig.callbacks, this.callbacks, parsedConfig.tags, this.tags, parsedConfig.metadata, this.metadata, { verbose: this.verbose });
67
68
  const runManager = await callbackManager_?.handleRetrieverStart(this.toJSON(), query, undefined, undefined, undefined, undefined, parsedConfig.runName);
68
69
  try {
@@ -1,5 +1,6 @@
1
1
  import { CallbackManager, parseCallbackConfigArg, } from "./callbacks/manager.js";
2
2
  import { Runnable } from "./runnables/base.js";
3
+ import { ensureConfig } from "./runnables/config.js";
3
4
  /**
4
5
  * Abstract base class for a Document retrieval system. A retrieval system
5
6
  * is defined as something that can take string queries and return the
@@ -59,7 +60,7 @@ export class BaseRetriever extends Runnable {
59
60
  * @returns A promise that resolves to an array of `Document` objects.
60
61
  */
61
62
  async getRelevantDocuments(query, config) {
62
- const parsedConfig = parseCallbackConfigArg(config);
63
+ const parsedConfig = ensureConfig(parseCallbackConfigArg(config));
63
64
  const callbackManager_ = await CallbackManager.configure(parsedConfig.callbacks, this.callbacks, parsedConfig.tags, this.tags, parsedConfig.metadata, this.metadata, { verbose: this.verbose });
64
65
  const runManager = await callbackManager_?.handleRetrieverStart(this.toJSON(), query, undefined, undefined, undefined, undefined, parsedConfig.runName);
65
66
  try {
@@ -111,9 +111,9 @@ class Runnable extends serializable_js_1.Serializable {
111
111
  if (options.length !== length) {
112
112
  throw new Error(`Passed "options" must be an array with the same length as the inputs, but got ${options.length} options for ${length} inputs`);
113
113
  }
114
- return options;
114
+ return options.map(config_js_1.ensureConfig);
115
115
  }
116
- return Array.from({ length }, () => options);
116
+ return Array.from({ length }, () => (0, config_js_1.ensureConfig)(options));
117
117
  }
118
118
  async batch(inputs, options, batchOptions) {
119
119
  const configList = this._getOptionsList(options ?? {}, inputs.length);
@@ -154,30 +154,39 @@ class Runnable extends serializable_js_1.Serializable {
154
154
  * @returns A readable stream that is also an iterable.
155
155
  */
156
156
  async stream(input, options) {
157
- return stream_js_1.IterableReadableStream.fromAsyncGenerator(this._streamIterator(input, options));
157
+ // Buffer the first streamed chunk to allow for initial errors
158
+ // to surface immediately.
159
+ const wrappedGenerator = new stream_js_1.AsyncGeneratorWithSetup(this._streamIterator(input, options));
160
+ await wrappedGenerator.setup;
161
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
158
162
  }
159
163
  _separateRunnableConfigFromCallOptions(options = {}) {
160
- const runnableConfig = {
164
+ const runnableConfig = (0, config_js_1.ensureConfig)({
161
165
  callbacks: options.callbacks,
162
166
  tags: options.tags,
163
167
  metadata: options.metadata,
164
168
  runName: options.runName,
165
169
  configurable: options.configurable,
166
- };
170
+ recursionLimit: options.recursionLimit,
171
+ maxConcurrency: options.maxConcurrency,
172
+ });
167
173
  const callOptions = { ...options };
168
174
  delete callOptions.callbacks;
169
175
  delete callOptions.tags;
170
176
  delete callOptions.metadata;
171
177
  delete callOptions.runName;
172
178
  delete callOptions.configurable;
179
+ delete callOptions.recursionLimit;
180
+ delete callOptions.maxConcurrency;
173
181
  return [runnableConfig, callOptions];
174
182
  }
175
183
  async _callWithConfig(func, input, options) {
176
- const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
177
- const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName());
184
+ const config = (0, config_js_1.ensureConfig)(options);
185
+ const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(config);
186
+ const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, config?.runType, undefined, undefined, config?.runName ?? this.getName());
178
187
  let output;
179
188
  try {
180
- output = await func.bind(this)(input, options, runManager);
189
+ output = await func.call(this, input, config, runManager);
181
190
  }
182
191
  catch (e) {
183
192
  await runManager?.handleChainError(e);
@@ -201,7 +210,7 @@ class Runnable extends serializable_js_1.Serializable {
201
210
  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())));
202
211
  let outputs;
203
212
  try {
204
- outputs = await func(inputs, optionsList, runManagers, batchOptions);
213
+ outputs = await func.call(this, inputs, optionsList, runManagers, batchOptions);
205
214
  }
206
215
  catch (e) {
207
216
  await Promise.all(runManagers.map((runManager) => runManager?.handleChainError(e)));
@@ -220,7 +229,8 @@ class Runnable extends serializable_js_1.Serializable {
220
229
  let finalInputSupported = true;
221
230
  let finalOutput;
222
231
  let finalOutputSupported = true;
223
- const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(options);
232
+ const config = (0, config_js_1.ensureConfig)(options);
233
+ const callbackManager_ = await (0, config_js_1.getCallbackManagerForConfig)(config);
224
234
  async function* wrapInputForTracing() {
225
235
  for await (const chunk of inputGenerator) {
226
236
  if (finalInputSupported) {
@@ -243,7 +253,7 @@ class Runnable extends serializable_js_1.Serializable {
243
253
  }
244
254
  let runManager;
245
255
  try {
246
- const pipe = await (0, stream_js_1.pipeGeneratorWithSetup)(transformer, wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName()), options);
256
+ const pipe = await (0, stream_js_1.pipeGeneratorWithSetup)(transformer.bind(this), wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, undefined, config?.runType, undefined, undefined, config?.runName ?? this.getName()), config);
247
257
  runManager = pipe.setup;
248
258
  const isLogStreamHandler = (handler) => handler.name === "log_stream_tracer";
249
259
  const streamLogHandler = runManager?.handlers.find(isLogStreamHandler);
@@ -346,7 +356,7 @@ class Runnable extends serializable_js_1.Serializable {
346
356
  ...streamOptions,
347
357
  autoClose: false,
348
358
  });
349
- const config = options ?? {};
359
+ const config = (0, config_js_1.ensureConfig)(options);
350
360
  const { callbacks } = config;
351
361
  if (callbacks === undefined) {
352
362
  config.callbacks = [stream];
@@ -478,10 +488,8 @@ class RunnableBinding extends Runnable {
478
488
  getName(suffix) {
479
489
  return this.bound.getName(suffix);
480
490
  }
481
- async _mergeConfig(
482
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
483
- options) {
484
- const config = (0, config_js_1.mergeConfigs)(this.config, options);
491
+ async _mergeConfig(...options) {
492
+ const config = (0, config_js_1.mergeConfigs)(this.config, ...options);
485
493
  return (0, config_js_1.mergeConfigs)(config, ...(this.configFactories
486
494
  ? await Promise.all(this.configFactories.map(async (configFactory) => await configFactory(config)))
487
495
  : []));
@@ -511,27 +519,24 @@ class RunnableBinding extends Runnable {
511
519
  });
512
520
  }
513
521
  async invoke(input, options) {
514
- return this.bound.invoke(input, await this._mergeConfig({ ...options, ...this.kwargs }));
522
+ return this.bound.invoke(input, await this._mergeConfig(options, this.kwargs));
515
523
  }
516
524
  async batch(inputs, options, batchOptions) {
517
525
  const mergedOptions = Array.isArray(options)
518
- ? await Promise.all(options.map(async (individualOption) => this._mergeConfig({
519
- ...individualOption,
520
- ...this.kwargs,
521
- })))
522
- : await this._mergeConfig({ ...options, ...this.kwargs });
526
+ ? await Promise.all(options.map(async (individualOption) => this._mergeConfig(individualOption, this.kwargs)))
527
+ : await this._mergeConfig(options, this.kwargs);
523
528
  return this.bound.batch(inputs, mergedOptions, batchOptions);
524
529
  }
525
530
  async *_streamIterator(input, options) {
526
- yield* this.bound._streamIterator(input, await this._mergeConfig({ ...options, ...this.kwargs }));
531
+ yield* this.bound._streamIterator(input, await this._mergeConfig(options, this.kwargs));
527
532
  }
528
533
  async stream(input, options) {
529
- return this.bound.stream(input, await this._mergeConfig({ ...options, ...this.kwargs }));
534
+ return this.bound.stream(input, await this._mergeConfig(options, this.kwargs));
530
535
  }
531
536
  async *transform(
532
537
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
533
538
  generator, options) {
534
- yield* this.bound.transform(generator, await this._mergeConfig({ ...options, ...this.kwargs }));
539
+ yield* this.bound.transform(generator, await this._mergeConfig(options, this.kwargs));
535
540
  }
536
541
  static isRunnableBinding(
537
542
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1042,7 +1047,9 @@ class RunnableMap extends Runnable {
1042
1047
  async function* generator() {
1043
1048
  yield input;
1044
1049
  }
1045
- return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1050
+ const wrappedGenerator = new stream_js_1.AsyncGeneratorWithSetup(this.transform(generator(), options));
1051
+ await wrappedGenerator.setup;
1052
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1046
1053
  }
1047
1054
  }
1048
1055
  exports.RunnableMap = RunnableMap;
@@ -1131,7 +1138,9 @@ class RunnableLambda extends Runnable {
1131
1138
  async function* generator() {
1132
1139
  yield input;
1133
1140
  }
1134
- return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1141
+ const wrappedGenerator = new stream_js_1.AsyncGeneratorWithSetup(this.transform(generator(), options));
1142
+ await wrappedGenerator.setup;
1143
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1135
1144
  }
1136
1145
  }
1137
1146
  exports.RunnableLambda = RunnableLambda;
@@ -1328,7 +1337,9 @@ class RunnableAssign extends Runnable {
1328
1337
  async function* generator() {
1329
1338
  yield input;
1330
1339
  }
1331
- return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1340
+ const wrappedGenerator = new stream_js_1.AsyncGeneratorWithSetup(this.transform(generator(), options));
1341
+ await wrappedGenerator.setup;
1342
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1332
1343
  }
1333
1344
  }
1334
1345
  exports.RunnableAssign = RunnableAssign;
@@ -1394,7 +1405,9 @@ class RunnablePick extends Runnable {
1394
1405
  async function* generator() {
1395
1406
  yield input;
1396
1407
  }
1397
- return stream_js_1.IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1408
+ const wrappedGenerator = new stream_js_1.AsyncGeneratorWithSetup(this.transform(generator(), options));
1409
+ await wrappedGenerator.setup;
1410
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1398
1411
  }
1399
1412
  }
1400
1413
  exports.RunnablePick = RunnablePick;
@@ -82,9 +82,9 @@ export declare abstract class Runnable<RunInput = any, RunOutput = any, CallOpti
82
82
  withFallbacks(fields: {
83
83
  fallbacks: Runnable<RunInput, RunOutput>[];
84
84
  }): RunnableWithFallbacks<RunInput, RunOutput>;
85
- protected _getOptionsList(options: Partial<CallOptions> | Partial<CallOptions>[], length?: number): Partial<CallOptions & {
85
+ protected _getOptionsList<O extends CallOptions & {
86
86
  runType?: string;
87
- }>[];
87
+ }>(options: Partial<O> | Partial<O>[], length?: number): Partial<O>[];
88
88
  /**
89
89
  * Default implementation of batch, which calls invoke N times.
90
90
  * Subclasses should override this method if they can batch more efficiently.
@@ -212,7 +212,7 @@ export declare class RunnableBinding<RunInput, RunOutput, CallOptions extends Ru
212
212
  configFactories?: Array<(config: RunnableConfig) => RunnableConfig | Promise<RunnableConfig>>;
213
213
  constructor(fields: RunnableBindingArgs<RunInput, RunOutput, CallOptions>);
214
214
  getName(suffix?: string | undefined): string;
215
- _mergeConfig(options?: Record<string, any>): Promise<Partial<CallOptions>>;
215
+ _mergeConfig(...options: (Partial<CallOptions> | RunnableConfig | undefined)[]): Promise<Partial<CallOptions>>;
216
216
  bind(kwargs: Partial<CallOptions>): RunnableBinding<RunInput, RunOutput, CallOptions>;
217
217
  withConfig(config: RunnableConfig): RunnableBinding<RunInput, RunOutput, CallOptions>;
218
218
  withRetry(fields?: {
@@ -2,8 +2,8 @@ import pRetry from "p-retry";
2
2
  import { CallbackManager, } from "../callbacks/manager.js";
3
3
  import { LogStreamCallbackHandler, RunLogPatch, } from "../tracers/log_stream.js";
4
4
  import { Serializable } from "../load/serializable.js";
5
- import { IterableReadableStream, concat, atee, pipeGeneratorWithSetup, } from "../utils/stream.js";
6
- import { DEFAULT_RECURSION_LIMIT, getCallbackManagerForConfig, mergeConfigs, patchConfig, } from "./config.js";
5
+ import { IterableReadableStream, concat, atee, pipeGeneratorWithSetup, AsyncGeneratorWithSetup, } from "../utils/stream.js";
6
+ import { DEFAULT_RECURSION_LIMIT, ensureConfig, getCallbackManagerForConfig, mergeConfigs, patchConfig, } from "./config.js";
7
7
  import { AsyncCaller } from "../utils/async_caller.js";
8
8
  import { RootListenersTracer } from "../tracers/root_listener.js";
9
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -105,9 +105,9 @@ export class Runnable extends Serializable {
105
105
  if (options.length !== length) {
106
106
  throw new Error(`Passed "options" must be an array with the same length as the inputs, but got ${options.length} options for ${length} inputs`);
107
107
  }
108
- return options;
108
+ return options.map(ensureConfig);
109
109
  }
110
- return Array.from({ length }, () => options);
110
+ return Array.from({ length }, () => ensureConfig(options));
111
111
  }
112
112
  async batch(inputs, options, batchOptions) {
113
113
  const configList = this._getOptionsList(options ?? {}, inputs.length);
@@ -148,30 +148,39 @@ export class Runnable extends Serializable {
148
148
  * @returns A readable stream that is also an iterable.
149
149
  */
150
150
  async stream(input, options) {
151
- return IterableReadableStream.fromAsyncGenerator(this._streamIterator(input, options));
151
+ // Buffer the first streamed chunk to allow for initial errors
152
+ // to surface immediately.
153
+ const wrappedGenerator = new AsyncGeneratorWithSetup(this._streamIterator(input, options));
154
+ await wrappedGenerator.setup;
155
+ return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
152
156
  }
153
157
  _separateRunnableConfigFromCallOptions(options = {}) {
154
- const runnableConfig = {
158
+ const runnableConfig = ensureConfig({
155
159
  callbacks: options.callbacks,
156
160
  tags: options.tags,
157
161
  metadata: options.metadata,
158
162
  runName: options.runName,
159
163
  configurable: options.configurable,
160
- };
164
+ recursionLimit: options.recursionLimit,
165
+ maxConcurrency: options.maxConcurrency,
166
+ });
161
167
  const callOptions = { ...options };
162
168
  delete callOptions.callbacks;
163
169
  delete callOptions.tags;
164
170
  delete callOptions.metadata;
165
171
  delete callOptions.runName;
166
172
  delete callOptions.configurable;
173
+ delete callOptions.recursionLimit;
174
+ delete callOptions.maxConcurrency;
167
175
  return [runnableConfig, callOptions];
168
176
  }
169
177
  async _callWithConfig(func, input, options) {
170
- const callbackManager_ = await getCallbackManagerForConfig(options);
171
- const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName());
178
+ const config = ensureConfig(options);
179
+ const callbackManager_ = await getCallbackManagerForConfig(config);
180
+ const runManager = await callbackManager_?.handleChainStart(this.toJSON(), _coerceToDict(input, "input"), undefined, config?.runType, undefined, undefined, config?.runName ?? this.getName());
172
181
  let output;
173
182
  try {
174
- output = await func.bind(this)(input, options, runManager);
183
+ output = await func.call(this, input, config, runManager);
175
184
  }
176
185
  catch (e) {
177
186
  await runManager?.handleChainError(e);
@@ -195,7 +204,7 @@ export class Runnable extends Serializable {
195
204
  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())));
196
205
  let outputs;
197
206
  try {
198
- outputs = await func(inputs, optionsList, runManagers, batchOptions);
207
+ outputs = await func.call(this, inputs, optionsList, runManagers, batchOptions);
199
208
  }
200
209
  catch (e) {
201
210
  await Promise.all(runManagers.map((runManager) => runManager?.handleChainError(e)));
@@ -214,7 +223,8 @@ export class Runnable extends Serializable {
214
223
  let finalInputSupported = true;
215
224
  let finalOutput;
216
225
  let finalOutputSupported = true;
217
- const callbackManager_ = await getCallbackManagerForConfig(options);
226
+ const config = ensureConfig(options);
227
+ const callbackManager_ = await getCallbackManagerForConfig(config);
218
228
  async function* wrapInputForTracing() {
219
229
  for await (const chunk of inputGenerator) {
220
230
  if (finalInputSupported) {
@@ -237,7 +247,7 @@ export class Runnable extends Serializable {
237
247
  }
238
248
  let runManager;
239
249
  try {
240
- const pipe = await pipeGeneratorWithSetup(transformer, wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, undefined, options?.runType, undefined, undefined, options?.runName ?? this.getName()), options);
250
+ const pipe = await pipeGeneratorWithSetup(transformer.bind(this), wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, undefined, config?.runType, undefined, undefined, config?.runName ?? this.getName()), config);
241
251
  runManager = pipe.setup;
242
252
  const isLogStreamHandler = (handler) => handler.name === "log_stream_tracer";
243
253
  const streamLogHandler = runManager?.handlers.find(isLogStreamHandler);
@@ -340,7 +350,7 @@ export class Runnable extends Serializable {
340
350
  ...streamOptions,
341
351
  autoClose: false,
342
352
  });
343
- const config = options ?? {};
353
+ const config = ensureConfig(options);
344
354
  const { callbacks } = config;
345
355
  if (callbacks === undefined) {
346
356
  config.callbacks = [stream];
@@ -471,10 +481,8 @@ export class RunnableBinding extends Runnable {
471
481
  getName(suffix) {
472
482
  return this.bound.getName(suffix);
473
483
  }
474
- async _mergeConfig(
475
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
476
- options) {
477
- const config = mergeConfigs(this.config, options);
484
+ async _mergeConfig(...options) {
485
+ const config = mergeConfigs(this.config, ...options);
478
486
  return mergeConfigs(config, ...(this.configFactories
479
487
  ? await Promise.all(this.configFactories.map(async (configFactory) => await configFactory(config)))
480
488
  : []));
@@ -504,27 +512,24 @@ export class RunnableBinding extends Runnable {
504
512
  });
505
513
  }
506
514
  async invoke(input, options) {
507
- return this.bound.invoke(input, await this._mergeConfig({ ...options, ...this.kwargs }));
515
+ return this.bound.invoke(input, await this._mergeConfig(options, this.kwargs));
508
516
  }
509
517
  async batch(inputs, options, batchOptions) {
510
518
  const mergedOptions = Array.isArray(options)
511
- ? await Promise.all(options.map(async (individualOption) => this._mergeConfig({
512
- ...individualOption,
513
- ...this.kwargs,
514
- })))
515
- : await this._mergeConfig({ ...options, ...this.kwargs });
519
+ ? await Promise.all(options.map(async (individualOption) => this._mergeConfig(individualOption, this.kwargs)))
520
+ : await this._mergeConfig(options, this.kwargs);
516
521
  return this.bound.batch(inputs, mergedOptions, batchOptions);
517
522
  }
518
523
  async *_streamIterator(input, options) {
519
- yield* this.bound._streamIterator(input, await this._mergeConfig({ ...options, ...this.kwargs }));
524
+ yield* this.bound._streamIterator(input, await this._mergeConfig(options, this.kwargs));
520
525
  }
521
526
  async stream(input, options) {
522
- return this.bound.stream(input, await this._mergeConfig({ ...options, ...this.kwargs }));
527
+ return this.bound.stream(input, await this._mergeConfig(options, this.kwargs));
523
528
  }
524
529
  async *transform(
525
530
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
526
531
  generator, options) {
527
- yield* this.bound.transform(generator, await this._mergeConfig({ ...options, ...this.kwargs }));
532
+ yield* this.bound.transform(generator, await this._mergeConfig(options, this.kwargs));
528
533
  }
529
534
  static isRunnableBinding(
530
535
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1031,7 +1036,9 @@ export class RunnableMap extends Runnable {
1031
1036
  async function* generator() {
1032
1037
  yield input;
1033
1038
  }
1034
- return IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1039
+ const wrappedGenerator = new AsyncGeneratorWithSetup(this.transform(generator(), options));
1040
+ await wrappedGenerator.setup;
1041
+ return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1035
1042
  }
1036
1043
  }
1037
1044
  /**
@@ -1119,7 +1126,9 @@ export class RunnableLambda extends Runnable {
1119
1126
  async function* generator() {
1120
1127
  yield input;
1121
1128
  }
1122
- return IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1129
+ const wrappedGenerator = new AsyncGeneratorWithSetup(this.transform(generator(), options));
1130
+ await wrappedGenerator.setup;
1131
+ return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1123
1132
  }
1124
1133
  }
1125
1134
  export class RunnableParallel extends RunnableMap {
@@ -1312,7 +1321,9 @@ export class RunnableAssign extends Runnable {
1312
1321
  async function* generator() {
1313
1322
  yield input;
1314
1323
  }
1315
- return IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1324
+ const wrappedGenerator = new AsyncGeneratorWithSetup(this.transform(generator(), options));
1325
+ await wrappedGenerator.setup;
1326
+ return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1316
1327
  }
1317
1328
  }
1318
1329
  /**
@@ -1377,6 +1388,8 @@ export class RunnablePick extends Runnable {
1377
1388
  async function* generator() {
1378
1389
  yield input;
1379
1390
  }
1380
- return IterableReadableStream.fromAsyncGenerator(this.transform(generator(), options));
1391
+ const wrappedGenerator = new AsyncGeneratorWithSetup(this.transform(generator(), options));
1392
+ await wrappedGenerator.setup;
1393
+ return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
1381
1394
  }
1382
1395
  }
@@ -7,25 +7,23 @@ async function getCallbackManagerForConfig(config) {
7
7
  return manager_js_1.CallbackManager.configure(config?.callbacks, undefined, config?.tags, undefined, config?.metadata);
8
8
  }
9
9
  exports.getCallbackManagerForConfig = getCallbackManagerForConfig;
10
- function mergeConfigs(config,
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- options) {
10
+ function mergeConfigs(...configs) {
13
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- const copy = { ...config };
15
- if (options) {
12
+ const copy = ensureConfig();
13
+ for (const options of configs.filter((c) => !!c)) {
16
14
  for (const key of Object.keys(options)) {
17
15
  if (key === "metadata") {
18
16
  copy[key] = { ...copy[key], ...options[key] };
19
17
  }
20
18
  else if (key === "tags") {
21
- copy[key] = (copy[key] ?? []).concat(options[key] ?? []);
19
+ copy[key] = [...new Set(copy[key].concat(options[key] ?? []))];
22
20
  }
23
21
  else if (key === "configurable") {
24
22
  copy[key] = { ...copy[key], ...options[key] };
25
23
  }
26
24
  else if (key === "callbacks") {
27
25
  const baseCallbacks = copy.callbacks;
28
- const providedCallbacks = options.callbacks ?? config.callbacks;
26
+ const providedCallbacks = options.callbacks;
29
27
  // callbacks can be either undefined, Array<handler> or manager
30
28
  // so merging two callbacks values has 6 cases
31
29
  if (Array.isArray(providedCallbacks)) {
@@ -39,7 +37,7 @@ options) {
39
37
  // baseCallbacks is a manager
40
38
  const manager = baseCallbacks.copy();
41
39
  for (const callback of providedCallbacks) {
42
- manager.addHandler(callback, true);
40
+ manager.addHandler((0, manager_js_1.ensureHandler)(callback), true);
43
41
  }
44
42
  copy.callbacks = manager;
45
43
  }
@@ -52,13 +50,13 @@ options) {
52
50
  else if (Array.isArray(baseCallbacks)) {
53
51
  const manager = providedCallbacks.copy();
54
52
  for (const callback of baseCallbacks) {
55
- manager.addHandler(callback, true);
53
+ manager.addHandler((0, manager_js_1.ensureHandler)(callback), true);
56
54
  }
57
55
  copy.callbacks = manager;
58
56
  }
59
57
  else {
60
58
  // baseCallbacks is also a manager
61
- copy.callbacks = new manager_js_1.CallbackManager(providedCallbacks.parentRunId, {
59
+ copy.callbacks = new manager_js_1.CallbackManager(providedCallbacks._parentRunId, {
62
60
  handlers: baseCallbacks.handlers.concat(providedCallbacks.handlers),
63
61
  inheritableHandlers: baseCallbacks.inheritableHandlers.concat(providedCallbacks.inheritableHandlers),
64
62
  tags: Array.from(new Set(baseCallbacks.tags.concat(providedCallbacks.tags))),
@@ -72,24 +70,40 @@ options) {
72
70
  }
73
71
  }
74
72
  else {
75
- copy[key] = options[key] ?? copy[key];
73
+ const typedKey = key;
74
+ copy[typedKey] = options[typedKey] ?? copy[typedKey];
76
75
  }
77
76
  }
78
77
  }
79
78
  return copy;
80
79
  }
81
80
  exports.mergeConfigs = mergeConfigs;
81
+ const PRIMITIVES = new Set(["string", "number", "boolean"]);
82
82
  /**
83
83
  * Ensure that a passed config is an object with all required keys present.
84
84
  */
85
85
  function ensureConfig(config) {
86
- return {
86
+ let empty = {
87
87
  tags: [],
88
88
  metadata: {},
89
89
  callbacks: undefined,
90
90
  recursionLimit: 25,
91
- ...config,
92
91
  };
92
+ if (config) {
93
+ empty = { ...empty, ...config };
94
+ }
95
+ if (config?.configurable) {
96
+ for (const key of Object.keys(config.configurable)) {
97
+ if (PRIMITIVES.has(typeof config.configurable[key]) &&
98
+ !empty.metadata?.[key]) {
99
+ if (!empty.metadata) {
100
+ empty.metadata = {};
101
+ }
102
+ empty.metadata[key] = config.configurable[key];
103
+ }
104
+ }
105
+ }
106
+ return empty;
93
107
  }
94
108
  exports.ensureConfig = ensureConfig;
95
109
  /**
@@ -14,11 +14,11 @@ export interface RunnableConfig extends BaseCallbackConfig {
14
14
  maxConcurrency?: number;
15
15
  }
16
16
  export declare function getCallbackManagerForConfig(config?: RunnableConfig): Promise<CallbackManager | undefined>;
17
- export declare function mergeConfigs<CallOptions extends RunnableConfig>(config: RunnableConfig, options?: Record<string, any>): Partial<CallOptions>;
17
+ export declare function mergeConfigs<CallOptions extends RunnableConfig>(...configs: (CallOptions | RunnableConfig | undefined | null)[]): Partial<CallOptions>;
18
18
  /**
19
19
  * Ensure that a passed config is an object with all required keys present.
20
20
  */
21
- export declare function ensureConfig<CallOptions extends RunnableConfig>(config?: CallOptions): Partial<CallOptions>;
21
+ export declare function ensureConfig<CallOptions extends RunnableConfig>(config?: CallOptions): CallOptions;
22
22
  /**
23
23
  * Helper function that patches runnable configs with updated properties.
24
24
  */