@langchain/core 0.1.27-rc.0 → 0.1.27-rc.2

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,7 @@
1
1
  import { applyPatch, } from "../utils/fast-json-patch/index.js";
2
2
  import { BaseTracer } from "./base.js";
3
3
  import { IterableReadableStream } from "../utils/stream.js";
4
+ import { AIMessageChunk } from "../messages/index.js";
4
5
  /**
5
6
  * List of jsonpatch JSONPatchOperations, which describe how to create the run state
6
7
  * from an empty dict. This is the minimal representation of the log, designed to
@@ -16,7 +17,7 @@ export class RunLogPatch {
16
17
  writable: true,
17
18
  value: void 0
18
19
  });
19
- this.ops = fields.ops;
20
+ this.ops = fields.ops ?? [];
20
21
  }
21
22
  concat(other) {
22
23
  const ops = this.ops.concat(other.ops);
@@ -44,6 +45,67 @@ export class RunLog extends RunLogPatch {
44
45
  const states = applyPatch(this.state, other.ops);
45
46
  return new RunLog({ ops, state: states[states.length - 1].newDocument });
46
47
  }
48
+ static fromRunLogPatch(patch) {
49
+ const states = applyPatch({}, patch.ops);
50
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
51
+ return new RunLog({
52
+ ops: patch.ops,
53
+ state: states[states.length - 1].newDocument,
54
+ });
55
+ }
56
+ }
57
+ /**
58
+ * Extract standardized inputs from a run.
59
+ *
60
+ * Standardizes the inputs based on the type of the runnable used.
61
+ *
62
+ * @param run - Run object
63
+ * @param schemaFormat - The schema format to use.
64
+ *
65
+ * @returns Valid inputs are only dict. By conventions, inputs always represented
66
+ * invocation using named arguments.
67
+ * A null means that the input is not yet known!
68
+ */
69
+ async function _getStandardizedInputs(run, schemaFormat) {
70
+ if (schemaFormat === "original") {
71
+ throw new Error("Do not assign inputs with original schema drop the key for now. " +
72
+ "When inputs are added to streamLog they should be added with " +
73
+ "standardized schema for streaming events.");
74
+ }
75
+ const { inputs } = run;
76
+ if (["retriever", "llm", "prompt"].includes(run.run_type)) {
77
+ return inputs;
78
+ }
79
+ if (Object.keys(inputs).length === 1 && inputs?.input === "") {
80
+ return undefined;
81
+ }
82
+ // new style chains
83
+ // These nest an additional 'input' key inside the 'inputs' to make sure
84
+ // the input is always a dict. We need to unpack and user the inner value.
85
+ // We should try to fix this in Runnables and callbacks/tracers
86
+ // Runnables should be using a null type here not a placeholder
87
+ // dict.
88
+ return inputs.input;
89
+ }
90
+ async function _getStandardizedOutputs(run, schemaFormat) {
91
+ const { outputs } = run;
92
+ if (schemaFormat === "original") {
93
+ // Return the old schema, without standardizing anything
94
+ return outputs;
95
+ }
96
+ if (["retriever", "llm", "prompt"].includes(run.run_type)) {
97
+ return outputs;
98
+ }
99
+ // TODO: Remove this hacky check
100
+ if (outputs !== undefined &&
101
+ Object.keys(outputs).length === 1 &&
102
+ outputs?.output !== undefined) {
103
+ return outputs.output;
104
+ }
105
+ return outputs;
106
+ }
107
+ function isChatGenerationChunk(x) {
108
+ return x !== undefined && x.message !== undefined;
47
109
  }
