@langchain/core 0.1.49 → 0.1.51

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.
@@ -165,16 +165,22 @@ class Runnable extends serializable_js_1.Serializable {
165
165
  await wrappedGenerator.setup;
166
166
  return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
167
167
  }
168
- _separateRunnableConfigFromCallOptions(options = {}) {
169
- const runnableConfig = (0, config_js_1.ensureConfig)({
170
- callbacks: options.callbacks,
171
- tags: options.tags,
172
- metadata: options.metadata,
173
- runName: options.runName,
174
- configurable: options.configurable,
175
- recursionLimit: options.recursionLimit,
176
- maxConcurrency: options.maxConcurrency,
177
- });
168
+ _separateRunnableConfigFromCallOptions(options) {
169
+ let runnableConfig;
170
+ if (options === undefined) {
171
+ runnableConfig = (0, config_js_1.ensureConfig)(options);
172
+ }
173
+ else {
174
+ runnableConfig = (0, config_js_1.ensureConfig)({
175
+ callbacks: options.callbacks,
176
+ tags: options.tags,
177
+ metadata: options.metadata,
178
+ runName: options.runName,
179
+ configurable: options.configurable,
180
+ recursionLimit: options.recursionLimit,
181
+ maxConcurrency: options.maxConcurrency,
182
+ });
183
+ }
178
184
  const callOptions = { ...options };
179
185
  delete callOptions.callbacks;
180
186
  delete callOptions.tags;
@@ -158,16 +158,22 @@ export class Runnable extends Serializable {
158
158
  await wrappedGenerator.setup;
159
159
  return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
160
160
  }
161
- _separateRunnableConfigFromCallOptions(options = {}) {
162
- const runnableConfig = ensureConfig({
163
- callbacks: options.callbacks,
164
- tags: options.tags,
165
- metadata: options.metadata,
166
- runName: options.runName,
167
- configurable: options.configurable,
168
- recursionLimit: options.recursionLimit,
169
- maxConcurrency: options.maxConcurrency,
170
- });
161
+ _separateRunnableConfigFromCallOptions(options) {
162
+ let runnableConfig;
163
+ if (options === undefined) {
164
+ runnableConfig = ensureConfig(options);
165
+ }
166
+ else {
167
+ runnableConfig = ensureConfig({
168
+ callbacks: options.callbacks,
169
+ tags: options.tags,
170
+ metadata: options.metadata,
171
+ runName: options.runName,
172
+ configurable: options.configurable,
173
+ recursionLimit: options.recursionLimit,
174
+ maxConcurrency: options.maxConcurrency,
175
+ });
176
+ }
171
177
  const callOptions = { ...options };
172
178
  delete callOptions.callbacks;
173
179
  delete callOptions.tags;
@@ -84,6 +84,9 @@ exports.mergeConfigs = mergeConfigs;
84
84
  const PRIMITIVES = new Set(["string", "number", "boolean"]);
85
85
  /**
86
86
  * Ensure that a passed config is an object with all required keys present.
87
+ *
88
+ * Note: To make sure async local storage loading works correctly, this
89
+ * should not be called with a default or prepopulated config argument.
87
90
  */
88
91
  function ensureConfig(config) {
89
92
  const loadedConfig = config ?? index_js_1.AsyncLocalStorageProviderSingleton.getInstance().getStore();
@@ -17,6 +17,9 @@ export declare function getCallbackManagerForConfig(config?: RunnableConfig): Pr
17
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
+ *
21
+ * Note: To make sure async local storage loading works correctly, this
22
+ * should not be called with a default or prepopulated config argument.
20
23
  */
21
24
  export declare function ensureConfig<CallOptions extends RunnableConfig>(config?: CallOptions): CallOptions;
22
25
  /**
@@ -79,6 +79,9 @@ export function mergeConfigs(...configs) {
79
79
  const PRIMITIVES = new Set(["string", "number", "boolean"]);
80
80
  /**
81
81
  * Ensure that a passed config is an object with all required keys present.
82
+ *
83
+ * Note: To make sure async local storage loading works correctly, this
84
+ * should not be called with a default or prepopulated config argument.
82
85
  */
83
86
  export function ensureConfig(config) {
84
87
  const loadedConfig = config ?? AsyncLocalStorageProviderSingleton.getInstance().getStore();
@@ -268,6 +268,9 @@ class RemoteRunnable extends base_js_1.Runnable {
268
268
  config: removeCallbacks(config),
269
269
  kwargs: kwargs ?? {},
270
270
  });
271
+ if (!response.ok) {
272
+ throw new Error(`${response.status} Error: ${await response.text()}`);
273
+ }
271
274
  return revive((await response.json()).output);
272
275
  }
273
276
  async _batch(inputs, options, _, batchOptions) {
@@ -286,6 +289,9 @@ class RemoteRunnable extends base_js_1.Runnable {
286
289
  .map((config) => ({ ...config, ...batchOptions })),
287
290
  kwargs,
288
291
  });
292
+ if (!response.ok) {
293
+ throw new Error(`${response.status} Error: ${await response.text()}`);
294
+ }
289
295
  const body = await response.json();
290
296
  if (!body.output)
291
297
  throw new Error("Invalid response from remote runnable");
@@ -315,21 +321,13 @@ class RemoteRunnable extends base_js_1.Runnable {
315
321
  if (!body) {
316
322
  throw new Error("Could not begin remote stream. Please check the given URL and try again.");
317
323
  }
318
- const stream = new ReadableStream({
319
- async start(controller) {
320
- const enqueueLine = (0, event_source_parse_js_1.getMessages)((msg) => {
321
- if (msg.data)
322
- controller.enqueue(deserialize(msg.data));
323
- });
324
- const onLine = (line, fieldLength, flush) => {
325
- enqueueLine(line, fieldLength, flush);
326
- if (flush)
327
- controller.close();
328
- };
329
- await (0, event_source_parse_js_1.getBytes)(body, (0, event_source_parse_js_1.getLines)(onLine));
330
- },
331
- });
332
- return stream_js_1.IterableReadableStream.fromReadableStream(stream);
324
+ const runnableStream = (0, event_source_parse_js_1.convertEventStreamToIterableReadableDataStream)(body);
325
+ async function* wrapper() {
326
+ for await (const chunk of runnableStream) {
327
+ yield deserialize(chunk);
328
+ }
329
+ }
330
+ return stream_js_1.IterableReadableStream.fromAsyncGenerator(wrapper());
333
331
  }
334
332
  async *streamLog(input, options, streamOptions) {
335
333
  const [config, kwargs] = this._separateRunnableConfigFromCallOptions(options);
@@ -365,7 +363,10 @@ class RemoteRunnable extends base_js_1.Runnable {
365
363
  ...camelCaseStreamOptions,
366
364
  diff: false,
367
365
  });
368
- const { body } = response;
366
+ const { body, ok } = response;
367
+ if (!ok) {
368
+ throw new Error(`${response.status} Error: ${await response.text()}`);
369
+ }
369
370
  if (!body) {
370
371
  throw new Error("Could not begin remote stream log. Please check the given URL and try again.");
371
372
  }
@@ -375,5 +376,46 @@ class RemoteRunnable extends base_js_1.Runnable {
375
376
  yield new log_stream_js_1.RunLogPatch({ ops: chunk.ops });
376
377
  }
377
378
  }
379
+ async *streamEvents(input, options, streamOptions) {
380
+ if (options?.version !== "v1") {
381
+ throw new Error(`Only version "v1" of the events schema is currently supported.`);
382
+ }
383
+ const [config, kwargs] = this._separateRunnableConfigFromCallOptions(options);
384
+ // The type is in camelCase but the API only accepts snake_case.
385
+ const camelCaseStreamOptions = {
386
+ include_names: streamOptions?.includeNames,
387
+ include_types: streamOptions?.includeTypes,
388
+ include_tags: streamOptions?.includeTags,
389
+ exclude_names: streamOptions?.excludeNames,
390
+ exclude_types: streamOptions?.excludeTypes,
391
+ exclude_tags: streamOptions?.excludeTags,
392
+ };
393
+ const response = await this.post("/stream_events", {
394
+ input,
395
+ config: removeCallbacks(config),
396
+ kwargs,
397
+ ...camelCaseStreamOptions,
398
+ diff: false,
399
+ });
400
+ const { body, ok } = response;
401
+ if (!ok) {
402
+ throw new Error(`${response.status} Error: ${await response.text()}`);
403
+ }
404
+ if (!body) {
405
+ throw new Error("Could not begin remote stream events. Please check the given URL and try again.");
406
+ }
407
+ const runnableStream = (0, event_source_parse_js_1.convertEventStreamToIterableReadableDataStream)(body);
408
+ for await (const log of runnableStream) {
409
+ const chunk = revive(JSON.parse(log));
410
+ yield {
411
+ event: chunk.event,
412
+ name: chunk.name,
413
+ run_id: chunk.run_id,
414
+ tags: chunk.tags,
415
+ metadata: chunk.metadata,
416
+ data: chunk.data,
417
+ };
418
+ }
419
+ }
378
420
  }
379
421
  exports.RemoteRunnable = RemoteRunnable;
@@ -1,7 +1,7 @@
1
1
  import { Runnable, RunnableBatchOptions } from "./base.js";
2
2
  import type { RunnableConfig } from "./config.js";
3
3
  import { CallbackManagerForChainRun } from "../callbacks/manager.js";
4
- import { RunLogPatch, type LogStreamCallbackHandlerInput } from "../tracers/log_stream.js";
4
+ import { RunLogPatch, type LogStreamCallbackHandlerInput, type StreamEvent } from "../tracers/log_stream.js";
5
5
  import { IterableReadableStream } from "../utils/stream.js";
6
6
  type RemoteRunnableOptions = {
7
7
  timeout?: number;
@@ -27,5 +27,8 @@ export declare class RemoteRunnable<RunInput, RunOutput, CallOptions extends Run
27
27
  batch(inputs: RunInput[], options?: Partial<CallOptions> | Partial<CallOptions>[], batchOptions?: RunnableBatchOptions): Promise<(RunOutput | Error)[]>;
28
28
  stream(input: RunInput, options?: Partial<CallOptions>): Promise<IterableReadableStream<RunOutput>>;
29
29
  streamLog(input: RunInput, options?: Partial<CallOptions>, streamOptions?: Omit<LogStreamCallbackHandlerInput, "autoClose">): AsyncGenerator<RunLogPatch>;
30
+ streamEvents(input: RunInput, options: Partial<CallOptions> & {
31
+ version: "v1";
32
+ }, streamOptions?: Omit<LogStreamCallbackHandlerInput, "autoClose">): AsyncGenerator<StreamEvent>;
30
33
  }
31
34
  export {};
@@ -4,7 +4,7 @@ import { ChatPromptValue, StringPromptValue } from "../prompt_values.js";
4
4
  import { LogStreamCallbackHandler, RunLogPatch, } from "../tracers/log_stream.js";
5
5
  import { AIMessage, AIMessageChunk, ChatMessage, ChatMessageChunk, FunctionMessage, FunctionMessageChunk, HumanMessage, HumanMessageChunk, SystemMessage, SystemMessageChunk, ToolMessage, ToolMessageChunk, isBaseMessage, } from "../messages/index.js";
6
6
  import { GenerationChunk, ChatGenerationChunk, RUN_KEY } from "../outputs.js";
7
- import { getBytes, getLines, getMessages, convertEventStreamToIterableReadableDataStream, } from "../utils/event_source_parse.js";
7
+ import { convertEventStreamToIterableReadableDataStream } from "../utils/event_source_parse.js";
8
8
  import { IterableReadableStream } from "../utils/stream.js";
9
9
  function isSuperset(set, subset) {
10
10
  for (const elem of subset) {
@@ -265,6 +265,9 @@ export class RemoteRunnable extends Runnable {
265
265
  config: removeCallbacks(config),
266
266
  kwargs: kwargs ?? {},
267
267
  });
268
+ if (!response.ok) {
269
+ throw new Error(`${response.status} Error: ${await response.text()}`);
270
+ }
268
271
  return revive((await response.json()).output);
269
272
  }
270
273
  async _batch(inputs, options, _, batchOptions) {
@@ -283,6 +286,9 @@ export class RemoteRunnable extends Runnable {
283
286
  .map((config) => ({ ...config, ...batchOptions })),
284
287
  kwargs,
285
288
  });
289
+ if (!response.ok) {
290
+ throw new Error(`${response.status} Error: ${await response.text()}`);
291
+ }
286
292
  const body = await response.json();
287
293
  if (!body.output)
288
294
  throw new Error("Invalid response from remote runnable");
@@ -312,21 +318,13 @@ export class RemoteRunnable extends Runnable {
312
318
  if (!body) {
313
319
  throw new Error("Could not begin remote stream. Please check the given URL and try again.");
314
320
  }
315
- const stream = new ReadableStream({
316
- async start(controller) {
317
- const enqueueLine = getMessages((msg) => {
318
- if (msg.data)
319
- controller.enqueue(deserialize(msg.data));
320
- });
321
- const onLine = (line, fieldLength, flush) => {
322
- enqueueLine(line, fieldLength, flush);
323
- if (flush)
324
- controller.close();
325
- };
326
- await getBytes(body, getLines(onLine));
327
- },
328
- });
329
- return IterableReadableStream.fromReadableStream(stream);
321
+ const runnableStream = convertEventStreamToIterableReadableDataStream(body);
322
+ async function* wrapper() {
323
+ for await (const chunk of runnableStream) {
324
+ yield deserialize(chunk);
325
+ }
326
+ }
327
+ return IterableReadableStream.fromAsyncGenerator(wrapper());
330
328
  }
331
329
  async *streamLog(input, options, streamOptions) {
332
330
  const [config, kwargs] = this._separateRunnableConfigFromCallOptions(options);
@@ -362,7 +360,10 @@ export class RemoteRunnable extends Runnable {
362
360
  ...camelCaseStreamOptions,
363
361
  diff: false,
364
362
  });
365
- const { body } = response;
363
+ const { body, ok } = response;
364
+ if (!ok) {
365
+ throw new Error(`${response.status} Error: ${await response.text()}`);
366
+ }
366
367
  if (!body) {
367
368
  throw new Error("Could not begin remote stream log. Please check the given URL and try again.");
368
369
  }
@@ -372,4 +373,45 @@ export class RemoteRunnable extends Runnable {
372
373
  yield new RunLogPatch({ ops: chunk.ops });
373
374
  }
374
375
  }
376
+ async *streamEvents(input, options, streamOptions) {
377
+ if (options?.version !== "v1") {
378
+ throw new Error(`Only version "v1" of the events schema is currently supported.`);
379
+ }
380
+ const [config, kwargs] = this._separateRunnableConfigFromCallOptions(options);
381
+ // The type is in camelCase but the API only accepts snake_case.
382
+ const camelCaseStreamOptions = {
383
+ include_names: streamOptions?.includeNames,
384
+ include_types: streamOptions?.includeTypes,
385
+ include_tags: streamOptions?.includeTags,
386
+ exclude_names: streamOptions?.excludeNames,
387
+ exclude_types: streamOptions?.excludeTypes,
388
+ exclude_tags: streamOptions?.excludeTags,
389
+ };
390
+ const response = await this.post("/stream_events", {
391
+ input,
392
+ config: removeCallbacks(config),
393
+ kwargs,
394
+ ...camelCaseStreamOptions,
395
+ diff: false,
396
+ });
397
+ const { body, ok } = response;
398
+ if (!ok) {
399
+ throw new Error(`${response.status} Error: ${await response.text()}`);
400
+ }
401
+ if (!body) {
402
+ throw new Error("Could not begin remote stream events. Please check the given URL and try again.");
403
+ }
404
+ const runnableStream = convertEventStreamToIterableReadableDataStream(body);
405
+ for await (const log of runnableStream) {
406
+ const chunk = revive(JSON.parse(log));
407
+ yield {
408
+ event: chunk.event,
409
+ name: chunk.name,
410
+ run_id: chunk.run_id,
411
+ tags: chunk.tags,
412
+ metadata: chunk.metadata,
413
+ data: chunk.data,
414
+ };
415
+ }
416
+ }
375
417
  }
