@langchain/core 0.2.0-rc.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/callbacks/base.cjs +9 -1
- package/dist/callbacks/base.d.ts +3 -0
- package/dist/callbacks/base.js +9 -1
- package/dist/callbacks/manager.cjs +51 -0
- package/dist/callbacks/manager.js +51 -0
- package/dist/callbacks/tests/callbacks.test.d.ts +1 -0
- package/dist/callbacks/tests/callbacks.test.js +492 -0
- package/dist/callbacks/tests/manager.int.test.d.ts +1 -0
- package/dist/callbacks/tests/manager.int.test.js +29 -0
- package/dist/callbacks/tests/run_collector.test.d.ts +1 -0
- package/dist/callbacks/tests/run_collector.test.js +58 -0
- package/dist/chat_history.cjs +13 -0
- package/dist/chat_history.d.ts +9 -0
- package/dist/chat_history.js +13 -0
- package/dist/language_models/base.cjs +3 -0
- package/dist/language_models/base.js +3 -0
- package/dist/language_models/chat_models.cjs +21 -3
- package/dist/language_models/chat_models.d.ts +11 -2
- package/dist/language_models/chat_models.js +21 -3
- package/dist/language_models/tests/chat_models.test.d.ts +1 -0
- package/dist/language_models/tests/chat_models.test.js +154 -0
- package/dist/language_models/tests/count_tokens.test.d.ts +1 -0
- package/dist/language_models/tests/count_tokens.test.js +19 -0
- package/dist/language_models/tests/llms.test.d.ts +1 -0
- package/dist/language_models/tests/llms.test.js +39 -0
- package/dist/messages/tests/base_message.test.d.ts +1 -0
- package/dist/messages/tests/base_message.test.js +97 -0
- package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.d.ts +1 -0
- package/dist/output_parsers/openai_tools/tests/json_output_tools_parser.test.js +81 -0
- package/dist/output_parsers/tests/json.test.d.ts +1 -0
- package/dist/output_parsers/tests/json.test.js +427 -0
- package/dist/output_parsers/tests/output_parser.test.d.ts +1 -0
- package/dist/output_parsers/tests/output_parser.test.js +78 -0
- package/dist/output_parsers/tests/string.test.d.ts +1 -0
- package/dist/output_parsers/tests/string.test.js +68 -0
- package/dist/output_parsers/tests/structured.test.d.ts +1 -0
- package/dist/output_parsers/tests/structured.test.js +166 -0
- package/dist/output_parsers/tests/xml.test.d.ts +1 -0
- package/dist/output_parsers/tests/xml.test.js +81 -0
- package/dist/prompts/tests/chat.mustache.test.d.ts +1 -0
- package/dist/prompts/tests/chat.mustache.test.js +61 -0
- package/dist/prompts/tests/chat.test.d.ts +1 -0
- package/dist/prompts/tests/chat.test.js +507 -0
- package/dist/prompts/tests/few_shot.test.d.ts +1 -0
- package/dist/prompts/tests/few_shot.test.js +224 -0
- package/dist/prompts/tests/pipeline.test.d.ts +1 -0
- package/dist/prompts/tests/pipeline.test.js +101 -0
- package/dist/prompts/tests/prompt.mustache.test.d.ts +1 -0
- package/dist/prompts/tests/prompt.mustache.test.js +85 -0
- package/dist/prompts/tests/prompt.test.d.ts +1 -0
- package/dist/prompts/tests/prompt.test.js +78 -0
- package/dist/prompts/tests/structured.test.d.ts +1 -0
- package/dist/prompts/tests/structured.test.js +37 -0
- package/dist/prompts/tests/template.test.d.ts +1 -0
- package/dist/prompts/tests/template.test.js +24 -0
- package/dist/runnables/base.cjs +174 -19
- package/dist/runnables/base.d.ts +47 -28
- package/dist/runnables/base.js +174 -19
- package/dist/runnables/history.cjs +87 -32
- package/dist/runnables/history.d.ts +1 -1
- package/dist/runnables/history.js +87 -32
- package/dist/runnables/iter.cjs +46 -0
- package/dist/runnables/iter.d.ts +5 -0
- package/dist/runnables/iter.js +39 -0
- package/dist/runnables/passthrough.cjs +1 -0
- package/dist/runnables/passthrough.d.ts +1 -1
- package/dist/runnables/passthrough.js +1 -0
- package/dist/runnables/remote.cjs +60 -48
- package/dist/runnables/remote.d.ts +8 -4
- package/dist/runnables/remote.js +61 -49
- package/dist/runnables/tests/runnable.test.d.ts +1 -0
- package/dist/runnables/tests/runnable.test.js +491 -0
- package/dist/runnables/tests/runnable_binding.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_binding.test.js +46 -0
- package/dist/runnables/tests/runnable_branch.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_branch.test.js +116 -0
- package/dist/runnables/tests/runnable_graph.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_graph.test.js +84 -0
- package/dist/runnables/tests/runnable_history.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_history.test.js +177 -0
- package/dist/runnables/tests/runnable_interface.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_interface.test.js +209 -0
- package/dist/runnables/tests/runnable_map.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_map.test.js +238 -0
- package/dist/runnables/tests/runnable_passthrough.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_passthrough.test.js +96 -0
- package/dist/runnables/tests/runnable_remote.int.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_remote.int.test.js +138 -0
- package/dist/runnables/tests/runnable_remote.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_remote.test.js +200 -0
- package/dist/runnables/tests/runnable_retry.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_retry.test.js +125 -0
- package/dist/runnables/tests/runnable_stream_events.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_stream_events.test.js +1013 -0
- package/dist/runnables/tests/runnable_stream_events_v2.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_stream_events_v2.test.js +973 -0
- package/dist/runnables/tests/runnable_stream_log.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_stream_log.test.js +282 -0
- package/dist/runnables/tests/runnable_tracing.int.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_tracing.int.test.js +37 -0
- package/dist/runnables/tests/runnable_with_fallbacks.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_with_fallbacks.test.js +36 -0
- package/dist/runnables/utils.d.ts +1 -1
- package/dist/singletons/index.cjs +1 -1
- package/dist/singletons/index.d.ts +2 -2
- package/dist/singletons/index.js +1 -1
- package/dist/singletons/tests/async_local_storage.test.d.ts +1 -0
- package/dist/singletons/tests/async_local_storage.test.js +120 -0
- package/dist/structured_query/tests/utils.test.d.ts +1 -0
- package/dist/structured_query/tests/utils.test.js +47 -0
- package/dist/tracers/event_stream.cjs +493 -0
- package/dist/tracers/event_stream.d.ts +137 -0
- package/dist/tracers/event_stream.js +489 -0
- package/dist/tracers/log_stream.d.ts +2 -77
- package/dist/tracers/tests/langchain_tracer.int.test.d.ts +1 -0
- package/dist/tracers/tests/langchain_tracer.int.test.js +74 -0
- package/dist/tracers/tests/tracer.test.d.ts +1 -0
- package/dist/tracers/tests/tracer.test.js +378 -0
- package/dist/utils/stream.cjs +27 -11
- package/dist/utils/stream.d.ts +6 -1
- package/dist/utils/stream.js +27 -11
- package/dist/utils/testing/tests/chatfake.test.d.ts +1 -0
- package/dist/utils/testing/tests/chatfake.test.js +112 -0
- package/dist/utils/tests/async_caller.test.d.ts +1 -0
- package/dist/utils/tests/async_caller.test.js +27 -0
- package/dist/utils/tests/enviroment.test.d.ts +1 -0
- package/dist/utils/tests/enviroment.test.js +6 -0
- package/dist/utils/tests/function_calling.test.d.ts +1 -0
- package/dist/utils/tests/function_calling.test.js +107 -0
- package/dist/utils/tests/math_utils.test.d.ts +1 -0
- package/dist/utils/tests/math_utils.test.js +139 -0
- package/dist/utils/tests/polyfill_stream.test.d.ts +1 -0
- package/dist/utils/tests/polyfill_stream.test.js +15 -0
- package/package.json +7 -7
package/dist/runnables/base.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import pRetry from "p-retry";
|
|
3
|
+
import { v4 as uuidv4 } from "uuid";
|
|
3
4
|
import { CallbackManager, } from "../callbacks/manager.js";
|
|
4
5
|
import { LogStreamCallbackHandler, RunLog, RunLogPatch, } from "../tracers/log_stream.js";
|
|
6
|
+
import { EventStreamCallbackHandler, } from "../tracers/event_stream.js";
|
|
5
7
|
import { Serializable } from "../load/serializable.js";
|
|
6
8
|
import { IterableReadableStream, concat, atee, pipeGeneratorWithSetup, AsyncGeneratorWithSetup, } from "../utils/stream.js";
|
|
7
9
|
import { DEFAULT_RECURSION_LIMIT, ensureConfig, getCallbackManagerForConfig, mergeConfigs, patchConfig, } from "./config.js";
|
|
@@ -11,6 +13,7 @@ import { _RootEventFilter, isRunnableInterface } from "./utils.js";
|
|
|
11
13
|
import { AsyncLocalStorageProviderSingleton } from "../singletons/index.js";
|
|
12
14
|
import { Graph } from "./graph.js";
|
|
13
15
|
import { convertToHttpEventStream } from "./wrappers.js";
|
|
16
|
+
import { consumeAsyncIterableInContext, consumeIteratorInContext, isAsyncIterable, isIterator, } from "./iter.js";
|
|
14
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
18
|
export function _coerceToDict(value, defaultKey) {
|
|
16
19
|
return value &&
|
|
@@ -160,7 +163,11 @@ export class Runnable extends Serializable {
|
|
|
160
163
|
async stream(input, options) {
|
|
161
164
|
// Buffer the first streamed chunk to allow for initial errors
|
|
162
165
|
// to surface immediately.
|
|
163
|
-
const
|
|
166
|
+
const config = ensureConfig(options);
|
|
167
|
+
const wrappedGenerator = new AsyncGeneratorWithSetup({
|
|
168
|
+
generator: this._streamIterator(input, config),
|
|
169
|
+
config,
|
|
170
|
+
});
|
|
164
171
|
await wrappedGenerator.setup;
|
|
165
172
|
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
|
|
166
173
|
}
|
|
@@ -273,11 +280,16 @@ export class Runnable extends Serializable {
|
|
|
273
280
|
const pipe = await pipeGeneratorWithSetup(transformer.bind(this), wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, config.runId, config.runType, undefined, undefined, config.runName ?? this.getName()), config);
|
|
274
281
|
delete config.runId;
|
|
275
282
|
runManager = pipe.setup;
|
|
283
|
+
const isStreamEventsHandler = (handler) => handler.name === "event_stream_tracer";
|
|
284
|
+
const streamEventsHandler = runManager?.handlers.find(isStreamEventsHandler);
|
|
285
|
+
let iterator = pipe.output;
|
|
286
|
+
if (streamEventsHandler !== undefined && runManager !== undefined) {
|
|
287
|
+
iterator = streamEventsHandler.tapOutputIterable(runManager.runId, iterator);
|
|
288
|
+
}
|
|
276
289
|
const isLogStreamHandler = (handler) => handler.name === "log_stream_tracer";
|
|
277
290
|
const streamLogHandler = runManager?.handlers.find(isLogStreamHandler);
|
|
278
|
-
let iterator = pipe.output;
|
|
279
291
|
if (streamLogHandler !== undefined && runManager !== undefined) {
|
|
280
|
-
iterator =
|
|
292
|
+
iterator = streamLogHandler.tapOutputIterable(runManager.runId, iterator);
|
|
281
293
|
}
|
|
282
294
|
for await (const chunk of iterator) {
|
|
283
295
|
yield chunk;
|
|
@@ -442,19 +454,93 @@ export class Runnable extends Serializable {
|
|
|
442
454
|
await runnableStreamConsumePromise;
|
|
443
455
|
}
|
|
444
456
|
}
|
|
445
|
-
|
|
457
|
+
streamEvents(input, options, streamOptions) {
|
|
458
|
+
let stream;
|
|
459
|
+
if (options.version === "v1") {
|
|
460
|
+
stream = this._streamEventsV1(input, options, streamOptions);
|
|
461
|
+
}
|
|
462
|
+
else if (options.version === "v2") {
|
|
463
|
+
stream = this._streamEventsV2(input, options, streamOptions);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
throw new Error(`Only versions "v1" and "v2" of the schema are currently supported.`);
|
|
467
|
+
}
|
|
446
468
|
if (options.encoding === "text/event-stream") {
|
|
447
|
-
|
|
448
|
-
yield* convertToHttpEventStream(stream);
|
|
469
|
+
return convertToHttpEventStream(stream);
|
|
449
470
|
}
|
|
450
471
|
else {
|
|
451
|
-
|
|
472
|
+
return IterableReadableStream.fromAsyncGenerator(stream);
|
|
452
473
|
}
|
|
453
474
|
}
|
|
454
|
-
async *
|
|
455
|
-
|
|
456
|
-
|
|
475
|
+
async *_streamEventsV2(input, options, streamOptions) {
|
|
476
|
+
const eventStreamer = new EventStreamCallbackHandler({
|
|
477
|
+
...streamOptions,
|
|
478
|
+
autoClose: false,
|
|
479
|
+
});
|
|
480
|
+
const config = ensureConfig(options);
|
|
481
|
+
const runId = config.runId ?? uuidv4();
|
|
482
|
+
config.runId = runId;
|
|
483
|
+
const callbacks = config.callbacks;
|
|
484
|
+
if (callbacks === undefined) {
|
|
485
|
+
config.callbacks = [eventStreamer];
|
|
486
|
+
}
|
|
487
|
+
else if (Array.isArray(callbacks)) {
|
|
488
|
+
config.callbacks = callbacks.concat(eventStreamer);
|
|
457
489
|
}
|
|
490
|
+
else {
|
|
491
|
+
const copiedCallbacks = callbacks.copy();
|
|
492
|
+
copiedCallbacks.inheritableHandlers.push(eventStreamer);
|
|
493
|
+
// eslint-disable-next-line no-param-reassign
|
|
494
|
+
config.callbacks = copiedCallbacks;
|
|
495
|
+
}
|
|
496
|
+
// Call the runnable in streaming mode,
|
|
497
|
+
// add each chunk to the output stream
|
|
498
|
+
const outerThis = this;
|
|
499
|
+
async function consumeRunnableStream() {
|
|
500
|
+
try {
|
|
501
|
+
const runnableStream = await outerThis.stream(input, config);
|
|
502
|
+
const tappedStream = eventStreamer.tapOutputIterable(runId, runnableStream);
|
|
503
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
504
|
+
for await (const _ of tappedStream) {
|
|
505
|
+
// Just iterate so that the callback handler picks up events
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
finally {
|
|
509
|
+
await eventStreamer.writer.close();
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
const runnableStreamConsumePromise = consumeRunnableStream();
|
|
513
|
+
let firstEventSent = false;
|
|
514
|
+
let firstEventRunId;
|
|
515
|
+
try {
|
|
516
|
+
for await (const event of eventStreamer) {
|
|
517
|
+
// This is a work-around an issue where the inputs into the
|
|
518
|
+
// chain are not available until the entire input is consumed.
|
|
519
|
+
// As a temporary solution, we'll modify the input to be the input
|
|
520
|
+
// that was passed into the chain.
|
|
521
|
+
if (!firstEventSent) {
|
|
522
|
+
event.data.input = input;
|
|
523
|
+
firstEventSent = true;
|
|
524
|
+
firstEventRunId = event.run_id;
|
|
525
|
+
yield event;
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
if (event.run_id === firstEventRunId && event.event.endsWith("_end")) {
|
|
529
|
+
// If it's the end event corresponding to the root runnable
|
|
530
|
+
// we dont include the input in the event since it's guaranteed
|
|
531
|
+
// to be included in the first event.
|
|
532
|
+
if (event.data?.input) {
|
|
533
|
+
delete event.data.input;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
yield event;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
finally {
|
|
540
|
+
await runnableStreamConsumePromise;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
async *_streamEventsV1(input, options, streamOptions) {
|
|
458
544
|
let runLog;
|
|
459
545
|
let hasEncounteredStartEvent = false;
|
|
460
546
|
const config = ensureConfig(options);
|
|
@@ -731,11 +817,16 @@ export class RunnableBinding extends Runnable {
|
|
|
731
817
|
generator, options) {
|
|
732
818
|
yield* this.bound.transform(generator, await this._mergeConfig(ensureConfig(options), this.kwargs));
|
|
733
819
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
820
|
+
streamEvents(input, options, streamOptions) {
|
|
821
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
822
|
+
const outerThis = this;
|
|
823
|
+
const generator = async function* () {
|
|
824
|
+
yield* outerThis.bound.streamEvents(input, {
|
|
825
|
+
...(await outerThis._mergeConfig(ensureConfig(options), outerThis.kwargs)),
|
|
826
|
+
version: options.version,
|
|
827
|
+
}, streamOptions);
|
|
828
|
+
};
|
|
829
|
+
return IterableReadableStream.fromAsyncGenerator(generator());
|
|
739
830
|
}
|
|
740
831
|
static isRunnableBinding(
|
|
741
832
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1279,7 +1370,11 @@ export class RunnableMap extends Runnable {
|
|
|
1279
1370
|
async function* generator() {
|
|
1280
1371
|
yield input;
|
|
1281
1372
|
}
|
|
1282
|
-
const
|
|
1373
|
+
const config = ensureConfig(options);
|
|
1374
|
+
const wrappedGenerator = new AsyncGeneratorWithSetup({
|
|
1375
|
+
generator: this.transform(generator(), config),
|
|
1376
|
+
config,
|
|
1377
|
+
});
|
|
1283
1378
|
await wrappedGenerator.setup;
|
|
1284
1379
|
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
|
|
1285
1380
|
}
|
|
@@ -1333,6 +1428,44 @@ export class RunnableLambda extends Runnable {
|
|
|
1333
1428
|
recursionLimit: (childConfig.recursionLimit ?? DEFAULT_RECURSION_LIMIT) - 1,
|
|
1334
1429
|
});
|
|
1335
1430
|
}
|
|
1431
|
+
else if (isAsyncIterable(output)) {
|
|
1432
|
+
let finalOutput;
|
|
1433
|
+
for await (const chunk of consumeAsyncIterableInContext(childConfig, output)) {
|
|
1434
|
+
if (finalOutput === undefined) {
|
|
1435
|
+
finalOutput = chunk;
|
|
1436
|
+
}
|
|
1437
|
+
else {
|
|
1438
|
+
// Make a best effort to gather, for any type that supports concat.
|
|
1439
|
+
try {
|
|
1440
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1441
|
+
finalOutput = concat(finalOutput, chunk);
|
|
1442
|
+
}
|
|
1443
|
+
catch (e) {
|
|
1444
|
+
finalOutput = chunk;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
output = finalOutput;
|
|
1449
|
+
}
|
|
1450
|
+
else if (isIterator(output)) {
|
|
1451
|
+
let finalOutput;
|
|
1452
|
+
for (const chunk of consumeIteratorInContext(childConfig, output)) {
|
|
1453
|
+
if (finalOutput === undefined) {
|
|
1454
|
+
finalOutput = chunk;
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1457
|
+
// Make a best effort to gather, for any type that supports concat.
|
|
1458
|
+
try {
|
|
1459
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1460
|
+
finalOutput = concat(finalOutput, chunk);
|
|
1461
|
+
}
|
|
1462
|
+
catch (e) {
|
|
1463
|
+
finalOutput = chunk;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
output = finalOutput;
|
|
1468
|
+
}
|
|
1336
1469
|
resolve(output);
|
|
1337
1470
|
}
|
|
1338
1471
|
catch (e) {
|
|
@@ -1387,6 +1520,16 @@ export class RunnableLambda extends Runnable {
|
|
|
1387
1520
|
yield chunk;
|
|
1388
1521
|
}
|
|
1389
1522
|
}
|
|
1523
|
+
else if (isAsyncIterable(output)) {
|
|
1524
|
+
for await (const chunk of consumeAsyncIterableInContext(config, output)) {
|
|
1525
|
+
yield chunk;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
else if (isIterator(output)) {
|
|
1529
|
+
for (const chunk of consumeIteratorInContext(config, output)) {
|
|
1530
|
+
yield chunk;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1390
1533
|
else {
|
|
1391
1534
|
yield output;
|
|
1392
1535
|
}
|
|
@@ -1398,7 +1541,11 @@ export class RunnableLambda extends Runnable {
|
|
|
1398
1541
|
async function* generator() {
|
|
1399
1542
|
yield input;
|
|
1400
1543
|
}
|
|
1401
|
-
const
|
|
1544
|
+
const config = ensureConfig(options);
|
|
1545
|
+
const wrappedGenerator = new AsyncGeneratorWithSetup({
|
|
1546
|
+
generator: this.transform(generator(), config),
|
|
1547
|
+
config,
|
|
1548
|
+
});
|
|
1402
1549
|
await wrappedGenerator.setup;
|
|
1403
1550
|
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
|
|
1404
1551
|
}
|
|
@@ -1598,7 +1745,11 @@ export class RunnableAssign extends Runnable {
|
|
|
1598
1745
|
async function* generator() {
|
|
1599
1746
|
yield input;
|
|
1600
1747
|
}
|
|
1601
|
-
const
|
|
1748
|
+
const config = ensureConfig(options);
|
|
1749
|
+
const wrappedGenerator = new AsyncGeneratorWithSetup({
|
|
1750
|
+
generator: this.transform(generator(), config),
|
|
1751
|
+
config,
|
|
1752
|
+
});
|
|
1602
1753
|
await wrappedGenerator.setup;
|
|
1603
1754
|
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
|
|
1604
1755
|
}
|
|
@@ -1665,7 +1816,11 @@ export class RunnablePick extends Runnable {
|
|
|
1665
1816
|
async function* generator() {
|
|
1666
1817
|
yield input;
|
|
1667
1818
|
}
|
|
1668
|
-
const
|
|
1819
|
+
const config = ensureConfig(options);
|
|
1820
|
+
const wrappedGenerator = new AsyncGeneratorWithSetup({
|
|
1821
|
+
generator: this.transform(generator(), config),
|
|
1822
|
+
config,
|
|
1823
|
+
});
|
|
1669
1824
|
await wrappedGenerator.setup;
|
|
1670
1825
|
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
|
|
1671
1826
|
}
|
|
@@ -126,68 +126,123 @@ class RunnableWithMessageHistory extends base_js_1.RunnableBinding {
|
|
|
126
126
|
this.outputMessagesKey = fields.outputMessagesKey;
|
|
127
127
|
this.historyMessagesKey = fields.historyMessagesKey;
|
|
128
128
|
}
|
|
129
|
-
_getInputMessages(
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
_getInputMessages(
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
131
|
+
inputValue) {
|
|
132
|
+
let parsedInputValue;
|
|
133
|
+
if (typeof inputValue === "object" &&
|
|
134
|
+
!Array.isArray(inputValue) &&
|
|
135
|
+
!(0, index_js_1.isBaseMessage)(inputValue)) {
|
|
136
|
+
let key;
|
|
137
|
+
if (this.inputMessagesKey) {
|
|
138
|
+
key = this.inputMessagesKey;
|
|
139
|
+
}
|
|
140
|
+
else if (Object.keys(inputValue).length === 1) {
|
|
141
|
+
key = Object.keys(inputValue)[0];
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
key = "input";
|
|
145
|
+
}
|
|
146
|
+
if (Array.isArray(inputValue[key]) && Array.isArray(inputValue[key][0])) {
|
|
147
|
+
parsedInputValue = inputValue[key][0];
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
parsedInputValue = inputValue[key];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
parsedInputValue = inputValue;
|
|
155
|
+
}
|
|
156
|
+
if (typeof parsedInputValue === "string") {
|
|
157
|
+
return [new index_js_1.HumanMessage(parsedInputValue)];
|
|
132
158
|
}
|
|
133
|
-
else if (Array.isArray(
|
|
134
|
-
return
|
|
159
|
+
else if (Array.isArray(parsedInputValue)) {
|
|
160
|
+
return parsedInputValue;
|
|
161
|
+
}
|
|
162
|
+
else if ((0, index_js_1.isBaseMessage)(parsedInputValue)) {
|
|
163
|
+
return [parsedInputValue];
|
|
135
164
|
}
|
|
136
165
|
else {
|
|
137
|
-
|
|
166
|
+
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages.\nGot ${JSON.stringify(parsedInputValue, null, 2)}`);
|
|
138
167
|
}
|
|
139
168
|
}
|
|
140
169
|
_getOutputMessages(
|
|
141
170
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
142
171
|
outputValue) {
|
|
143
|
-
let
|
|
172
|
+
let parsedOutputValue;
|
|
144
173
|
if (!Array.isArray(outputValue) &&
|
|
145
174
|
!(0, index_js_1.isBaseMessage)(outputValue) &&
|
|
146
175
|
typeof outputValue !== "string") {
|
|
147
|
-
|
|
176
|
+
let key;
|
|
177
|
+
if (this.outputMessagesKey !== undefined) {
|
|
178
|
+
key = this.outputMessagesKey;
|
|
179
|
+
}
|
|
180
|
+
else if (Object.keys(outputValue).length === 1) {
|
|
181
|
+
key = Object.keys(outputValue)[0];
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
key = "output";
|
|
185
|
+
}
|
|
186
|
+
// If you are wrapping a chat model directly
|
|
187
|
+
// The output is actually this weird generations object
|
|
188
|
+
if (outputValue.generations !== undefined) {
|
|
189
|
+
parsedOutputValue = outputValue.generations[0][0].message;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
parsedOutputValue = outputValue[key];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
parsedOutputValue = outputValue;
|
|
148
197
|
}
|
|
149
|
-
if (typeof
|
|
150
|
-
return [new index_js_1.AIMessage(
|
|
198
|
+
if (typeof parsedOutputValue === "string") {
|
|
199
|
+
return [new index_js_1.AIMessage(parsedOutputValue)];
|
|
151
200
|
}
|
|
152
|
-
else if (Array.isArray(
|
|
153
|
-
return
|
|
201
|
+
else if (Array.isArray(parsedOutputValue)) {
|
|
202
|
+
return parsedOutputValue;
|
|
154
203
|
}
|
|
155
|
-
else if ((0, index_js_1.isBaseMessage)(
|
|
156
|
-
return [
|
|
204
|
+
else if ((0, index_js_1.isBaseMessage)(parsedOutputValue)) {
|
|
205
|
+
return [parsedOutputValue];
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages. Received: ${JSON.stringify(parsedOutputValue, null, 2)}`);
|
|
157
209
|
}
|
|
158
|
-
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages. Received: ${JSON.stringify(newOutputValue, null, 2)}`);
|
|
159
210
|
}
|
|
160
211
|
async _enterHistory(
|
|
161
212
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
162
213
|
input, kwargs) {
|
|
163
214
|
const history = kwargs?.config?.configurable?.messageHistory;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const historyMessages = history ? await history.getMessages() : [];
|
|
170
|
-
const returnType = [
|
|
171
|
-
...historyMessages,
|
|
172
|
-
...this._getInputMessages(inputVal),
|
|
173
|
-
];
|
|
174
|
-
return returnType;
|
|
215
|
+
const messages = await history.getMessages();
|
|
216
|
+
if (this.historyMessagesKey === undefined) {
|
|
217
|
+
return messages.concat(this._getInputMessages(input));
|
|
218
|
+
}
|
|
219
|
+
return messages;
|
|
175
220
|
}
|
|
176
221
|
async _exitHistory(run, config) {
|
|
177
222
|
const history = config.configurable?.messageHistory;
|
|
178
223
|
// Get input messages
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
224
|
+
let inputs;
|
|
225
|
+
// Chat model inputs are nested arrays
|
|
226
|
+
if (Array.isArray(run.inputs) && Array.isArray(run.inputs[0])) {
|
|
227
|
+
inputs = run.inputs[0];
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
inputs = run.inputs;
|
|
231
|
+
}
|
|
232
|
+
let inputMessages = this._getInputMessages(inputs);
|
|
233
|
+
// If historic messages were prepended to the input messages, remove them to
|
|
234
|
+
// avoid adding duplicate messages to history.
|
|
235
|
+
if (this.historyMessagesKey === undefined) {
|
|
236
|
+
const existingMessages = await history.getMessages();
|
|
237
|
+
inputMessages = inputMessages.slice(existingMessages.length);
|
|
238
|
+
}
|
|
182
239
|
// Get output messages
|
|
183
240
|
const outputValue = run.outputs;
|
|
184
241
|
if (!outputValue) {
|
|
185
242
|
throw new Error(`Output values from 'Run' undefined. Run: ${JSON.stringify(run, null, 2)}`);
|
|
186
243
|
}
|
|
187
244
|
const outputMessages = this._getOutputMessages(outputValue);
|
|
188
|
-
|
|
189
|
-
await history.addMessage(message);
|
|
190
|
-
}
|
|
245
|
+
await history.addMessages([...inputMessages, ...outputMessages]);
|
|
191
246
|
}
|
|
192
247
|
async _mergeConfig(...configs) {
|
|
193
248
|
const config = await super._mergeConfig(...configs);
|
|
@@ -83,7 +83,7 @@ export declare class RunnableWithMessageHistory<RunInput, RunOutput> extends Run
|
|
|
83
83
|
historyMessagesKey?: string;
|
|
84
84
|
getMessageHistory: GetSessionHistoryCallable;
|
|
85
85
|
constructor(fields: RunnableWithMessageHistoryInputs<RunInput, RunOutput>);
|
|
86
|
-
_getInputMessages(inputValue: string | BaseMessage | Array<BaseMessage>): Array<BaseMessage>;
|
|
86
|
+
_getInputMessages(inputValue: string | BaseMessage | Array<BaseMessage> | Record<string, any>): Array<BaseMessage>;
|
|
87
87
|
_getOutputMessages(outputValue: string | BaseMessage | Array<BaseMessage> | Record<string, any>): Array<BaseMessage>;
|
|
88
88
|
_enterHistory(input: any, kwargs?: {
|
|
89
89
|
config?: RunnableConfig;
|
|
@@ -123,68 +123,123 @@ export class RunnableWithMessageHistory extends RunnableBinding {
|
|
|
123
123
|
this.outputMessagesKey = fields.outputMessagesKey;
|
|
124
124
|
this.historyMessagesKey = fields.historyMessagesKey;
|
|
125
125
|
}
|
|
126
|
-
_getInputMessages(
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
_getInputMessages(
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
+
inputValue) {
|
|
129
|
+
let parsedInputValue;
|
|
130
|
+
if (typeof inputValue === "object" &&
|
|
131
|
+
!Array.isArray(inputValue) &&
|
|
132
|
+
!isBaseMessage(inputValue)) {
|
|
133
|
+
let key;
|
|
134
|
+
if (this.inputMessagesKey) {
|
|
135
|
+
key = this.inputMessagesKey;
|
|
136
|
+
}
|
|
137
|
+
else if (Object.keys(inputValue).length === 1) {
|
|
138
|
+
key = Object.keys(inputValue)[0];
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
key = "input";
|
|
142
|
+
}
|
|
143
|
+
if (Array.isArray(inputValue[key]) && Array.isArray(inputValue[key][0])) {
|
|
144
|
+
parsedInputValue = inputValue[key][0];
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
parsedInputValue = inputValue[key];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
parsedInputValue = inputValue;
|
|
152
|
+
}
|
|
153
|
+
if (typeof parsedInputValue === "string") {
|
|
154
|
+
return [new HumanMessage(parsedInputValue)];
|
|
129
155
|
}
|
|
130
|
-
else if (Array.isArray(
|
|
131
|
-
return
|
|
156
|
+
else if (Array.isArray(parsedInputValue)) {
|
|
157
|
+
return parsedInputValue;
|
|
158
|
+
}
|
|
159
|
+
else if (isBaseMessage(parsedInputValue)) {
|
|
160
|
+
return [parsedInputValue];
|
|
132
161
|
}
|
|
133
162
|
else {
|
|
134
|
-
|
|
163
|
+
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages.\nGot ${JSON.stringify(parsedInputValue, null, 2)}`);
|
|
135
164
|
}
|
|
136
165
|
}
|
|
137
166
|
_getOutputMessages(
|
|
138
167
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
168
|
outputValue) {
|
|
140
|
-
let
|
|
169
|
+
let parsedOutputValue;
|
|
141
170
|
if (!Array.isArray(outputValue) &&
|
|
142
171
|
!isBaseMessage(outputValue) &&
|
|
143
172
|
typeof outputValue !== "string") {
|
|
144
|
-
|
|
173
|
+
let key;
|
|
174
|
+
if (this.outputMessagesKey !== undefined) {
|
|
175
|
+
key = this.outputMessagesKey;
|
|
176
|
+
}
|
|
177
|
+
else if (Object.keys(outputValue).length === 1) {
|
|
178
|
+
key = Object.keys(outputValue)[0];
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
key = "output";
|
|
182
|
+
}
|
|
183
|
+
// If you are wrapping a chat model directly
|
|
184
|
+
// The output is actually this weird generations object
|
|
185
|
+
if (outputValue.generations !== undefined) {
|
|
186
|
+
parsedOutputValue = outputValue.generations[0][0].message;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
parsedOutputValue = outputValue[key];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
parsedOutputValue = outputValue;
|
|
145
194
|
}
|
|
146
|
-
if (typeof
|
|
147
|
-
return [new AIMessage(
|
|
195
|
+
if (typeof parsedOutputValue === "string") {
|
|
196
|
+
return [new AIMessage(parsedOutputValue)];
|
|
148
197
|
}
|
|
149
|
-
else if (Array.isArray(
|
|
150
|
-
return
|
|
198
|
+
else if (Array.isArray(parsedOutputValue)) {
|
|
199
|
+
return parsedOutputValue;
|
|
151
200
|
}
|
|
152
|
-
else if (isBaseMessage(
|
|
153
|
-
return [
|
|
201
|
+
else if (isBaseMessage(parsedOutputValue)) {
|
|
202
|
+
return [parsedOutputValue];
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages. Received: ${JSON.stringify(parsedOutputValue, null, 2)}`);
|
|
154
206
|
}
|
|
155
|
-
throw new Error(`Expected a string, BaseMessage, or array of BaseMessages. Received: ${JSON.stringify(newOutputValue, null, 2)}`);
|
|
156
207
|
}
|
|
157
208
|
async _enterHistory(
|
|
158
209
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
159
210
|
input, kwargs) {
|
|
160
211
|
const history = kwargs?.config?.configurable?.messageHistory;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const historyMessages = history ? await history.getMessages() : [];
|
|
167
|
-
const returnType = [
|
|
168
|
-
...historyMessages,
|
|
169
|
-
...this._getInputMessages(inputVal),
|
|
170
|
-
];
|
|
171
|
-
return returnType;
|
|
212
|
+
const messages = await history.getMessages();
|
|
213
|
+
if (this.historyMessagesKey === undefined) {
|
|
214
|
+
return messages.concat(this._getInputMessages(input));
|
|
215
|
+
}
|
|
216
|
+
return messages;
|
|
172
217
|
}
|
|
173
218
|
async _exitHistory(run, config) {
|
|
174
219
|
const history = config.configurable?.messageHistory;
|
|
175
220
|
// Get input messages
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
221
|
+
let inputs;
|
|
222
|
+
// Chat model inputs are nested arrays
|
|
223
|
+
if (Array.isArray(run.inputs) && Array.isArray(run.inputs[0])) {
|
|
224
|
+
inputs = run.inputs[0];
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
inputs = run.inputs;
|
|
228
|
+
}
|
|
229
|
+
let inputMessages = this._getInputMessages(inputs);
|
|
230
|
+
// If historic messages were prepended to the input messages, remove them to
|
|
231
|
+
// avoid adding duplicate messages to history.
|
|
232
|
+
if (this.historyMessagesKey === undefined) {
|
|
233
|
+
const existingMessages = await history.getMessages();
|
|
234
|
+
inputMessages = inputMessages.slice(existingMessages.length);
|
|
235
|
+
}
|
|
179
236
|
// Get output messages
|
|
180
237
|
const outputValue = run.outputs;
|
|
181
238
|
if (!outputValue) {
|
|
182
239
|
throw new Error(`Output values from 'Run' undefined. Run: ${JSON.stringify(run, null, 2)}`);
|
|
183
240
|
}
|
|
184
241
|
const outputMessages = this._getOutputMessages(outputValue);
|
|
185
|
-
|
|
186
|
-
await history.addMessage(message);
|
|
187
|
-
}
|
|
242
|
+
await history.addMessages([...inputMessages, ...outputMessages]);
|
|
188
243
|
}
|
|
189
244
|
async _mergeConfig(...configs) {
|
|
190
245
|
const config = await super._mergeConfig(...configs);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.consumeAsyncIterableInContext = exports.consumeIteratorInContext = exports.isAsyncIterable = exports.isIterator = void 0;
|
|
4
|
+
const index_js_1 = require("../singletons/index.cjs");
|
|
5
|
+
function isIterator(thing) {
|
|
6
|
+
return (typeof thing === "object" &&
|
|
7
|
+
thing !== null &&
|
|
8
|
+
typeof thing[Symbol.iterator] === "function" &&
|
|
9
|
+
// avoid detecting array/set as iterator
|
|
10
|
+
typeof thing.next === "function");
|
|
11
|
+
}
|
|
12
|
+
exports.isIterator = isIterator;
|
|
13
|
+
function isAsyncIterable(thing) {
|
|
14
|
+
return (typeof thing === "object" &&
|
|
15
|
+
thing !== null &&
|
|
16
|
+
typeof thing[Symbol.asyncIterator] ===
|
|
17
|
+
"function");
|
|
18
|
+
}
|
|
19
|
+
exports.isAsyncIterable = isAsyncIterable;
|
|
20
|
+
function* consumeIteratorInContext(context, iter) {
|
|
21
|
+
const storage = index_js_1.AsyncLocalStorageProviderSingleton.getInstance();
|
|
22
|
+
while (true) {
|
|
23
|
+
const { value, done } = storage.run(context, iter.next.bind(iter));
|
|
24
|
+
if (done) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
yield value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.consumeIteratorInContext = consumeIteratorInContext;
|
|
33
|
+
async function* consumeAsyncIterableInContext(context, iter) {
|
|
34
|
+
const storage = index_js_1.AsyncLocalStorageProviderSingleton.getInstance();
|
|
35
|
+
const iterator = iter[Symbol.asyncIterator]();
|
|
36
|
+
while (true) {
|
|
37
|
+
const { value, done } = await storage.run(context, iterator.next.bind(iter));
|
|
38
|
+
if (done) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
yield value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.consumeAsyncIterableInContext = consumeAsyncIterableInContext;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RunnableConfig } from "./config.js";
|
|
2
|
+
export declare function isIterator(thing: unknown): thing is IterableIterator<unknown>;
|
|
3
|
+
export declare function isAsyncIterable(thing: unknown): thing is AsyncIterable<unknown>;
|
|
4
|
+
export declare function consumeIteratorInContext<T>(context: Partial<RunnableConfig> | undefined, iter: IterableIterator<T>): IterableIterator<T>;
|
|
5
|
+
export declare function consumeAsyncIterableInContext<T>(context: Partial<RunnableConfig> | undefined, iter: AsyncIterable<T>): AsyncIterableIterator<T>;
|