48
110
  /**
49
111
  * Class that extends the `BaseTracer` class from the
@@ -96,6 +158,12 @@ export class LogStreamCallbackHandler extends BaseTracer {
96
158
  writable: true,
97
159
  value: void 0
98
160
  });
161
+ Object.defineProperty(this, "_schemaFormat", {
162
+ enumerable: true,
163
+ configurable: true,
164
+ writable: true,
165
+ value: "original"
166
+ });
99
167
  Object.defineProperty(this, "rootId", {
100
168
  enumerable: true,
101
169
  configurable: true,
@@ -145,6 +213,7 @@ export class LogStreamCallbackHandler extends BaseTracer {
145
213
  this.excludeNames = fields?.excludeNames;
146
214
  this.excludeTypes = fields?.excludeTypes;
147
215
  this.excludeTags = fields?.excludeTags;
216
+ this._schemaFormat = fields?._schemaFormat ?? this._schemaFormat;
148
217
  this.transformStream = new TransformStream();
149
218
  this.writer = this.transformStream.writable.getWriter();
150
219
  this.receiveStream = IterableReadableStream.fromReadableStream(this.transformStream.readable);
@@ -220,6 +289,8 @@ export class LogStreamCallbackHandler extends BaseTracer {
220
289
  path: "",
221
290
  value: {
222
291
  id: run.id,
292
+ name: run.name,
293
+ type: run.run_type,
223
294
  streamed_output: [],
224
295
  final_output: undefined,
225
296
  logs: {},
@@ -250,6 +321,9 @@ export class LogStreamCallbackHandler extends BaseTracer {
250
321
  final_output: undefined,
251
322
  end_time: undefined,
252
323
  };
324
+ if (this._schemaFormat === "streaming_events") {
325
+ logEntry.inputs = await _getStandardizedInputs(run, this._schemaFormat);
326
+ }
253
327
  await this.writer.write(new RunLogPatch({
254
328
  ops: [
255
329
  {
@@ -266,13 +340,19 @@ export class LogStreamCallbackHandler extends BaseTracer {
266
340
  if (runName === undefined) {
267
341
  return;
268
342
  }
269
- const ops = [
270
- {
271
- op: "add",
272
- path: `/logs/${runName}/final_output`,
273
- value: run.outputs,
274
- },
275
- ];
343
+ const ops = [];
344
+ if (this._schemaFormat === "streaming_events") {
345
+ ops.push({
346
+ op: "replace",
347
+ path: `/logs/${runName}/inputs`,
348
+ value: await _getStandardizedInputs(run, this._schemaFormat),
349
+ });
350
+ }
351
+ ops.push({
352
+ op: "add",
353
+ path: `/logs/${runName}/final_output`,
354
+ value: await _getStandardizedOutputs(run, this._schemaFormat),
355
+ });
276
356
  if (run.end_time !== undefined) {
277
357
  ops.push({
278
358
  op: "add",
@@ -290,7 +370,7 @@ export class LogStreamCallbackHandler extends BaseTracer {
290
370
  {
291
371
  op: "replace",
292
372
  path: "/final_output",
293
- value: run.outputs,
373
+ value: await _getStandardizedOutputs(run, this._schemaFormat),
294
374
  },
295
375
  ],
296
376
  });
@@ -301,11 +381,25 @@ export class LogStreamCallbackHandler extends BaseTracer {
301
381
  }
302
382
  }
303
383
  }
304
- async onLLMNewToken(run, token) {
384
+ async onLLMNewToken(run, token, kwargs) {
305
385
  const runName = this.keyMapByRunId[run.id];
306
386
  if (runName === undefined) {
307
387
  return;
308
388
  }
389
+ // TODO: Remove hack
390
+ const isChatModel = run.inputs.messages !== undefined;
391
+ let streamedOutputValue;
392
+ if (isChatModel) {
393
+ if (isChatGenerationChunk(kwargs?.chunk)) {
394
+ streamedOutputValue = kwargs?.chunk;
395
+ }
396
+ else {
397
+ streamedOutputValue = new AIMessageChunk(token);
398
+ }
399
+ }
400
+ else {
401
+ streamedOutputValue = token;
402
+ }
309
403
  const patch = new RunLogPatch({
310
404
  ops: [
311
405
  {
@@ -313,6 +407,11 @@ export class LogStreamCallbackHandler extends BaseTracer {
313
407
  path: `/logs/${runName}/streamed_output_str/-`,
314
408
  value: token,
315
409
  },
410
+ {
411
+ op: "add",
412
+ path: `/logs/${runName}/streamed_output/-`,
413
+ value: streamedOutputValue,
414
+ },
316
415
  ],
317
416
  });
318
417
  await this.writer.write(patch);
@@ -274,12 +274,14 @@ class FakeListChatModel extends chat_models_js_1.BaseChatModel {
274
274
  text,
275
275
  };
276
276
  }
277
- async *_streamResponseChunks(_messages, _options, _runManager) {
277
+ async *_streamResponseChunks(_messages, _options, runManager) {
278
278
  const response = this._currentResponse();
279
279
  this._incrementResponse();
280
280
  for await (const text of response) {
281
281
  await this._sleepIfRequested();
282
- yield this._createResponseChunk(text);
282
+ const chunk = this._createResponseChunk(text);
283
+ yield chunk;
284
+ void runManager?.handleLLMNewToken(text);
283
285
  }
284
286
  }
285
287
  async _sleepIfRequested() {
@@ -107,7 +107,7 @@ export declare class FakeListChatModel extends BaseChatModel {
107
107
  message: AIMessage;
108
108
  text: string;
109
109
  };
110
- _streamResponseChunks(_messages: BaseMessage[], _options: this["ParsedCallOptions"], _runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
110
+ _streamResponseChunks(_messages: BaseMessage[], _options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
111
111
  _sleepIfRequested(): Promise<void>;
112
112
  _sleep(): Promise<void>;
113
113
  _createResponseChunk(text: string): ChatGenerationChunk;
@@ -265,12 +265,14 @@ export class FakeListChatModel extends BaseChatModel {
265
265
  text,
266
266
  };
267
267
  }
268
- async *_streamResponseChunks(_messages, _options, _runManager) {
268
+ async *_streamResponseChunks(_messages, _options, runManager) {
269
269
  const response = this._currentResponse();
270
270
  this._incrementResponse();
271
271
  for await (const text of response) {
272
272
  await this._sleepIfRequested();
273
- yield this._createResponseChunk(text);
273
+ const chunk = this._createResponseChunk(text);
274
+ yield chunk;
275
+ void runManager?.handleLLMNewToken(text);
274
276
  }
275
277
  }
276
278
  async _sleepIfRequested() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.1.27-rc.0",
3
+ "version": "0.1.27-rc.2",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {