@langchain/core 0.2.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/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/chat_models.d.ts +2 -2
- 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 +87 -6
- package/dist/runnables/base.d.ts +45 -26
- package/dist/runnables/base.js +87 -6
- 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/remote.cjs +2 -2
- package/dist/runnables/remote.d.ts +3 -3
- package/dist/runnables/remote.js +2 -2
- 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/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/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 +6 -6
package/dist/runnables/base.cjs
CHANGED
|
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
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 = exports._coerceToDict = void 0;
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const p_retry_1 = __importDefault(require("p-retry"));
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
9
10
|
const manager_js_1 = require("../callbacks/manager.cjs");
|
|
10
11
|
const log_stream_js_1 = require("../tracers/log_stream.cjs");
|
|
12
|
+
const event_stream_js_1 = require("../tracers/event_stream.cjs");
|
|
11
13
|
const serializable_js_1 = require("../load/serializable.cjs");
|
|
12
14
|
const stream_js_1 = require("../utils/stream.cjs");
|
|
13
15
|
const config_js_1 = require("./config.cjs");
|
|
@@ -285,11 +287,16 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
285
287
|
const pipe = await (0, stream_js_1.pipeGeneratorWithSetup)(transformer.bind(this), wrapInputForTracing(), async () => callbackManager_?.handleChainStart(this.toJSON(), { input: "" }, config.runId, config.runType, undefined, undefined, config.runName ?? this.getName()), config);
|
|
286
288
|
delete config.runId;
|
|
287
289
|
runManager = pipe.setup;
|
|
290
|
+
const isStreamEventsHandler = (handler) => handler.name === "event_stream_tracer";
|
|
291
|
+
const streamEventsHandler = runManager?.handlers.find(isStreamEventsHandler);
|
|
292
|
+
let iterator = pipe.output;
|
|
293
|
+
if (streamEventsHandler !== undefined && runManager !== undefined) {
|
|
294
|
+
iterator = streamEventsHandler.tapOutputIterable(runManager.runId, iterator);
|
|
295
|
+
}
|
|
288
296
|
const isLogStreamHandler = (handler) => handler.name === "log_stream_tracer";
|
|
289
297
|
const streamLogHandler = runManager?.handlers.find(isLogStreamHandler);
|
|
290
|
-
let iterator = pipe.output;
|
|
291
298
|
if (streamLogHandler !== undefined && runManager !== undefined) {
|
|
292
|
-
iterator =
|
|
299
|
+
iterator = streamLogHandler.tapOutputIterable(runManager.runId, iterator);
|
|
293
300
|
}
|
|
294
301
|
for await (const chunk of iterator) {
|
|
295
302
|
yield chunk;
|
|
@@ -455,7 +462,16 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
455
462
|
}
|
|
456
463
|
}
|
|
457
464
|
streamEvents(input, options, streamOptions) {
|
|
458
|
-
|
|
465
|
+
let stream;
|
|
466
|
+
if (options.version === "v1") {
|
|
467
|
+
stream = this._streamEventsV1(input, options, streamOptions);
|
|
468
|
+
}
|
|
469
|
+
else if (options.version === "v2") {
|
|
470
|
+
stream = this._streamEventsV2(input, options, streamOptions);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
throw new Error(`Only versions "v1" and "v2" of the schema are currently supported.`);
|
|
474
|
+
}
|
|
459
475
|
if (options.encoding === "text/event-stream") {
|
|
460
476
|
return (0, wrappers_js_1.convertToHttpEventStream)(stream);
|
|
461
477
|
}
|
|
@@ -463,10 +479,75 @@ class Runnable extends serializable_js_1.Serializable {
|
|
|
463
479
|
return stream_js_1.IterableReadableStream.fromAsyncGenerator(stream);
|
|
464
480
|
}
|
|
465
481
|
}
|
|
466
|
-
async *
|
|
467
|
-
|
|
468
|
-
|
|
482
|
+
async *_streamEventsV2(input, options, streamOptions) {
|
|
483
|
+
const eventStreamer = new event_stream_js_1.EventStreamCallbackHandler({
|
|
484
|
+
...streamOptions,
|
|
485
|
+
autoClose: false,
|
|
486
|
+
});
|
|
487
|
+
const config = (0, config_js_1.ensureConfig)(options);
|
|
488
|
+
const runId = config.runId ?? (0, uuid_1.v4)();
|
|
489
|
+
config.runId = runId;
|
|
490
|
+
const callbacks = config.callbacks;
|
|
491
|
+
if (callbacks === undefined) {
|
|
492
|
+
config.callbacks = [eventStreamer];
|
|
493
|
+
}
|
|
494
|
+
else if (Array.isArray(callbacks)) {
|
|
495
|
+
config.callbacks = callbacks.concat(eventStreamer);
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
const copiedCallbacks = callbacks.copy();
|
|
499
|
+
copiedCallbacks.inheritableHandlers.push(eventStreamer);
|
|
500
|
+
// eslint-disable-next-line no-param-reassign
|
|
501
|
+
config.callbacks = copiedCallbacks;
|
|
502
|
+
}
|
|
503
|
+
// Call the runnable in streaming mode,
|
|
504
|
+
// add each chunk to the output stream
|
|
505
|
+
const outerThis = this;
|
|
506
|
+
async function consumeRunnableStream() {
|
|
507
|
+
try {
|
|
508
|
+
const runnableStream = await outerThis.stream(input, config);
|
|
509
|
+
const tappedStream = eventStreamer.tapOutputIterable(runId, runnableStream);
|
|
510
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
511
|
+
for await (const _ of tappedStream) {
|
|
512
|
+
// Just iterate so that the callback handler picks up events
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
finally {
|
|
516
|
+
await eventStreamer.writer.close();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const runnableStreamConsumePromise = consumeRunnableStream();
|
|
520
|
+
let firstEventSent = false;
|
|
521
|
+
let firstEventRunId;
|
|
522
|
+
try {
|
|
523
|
+
for await (const event of eventStreamer) {
|
|
524
|
+
// This is a work-around an issue where the inputs into the
|
|
525
|
+
// chain are not available until the entire input is consumed.
|
|
526
|
+
// As a temporary solution, we'll modify the input to be the input
|
|
527
|
+
// that was passed into the chain.
|
|
528
|
+
if (!firstEventSent) {
|
|
529
|
+
event.data.input = input;
|
|
530
|
+
firstEventSent = true;
|
|
531
|
+
firstEventRunId = event.run_id;
|
|
532
|
+
yield event;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
if (event.run_id === firstEventRunId && event.event.endsWith("_end")) {
|
|
536
|
+
// If it's the end event corresponding to the root runnable
|
|
537
|
+
// we dont include the input in the event since it's guaranteed
|
|
538
|
+
// to be included in the first event.
|
|
539
|
+
if (event.data?.input) {
|
|
540
|
+
delete event.data.input;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
yield event;
|
|
544
|
+
}
|
|
469
545
|
}
|
|
546
|
+
finally {
|
|
547
|
+
await runnableStreamConsumePromise;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
async *_streamEventsV1(input, options, streamOptions) {
|
|
470
551
|
let runLog;
|
|
471
552
|
let hasEncounteredStartEvent = false;
|
|
472
553
|
const config = (0, config_js_1.ensureConfig)(options);
|
package/dist/runnables/base.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RunnableInterface, RunnableBatchOptions } from "./types.js";
|
|
2
2
|
import { CallbackManagerForChainRun } from "../callbacks/manager.js";
|
|
3
|
-
import { LogStreamCallbackHandler, LogStreamCallbackHandlerInput, RunLogPatch
|
|
3
|
+
import { LogStreamCallbackHandler, LogStreamCallbackHandlerInput, RunLogPatch } from "../tracers/log_stream.js";
|
|
4
|
+
import { EventStreamCallbackHandlerInput, StreamEvent } from "../tracers/event_stream.js";
|
|
4
5
|
import { Serializable } from "../load/serializable.js";
|
|
5
6
|
import { IterableReadableStream } from "../utils/stream.js";
|
|
6
7
|
import { RunnableConfig } from "./config.js";
|
|
@@ -179,33 +180,51 @@ export declare abstract class Runnable<RunInput = any, RunOutput = any, CallOpti
|
|
|
179
180
|
* chains. Metadata fields have been omitted from the table for brevity.
|
|
180
181
|
* Chain definitions have been included after the table.
|
|
181
182
|
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* |
|
|
186
|
-
*
|
|
187
|
-
* |
|
|
188
|
-
*
|
|
189
|
-
* |
|
|
190
|
-
*
|
|
191
|
-
* |
|
|
192
|
-
*
|
|
193
|
-
* |
|
|
194
|
-
*
|
|
195
|
-
* |
|
|
196
|
-
*
|
|
197
|
-
* |
|
|
183
|
+
* **ATTENTION** This reference table is for the V2 version of the schema.
|
|
184
|
+
*
|
|
185
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
186
|
+
* | event | name | chunk | input | output |
|
|
187
|
+
* +======================+==================+=================================+===============================================+=================================================+
|
|
188
|
+
* | on_chat_model_start | [model name] | | {"messages": [[SystemMessage, HumanMessage]]} | |
|
|
189
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
190
|
+
* | on_chat_model_stream | [model name] | AIMessageChunk(content="hello") | | |
|
|
191
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
192
|
+
* | on_chat_model_end | [model name] | | {"messages": [[SystemMessage, HumanMessage]]} | AIMessageChunk(content="hello world") |
|
|
193
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
194
|
+
* | on_llm_start | [model name] | | {'input': 'hello'} | |
|
|
195
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
196
|
+
* | on_llm_stream | [model name] | 'Hello' | | |
|
|
197
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
198
|
+
* | on_llm_end | [model name] | | 'Hello human!' | |
|
|
199
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
200
|
+
* | on_chain_start | format_docs | | | |
|
|
201
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
202
|
+
* | on_chain_stream | format_docs | "hello world!, goodbye world!" | | |
|
|
203
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
204
|
+
* | on_chain_end | format_docs | | [Document(...)] | "hello world!, goodbye world!" |
|
|
205
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
206
|
+
* | on_tool_start | some_tool | | {"x": 1, "y": "2"} | |
|
|
207
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
208
|
+
* | on_tool_end | some_tool | | | {"x": 1, "y": "2"} |
|
|
209
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
210
|
+
* | on_retriever_start | [retriever name] | | {"query": "hello"} | |
|
|
211
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
212
|
+
* | on_retriever_end | [retriever name] | | {"query": "hello"} | [Document(...), ..] |
|
|
213
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
214
|
+
* | on_prompt_start | [template_name] | | {"question": "hello"} | |
|
|
215
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
216
|
+
* | on_prompt_end | [template_name] | | {"question": "hello"} | ChatPromptValue(messages: [SystemMessage, ...]) |
|
|
217
|
+
* +----------------------+------------------+---------------------------------+-----------------------------------------------+-------------------------------------------------+
|
|
198
218
|
*/
|
|
199
219
|
streamEvents(input: RunInput, options: Partial<CallOptions> & {
|
|
200
|
-
version: "v1";
|
|
201
|
-
}, streamOptions?: Omit<
|
|
220
|
+
version: "v1" | "v2";
|
|
221
|
+
}, streamOptions?: Omit<EventStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<StreamEvent>;
|
|
202
222
|
streamEvents(input: RunInput, options: Partial<CallOptions> & {
|
|
203
|
-
version: "v1";
|
|
223
|
+
version: "v1" | "v2";
|
|
204
224
|
encoding: "text/event-stream";
|
|
205
|
-
}, streamOptions?: Omit<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}, streamOptions?: Omit<LogStreamCallbackHandlerInput, "autoClose">): AsyncGenerator<StreamEvent>;
|
|
225
|
+
}, streamOptions?: Omit<EventStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<Uint8Array>;
|
|
226
|
+
private _streamEventsV2;
|
|
227
|
+
private _streamEventsV1;
|
|
209
228
|
static isRunnable(thing: any): thing is Runnable;
|
|
210
229
|
/**
|
|
211
230
|
* Bind lifecycle listeners to a Runnable, returning a new Runnable.
|
|
@@ -262,10 +281,10 @@ export declare class RunnableBinding<RunInput, RunOutput, CallOptions extends Ru
|
|
|
262
281
|
stream(input: RunInput, options?: Partial<CallOptions> | undefined): Promise<IterableReadableStream<RunOutput>>;
|
|
263
282
|
transform(generator: AsyncGenerator<RunInput>, options: Partial<CallOptions>): AsyncGenerator<RunOutput>;
|
|
264
283
|
streamEvents(input: RunInput, options: Partial<CallOptions> & {
|
|
265
|
-
version: "v1";
|
|
284
|
+
version: "v1" | "v2";
|
|
266
285
|
}, streamOptions?: Omit<LogStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<StreamEvent>;
|
|
267
286
|
streamEvents(input: RunInput, options: Partial<CallOptions> & {
|
|
268
|
-
version: "v1";
|
|
287
|
+
version: "v1" | "v2";
|
|
269
288
|
encoding: "text/event-stream";
|
|
270
289
|
}, streamOptions?: Omit<LogStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<Uint8Array>;
|
|
271
290
|
static isRunnableBinding(thing: any): thing is RunnableBinding<any, any, any>;
|
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";
|
|
@@ -278,11 +280,16 @@ export class Runnable extends Serializable {
|
|
|
278
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);
|
|
279
281
|
delete config.runId;
|
|
280
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
|
+
}
|
|
281
289
|
const isLogStreamHandler = (handler) => handler.name === "log_stream_tracer";
|
|
282
290
|
const streamLogHandler = runManager?.handlers.find(isLogStreamHandler);
|
|
283
|
-
let iterator = pipe.output;
|
|
284
291
|
if (streamLogHandler !== undefined && runManager !== undefined) {
|
|
285
|
-
iterator =
|
|
292
|
+
iterator = streamLogHandler.tapOutputIterable(runManager.runId, iterator);
|
|
286
293
|
}
|
|
287
294
|
for await (const chunk of iterator) {
|
|
288
295
|
yield chunk;
|
|
@@ -448,7 +455,16 @@ export class Runnable extends Serializable {
|
|
|
448
455
|
}
|
|
449
456
|
}
|
|
450
457
|
streamEvents(input, options, streamOptions) {
|
|
451
|
-
|
|
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
|
+
}
|
|
452
468
|
if (options.encoding === "text/event-stream") {
|
|
453
469
|
return convertToHttpEventStream(stream);
|
|
454
470
|
}
|
|
@@ -456,10 +472,75 @@ export class Runnable extends Serializable {
|
|
|
456
472
|
return IterableReadableStream.fromAsyncGenerator(stream);
|
|
457
473
|
}
|
|
458
474
|
}
|
|
459
|
-
async *
|
|
460
|
-
|
|
461
|
-
|
|
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);
|
|
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
|
+
}
|
|
462
538
|
}
|
|
539
|
+
finally {
|
|
540
|
+
await runnableStreamConsumePromise;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
async *_streamEventsV1(input, options, streamOptions) {
|
|
463
544
|
let runLog;
|
|
464
545
|
let hasEncounteredStartEvent = false;
|
|
465
546
|
const config = ensureConfig(options);
|
|
@@ -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;
|