@@ -184,12 +184,20 @@ function newMessage() {
184
184
  retry: undefined,
185
185
  };
186
186
  }
187
- function convertEventStreamToIterableReadableDataStream(stream) {
187
+ function convertEventStreamToIterableReadableDataStream(stream, onMetadataEvent) {
188
188
  const dataStream = new ReadableStream({
189
189
  async start(controller) {
190
190
  const enqueueLine = getMessages((msg) => {
191
- if (msg.data)
192
- controller.enqueue(msg.data);
191
+ if (msg.event === "error") {
192
+ throw new Error(msg.data ?? "Unspecified event streaming error.");
193
+ }
194
+ else if (msg.event === "metadata") {
195
+ onMetadataEvent?.(msg);
196
+ }
197
+ else {
198
+ if (msg.data)
199
+ controller.enqueue(msg.data);
200
+ }
193
201
  });
194
202
  const onLine = (line, fieldLength, flush) => {
195
203
  enqueueLine(line, fieldLength, flush);
@@ -36,4 +36,4 @@ export declare function getLines(onLine: (line: Uint8Array, fieldLength: number,
36
36
  * @returns A function that should be called for each incoming line buffer.
37
37
  */
38
38
  export declare function getMessages(onMessage?: (msg: EventSourceMessage) => void, onId?: (id: string) => void, onRetry?: (retry: number) => void): (line: Uint8Array, fieldLength: number, flush?: boolean) => void;
39
- export declare function convertEventStreamToIterableReadableDataStream(stream: ReadableStream): IterableReadableStream<any>;
39
+ export declare function convertEventStreamToIterableReadableDataStream(stream: ReadableStream, onMetadataEvent?: (e: unknown) => unknown): IterableReadableStream<any>;
@@ -178,12 +178,20 @@ function newMessage() {
178
178
  retry: undefined,
179
179
  };
180
180
  }
181
- export function convertEventStreamToIterableReadableDataStream(stream) {
181
+ export function convertEventStreamToIterableReadableDataStream(stream, onMetadataEvent) {
182
182
  const dataStream = new ReadableStream({
183
183
  async start(controller) {
184
184
  const enqueueLine = getMessages((msg) => {
185
- if (msg.data)
186
- controller.enqueue(msg.data);
185
+ if (msg.event === "error") {
186
+ throw new Error(msg.data ?? "Unspecified event streaming error.");
187
+ }
188
+ else if (msg.event === "metadata") {
189
+ onMetadataEvent?.(msg);
190
+ }
191
+ else {
192
+ if (msg.data)
193
+ controller.enqueue(msg.data);
194
+ }
187
195
  });
188
196
  const onLine = (line, fieldLength, flush) => {
189
197
  enqueueLine(line, fieldLength, flush);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {
@@ -14,7 +14,8 @@
14
14
  },
15
15
  "homepage": "https://github.com/langchain-ai/langchainjs/tree/main/langchain-core/",
16
16
  "scripts": {
17
- "build": "yarn clean && yarn build:esm && yarn build:cjs && yarn run build:scripts",
17
+ "build": "yarn build:deps && yarn clean && yarn build:esm && yarn build:cjs && yarn run build:scripts",
18
+ "build:deps": "yarn turbo:command build --filter=@langchain/scripts",
18
19
  "build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/ && rimraf dist/tests dist/**/tests",
19
20
  "build:cjs": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist-cjs/ -p tsconfig.cjs.json && yarn move-cjs-to-dist && rimraf dist-cjs",
20
21
  "build:watch": "yarn create-entrypoints && tsc --outDir dist/ --watch",