@langchain/core 0.3.31 → 0.3.33

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.
@@ -58,12 +58,12 @@ declare abstract class BaseCallbackHandlerMethodsClass {
58
58
  /**
59
59
  * Called if an LLM/ChatModel run encounters an error
60
60
  */
61
- handleLLMError?(err: Error, runId: string, parentRunId?: string, tags?: string[]): // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ handleLLMError?(err: Error, runId: string, parentRunId?: string, tags?: string[], extraParams?: Record<string, unknown>): // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
62
  Promise<any> | any;
63
63
  /**
64
64
  * Called at the end of an LLM/ChatModel run, with the output and the run ID.
65
65
  */
66
- handleLLMEnd?(output: LLMResult, runId: string, parentRunId?: string, tags?: string[]): // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ handleLLMEnd?(output: LLMResult, runId: string, parentRunId?: string, tags?: string[], extraParams?: Record<string, unknown>): // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
67
  Promise<any> | any;
68
68
  /**
69
69
  * Called at the start of a Chat Model run, with the prompt(s)
@@ -228,11 +228,11 @@ export declare abstract class BaseCallbackHandler extends BaseCallbackHandlerMet
228
228
  /**
229
229
  * Called if an LLM/ChatModel run encounters an error
230
230
  */
231
- handleLLMError?(err: any, runId: string, parentRunId?: string | undefined, tags?: string[] | undefined): any;
231
+ handleLLMError?(err: any, runId: string, parentRunId?: string | undefined, tags?: string[] | undefined, extraParams?: Record<string, unknown> | undefined): any;
232
232
  /**
233
233
  * Called at the end of an LLM/ChatModel run, with the output and the run ID.
234
234
  */
235
- handleLLMEnd?(output: LLMResult, runId: string, parentRunId?: string | undefined, tags?: string[] | undefined): any;
235
+ handleLLMEnd?(output: LLMResult, runId: string, parentRunId?: string | undefined, tags?: string[] | undefined, extraParams?: Record<string, unknown> | undefined): any;
236
236
  /**
237
237
  * Called at the start of a Chat Model run, with the prompt(s)
238
238
  * and the run ID.
@@ -199,11 +199,11 @@ class CallbackManagerForLLMRun extends BaseRunManager {
199
199
  }
200
200
  }, handler.awaitHandlers)));
201
201
  }
202
- async handleLLMError(err) {
202
+ async handleLLMError(err, _runId, _parentRunId, _tags, extraParams) {
203
203
  await Promise.all(this.handlers.map((handler) => (0, promises_js_1.consumeCallback)(async () => {
204
204
  if (!handler.ignoreLLM) {
205
205
  try {
206
- await handler.handleLLMError?.(err, this.runId, this._parentRunId, this.tags);
206
+ await handler.handleLLMError?.(err, this.runId, this._parentRunId, this.tags, extraParams);
207
207
  }
208
208
  catch (err) {
209
209
  const logFunction = handler.raiseError
@@ -217,11 +217,11 @@ class CallbackManagerForLLMRun extends BaseRunManager {
217
217
  }
218
218
  }, handler.awaitHandlers)));
219
219
  }
220
- async handleLLMEnd(output) {
220
+ async handleLLMEnd(output, _runId, _parentRunId, _tags, extraParams) {
221
221
  await Promise.all(this.handlers.map((handler) => (0, promises_js_1.consumeCallback)(async () => {
222
222
  if (!handler.ignoreLLM) {
223
223
  try {
224
- await handler.handleLLMEnd?.(output, this.runId, this._parentRunId, this.tags);
224
+ await handler.handleLLMEnd?.(output, this.runId, this._parentRunId, this.tags, extraParams);
225
225
  }
226
226
  catch (err) {
227
227
  const logFunction = handler.raiseError
@@ -77,8 +77,8 @@ export declare class CallbackManagerForRetrieverRun extends BaseRunManager imple
77
77
  }
78
78
  export declare class CallbackManagerForLLMRun extends BaseRunManager implements BaseCallbackManagerMethods {
79
79
  handleLLMNewToken(token: string, idx?: NewTokenIndices, _runId?: string, _parentRunId?: string, _tags?: string[], fields?: HandleLLMNewTokenCallbackFields): Promise<void>;
80
- handleLLMError(err: Error | unknown): Promise<void>;
81
- handleLLMEnd(output: LLMResult): Promise<void>;
80
+ handleLLMError(err: Error | unknown, _runId?: string, _parentRunId?: string, _tags?: string[], extraParams?: Record<string, unknown>): Promise<void>;
81
+ handleLLMEnd(output: LLMResult, _runId?: string, _parentRunId?: string, _tags?: string[], extraParams?: Record<string, unknown>): Promise<void>;
82
82
  }
83
83
  export declare class CallbackManagerForChainRun extends BaseRunManager implements BaseCallbackManagerMethods {
84
84
  getChild(tag?: string): CallbackManager;
@@ -192,11 +192,11 @@ export class CallbackManagerForLLMRun extends BaseRunManager {
192
192
  }
193
193
  }, handler.awaitHandlers)));
194
194
  }
195
- async handleLLMError(err) {
195
+ async handleLLMError(err, _runId, _parentRunId, _tags, extraParams) {
196
196
  await Promise.all(this.handlers.map((handler) => consumeCallback(async () => {
197
197
  if (!handler.ignoreLLM) {
198
198
  try {
199
- await handler.handleLLMError?.(err, this.runId, this._parentRunId, this.tags);
199
+ await handler.handleLLMError?.(err, this.runId, this._parentRunId, this.tags, extraParams);
200
200
  }
201
201
  catch (err) {
202
202
  const logFunction = handler.raiseError
@@ -210,11 +210,11 @@ export class CallbackManagerForLLMRun extends BaseRunManager {
210
210
  }
211
211
  }, handler.awaitHandlers)));
212
212
  }
213
- async handleLLMEnd(output) {
213
+ async handleLLMEnd(output, _runId, _parentRunId, _tags, extraParams) {
214
214
  await Promise.all(this.handlers.map((handler) => consumeCallback(async () => {
215
215
  if (!handler.ignoreLLM) {
216
216
  try {
217
- await handler.handleLLMEnd?.(output, this.runId, this._parentRunId, this.tags);
217
+ await handler.handleLLMEnd?.(output, this.runId, this._parentRunId, this.tags, extraParams);
218
218
  }
219
219
  catch (err) {
220
220
  const logFunction = handler.raiseError
@@ -148,20 +148,27 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
148
148
  };
149
149
  }
150
150
  /** @ignore */
151
- async _generateUncached(messages, parsedOptions, handledOptions) {
151
+ async _generateUncached(messages, parsedOptions, handledOptions, startedRunManagers) {
152
152
  const baseMessages = messages.map((messageList) => messageList.map(index_js_1.coerceMessageLikeToMessage));
153
- const inheritableMetadata = {
154
- ...handledOptions.metadata,
155
- ...this.getLsParams(parsedOptions),
156
- };
157
- // create callback manager and start run
158
- const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
159
- const extra = {
160
- options: parsedOptions,
161
- invocation_params: this?.invocationParams(parsedOptions),
162
- batch_size: 1,
163
- };
164
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
153
+ let runManagers;
154
+ if (startedRunManagers !== undefined &&
155
+ startedRunManagers.length === baseMessages.length) {
156
+ runManagers = startedRunManagers;
157
+ }
158
+ else {
159
+ const inheritableMetadata = {
160
+ ...handledOptions.metadata,
161
+ ...this.getLsParams(parsedOptions),
162
+ };
163
+ // create callback manager and start run
164
+ const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
165
+ const extra = {
166
+ options: parsedOptions,
167
+ invocation_params: this?.invocationParams(parsedOptions),
168
+ batch_size: 1,
169
+ };
170
+ runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
171
+ }
165
172
  const generations = [];
166
173
  const llmOutputs = [];
167
174
  // Even if stream is not explicitly called, check if model is implicitly
@@ -279,7 +286,6 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
279
286
  options: parsedOptions,
280
287
  invocation_params: this?.invocationParams(parsedOptions),
281
288
  batch_size: 1,
282
- cached: true,
283
289
  };
284
290
  const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
285
291
  // generate results
@@ -304,23 +310,45 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
304
310
  await Promise.all(cachedResults.map(async ({ result: promiseResult, runManager }, i) => {
305
311
  if (promiseResult.status === "fulfilled") {
306
312
  const result = promiseResult.value;
307
- generations[i] = result;
313
+ generations[i] = result.map((result) => {
314
+ if ("message" in result &&
315
+ (0, index_js_1.isBaseMessage)(result.message) &&
316
+ (0, index_js_1.isAIMessage)(result.message)) {
317
+ // eslint-disable-next-line no-param-reassign
318
+ result.message.usage_metadata = {
319
+ input_tokens: 0,
320
+ output_tokens: 0,
321
+ total_tokens: 0,
322
+ };
323
+ }
324
+ // eslint-disable-next-line no-param-reassign
325
+ result.generationInfo = {
326
+ ...result.generationInfo,
327
+ tokenUsage: {},
328
+ };
329
+ return result;
330
+ });
308
331
  if (result.length) {
309
332
  await runManager?.handleLLMNewToken(result[0].text);
310
333
  }
311
334
  return runManager?.handleLLMEnd({
312
335
  generations: [result],
336
+ }, undefined, undefined, undefined, {
337
+ cached: true,
313
338
  });
314
339
  }
315
340
  else {
316
341
  // status === "rejected"
317
- await runManager?.handleLLMError(promiseResult.reason);
342
+ await runManager?.handleLLMError(promiseResult.reason, undefined, undefined, undefined, {
343
+ cached: true,
344
+ });
318
345
  return Promise.reject(promiseResult.reason);
319
346
  }
320
347
  }));
321
348
  const output = {
322
349
  generations,
323
350
  missingPromptIndices,
351
+ startedRunManagers: runManagers,
324
352
  };
325
353
  // This defines RUN_KEY as a non-enumerable property on the output object
326
354
  // so that it is not serialized when the output is stringified, and so that
@@ -357,7 +385,7 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
357
385
  }
358
386
  const { cache } = this;
359
387
  const llmStringKey = this._getSerializedCacheKeyParametersForCall(callOptions);
360
- const { generations, missingPromptIndices } = await this._generateCached({
388
+ const { generations, missingPromptIndices, startedRunManagers } = await this._generateCached({
361
389
  messages: baseMessages,
362
390
  cache,
363
391
  llmStringKey,
@@ -366,7 +394,9 @@ class BaseChatModel extends base_js_1.BaseLanguageModel {
366
394
  });
367
395
  let llmOutput = {};
368
396
  if (missingPromptIndices.length > 0) {
369
- const results = await this._generateUncached(missingPromptIndices.map((i) => baseMessages[i]), callOptions, runnableConfig);
397
+ const results = await this._generateUncached(missingPromptIndices.map((i) => baseMessages[i]), callOptions, runnableConfig, startedRunManagers !== undefined
398
+ ? missingPromptIndices.map((i) => startedRunManagers?.[i])
399
+ : undefined);
370
400
  await Promise.all(results.generations.map(async (generation, index) => {
371
401
  const promptIndex = missingPromptIndices[index];
372
402
  generations[promptIndex] = generation;
@@ -104,7 +104,7 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
104
104
  _streamIterator(input: BaseLanguageModelInput, options?: CallOptions): AsyncGenerator<OutputMessageType>;
105
105
  getLsParams(options: this["ParsedCallOptions"]): LangSmithParams;
106
106
  /** @ignore */
107
- _generateUncached(messages: BaseMessageLike[][], parsedOptions: this["ParsedCallOptions"], handledOptions: RunnableConfig): Promise<LLMResult>;
107
+ _generateUncached(messages: BaseMessageLike[][], parsedOptions: this["ParsedCallOptions"], handledOptions: RunnableConfig, startedRunManagers?: CallbackManagerForLLMRun[]): Promise<LLMResult>;
108
108
  _generateCached({ messages, cache, llmStringKey, parsedOptions, handledOptions, }: {
109
109
  messages: BaseMessageLike[][];
110
110
  cache: BaseCache<Generation[]>;
@@ -113,6 +113,7 @@ export declare abstract class BaseChatModel<CallOptions extends BaseChatModelCal
113
113
  handledOptions: RunnableConfig;
114
114
  }): Promise<LLMResult & {
115
115
  missingPromptIndices: number[];
116
+ startedRunManagers?: CallbackManagerForLLMRun[];
116
117
  }>;
117
118
  /**
118
119
  * Generates chat based on the input messages.
@@ -1,5 +1,5 @@
1
1
  import { zodToJsonSchema } from "zod-to-json-schema";
2
- import { AIMessage, HumanMessage, coerceMessageLikeToMessage, isAIMessageChunk, } from "../messages/index.js";
2
+ import { AIMessage, HumanMessage, coerceMessageLikeToMessage, isAIMessageChunk, isBaseMessage, isAIMessage, } from "../messages/index.js";
3
3
  import { RUN_KEY, } from "../outputs.js";
4
4
  import { BaseLanguageModel, } from "./base.js";
5
5
  import { CallbackManager, } from "../callbacks/manager.js";
@@ -144,20 +144,27 @@ export class BaseChatModel extends BaseLanguageModel {
144
144
  };
145
145
  }
146
146
  /** @ignore */
147
- async _generateUncached(messages, parsedOptions, handledOptions) {
147
+ async _generateUncached(messages, parsedOptions, handledOptions, startedRunManagers) {
148
148
  const baseMessages = messages.map((messageList) => messageList.map(coerceMessageLikeToMessage));
149
- const inheritableMetadata = {
150
- ...handledOptions.metadata,
151
- ...this.getLsParams(parsedOptions),
152
- };
153
- // create callback manager and start run
154
- const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
155
- const extra = {
156
- options: parsedOptions,
157
- invocation_params: this?.invocationParams(parsedOptions),
158
- batch_size: 1,
159
- };
160
- const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
149
+ let runManagers;
150
+ if (startedRunManagers !== undefined &&
151
+ startedRunManagers.length === baseMessages.length) {
152
+ runManagers = startedRunManagers;
153
+ }
154
+ else {
155
+ const inheritableMetadata = {
156
+ ...handledOptions.metadata,
157
+ ...this.getLsParams(parsedOptions),
158
+ };
159
+ // create callback manager and start run
160
+ const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, inheritableMetadata, this.metadata, { verbose: this.verbose });
161
+ const extra = {
162
+ options: parsedOptions,
163
+ invocation_params: this?.invocationParams(parsedOptions),
164
+ batch_size: 1,
165
+ };
166
+ runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
167
+ }
161
168
  const generations = [];
162
169
  const llmOutputs = [];
163
170
  // Even if stream is not explicitly called, check if model is implicitly
@@ -275,7 +282,6 @@ export class BaseChatModel extends BaseLanguageModel {
275
282
  options: parsedOptions,
276
283
  invocation_params: this?.invocationParams(parsedOptions),
277
284
  batch_size: 1,
278
- cached: true,
279
285
  };
280
286
  const runManagers = await callbackManager_?.handleChatModelStart(this.toJSON(), baseMessages, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions.runName);
281
287
  // generate results
@@ -300,23 +306,45 @@ export class BaseChatModel extends BaseLanguageModel {
300
306
  await Promise.all(cachedResults.map(async ({ result: promiseResult, runManager }, i) => {
301
307
  if (promiseResult.status === "fulfilled") {
302
308
  const result = promiseResult.value;
303
- generations[i] = result;
309
+ generations[i] = result.map((result) => {
310
+ if ("message" in result &&
311
+ isBaseMessage(result.message) &&
312
+ isAIMessage(result.message)) {
313
+ // eslint-disable-next-line no-param-reassign
314
+ result.message.usage_metadata = {
315
+ input_tokens: 0,
316
+ output_tokens: 0,
317
+ total_tokens: 0,
318
+ };
319
+ }
320
+ // eslint-disable-next-line no-param-reassign
321
+ result.generationInfo = {
322
+ ...result.generationInfo,
323
+ tokenUsage: {},
324
+ };
325
+ return result;
326
+ });
304
327
  if (result.length) {
305
328
  await runManager?.handleLLMNewToken(result[0].text);
306
329
  }
307
330
  return runManager?.handleLLMEnd({
308
331
  generations: [result],
332
+ }, undefined, undefined, undefined, {
333
+ cached: true,
309
334
  });
310
335
  }
311
336
  else {
312
337
  // status === "rejected"
313
- await runManager?.handleLLMError(promiseResult.reason);
338
+ await runManager?.handleLLMError(promiseResult.reason, undefined, undefined, undefined, {
339
+ cached: true,
340
+ });
314
341
  return Promise.reject(promiseResult.reason);
315
342
  }
316
343
  }));
317
344
  const output = {
318
345
  generations,
319
346
  missingPromptIndices,
347
+ startedRunManagers: runManagers,
320
348
  };
321
349
  // This defines RUN_KEY as a non-enumerable property on the output object
322
350
  // so that it is not serialized when the output is stringified, and so that
@@ -353,7 +381,7 @@ export class BaseChatModel extends BaseLanguageModel {
353
381
  }
354
382
  const { cache } = this;
355
383
  const llmStringKey = this._getSerializedCacheKeyParametersForCall(callOptions);
356
- const { generations, missingPromptIndices } = await this._generateCached({
384
+ const { generations, missingPromptIndices, startedRunManagers } = await this._generateCached({
357
385
  messages: baseMessages,
358
386
  cache,
359
387
  llmStringKey,
@@ -362,7 +390,9 @@ export class BaseChatModel extends BaseLanguageModel {
362
390
  });
363
391
  let llmOutput = {};
364
392
  if (missingPromptIndices.length > 0) {
365
- const results = await this._generateUncached(missingPromptIndices.map((i) => baseMessages[i]), callOptions, runnableConfig);
393
+ const results = await this._generateUncached(missingPromptIndices.map((i) => baseMessages[i]), callOptions, runnableConfig, startedRunManagers !== undefined
394
+ ? missingPromptIndices.map((i) => startedRunManagers?.[i])
395
+ : undefined);
366
396
  await Promise.all(results.generations.map(async (generation, index) => {
367
397
  const promptIndex = missingPromptIndices[index];
368
398
  generations[promptIndex] = generation;
@@ -126,14 +126,21 @@ class BaseLLM extends base_js_1.BaseLanguageModel {
126
126
  return llmResults;
127
127
  }
128
128
  /** @ignore */
129
- async _generateUncached(prompts, parsedOptions, handledOptions) {
130
- const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
131
- const extra = {
132
- options: parsedOptions,
133
- invocation_params: this?.invocationParams(parsedOptions),
134
- batch_size: prompts.length,
135
- };
136
- const runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions?.runName);
129
+ async _generateUncached(prompts, parsedOptions, handledOptions, startedRunManagers) {
130
+ let runManagers;
131
+ if (startedRunManagers !== undefined &&
132
+ startedRunManagers.length === prompts.length) {
133
+ runManagers = startedRunManagers;
134
+ }
135
+ else {
136
+ const callbackManager_ = await manager_js_1.CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
137
+ const extra = {
138
+ options: parsedOptions,
139
+ invocation_params: this?.invocationParams(parsedOptions),
140
+ batch_size: prompts.length,
141
+ };
142
+ runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions?.runName);
143
+ }
137
144
  // Even if stream is not explicitly called, check if model is implicitly
138
145
  // called from streamEvents() or streamLog() to get all streamed events.
139
146
  // Bail out if _streamResponseChunks not overridden
@@ -191,7 +198,6 @@ class BaseLLM extends base_js_1.BaseLanguageModel {
191
198
  options: parsedOptions,
192
199
  invocation_params: this?.invocationParams(parsedOptions),
193
200
  batch_size: prompts.length,
194
- cached: true,
195
201
  };
196
202
  const runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, runId, undefined, extra, undefined, undefined, handledOptions?.runName);
197
203
  // generate results
@@ -214,23 +220,35 @@ class BaseLLM extends base_js_1.BaseLanguageModel {
214
220
  await Promise.all(cachedResults.map(async ({ result: promiseResult, runManager }, i) => {
215
221
  if (promiseResult.status === "fulfilled") {
216
222
  const result = promiseResult.value;
217
- generations[i] = result;
223
+ generations[i] = result.map((result) => {
224
+ // eslint-disable-next-line no-param-reassign
225
+ result.generationInfo = {
226
+ ...result.generationInfo,
227
+ tokenUsage: {},
228
+ };
229
+ return result;
230
+ });
218
231
  if (result.length) {
219
232
  await runManager?.handleLLMNewToken(result[0].text);
220
233
  }
221
234
  return runManager?.handleLLMEnd({
222
235
  generations: [result],
236
+ }, undefined, undefined, undefined, {
237
+ cached: true,
223
238
  });
224
239
  }
225
240
  else {
226
241
  // status === "rejected"
227
- await runManager?.handleLLMError(promiseResult.reason);
242
+ await runManager?.handleLLMError(promiseResult.reason, undefined, undefined, undefined, {
243
+ cached: true,
244
+ });
228
245
  return Promise.reject(promiseResult.reason);
229
246
  }
230
247
  }));
231
248
  const output = {
232
249
  generations,
233
250
  missingPromptIndices,
251
+ startedRunManagers: runManagers,
234
252
  };
235
253
  // This defines RUN_KEY as a non-enumerable property on the output object
236
254
  // so that it is not serialized when the output is stringified, and so that
@@ -264,7 +282,7 @@ class BaseLLM extends base_js_1.BaseLanguageModel {
264
282
  }
265
283
  const { cache } = this;
266
284
  const llmStringKey = this._getSerializedCacheKeyParametersForCall(callOptions);
267
- const { generations, missingPromptIndices } = await this._generateCached({
285
+ const { generations, missingPromptIndices, startedRunManagers } = await this._generateCached({
268
286
  prompts,
269
287
  cache,
270
288
  llmStringKey,
@@ -274,7 +292,9 @@ class BaseLLM extends base_js_1.BaseLanguageModel {
274
292
  });
275
293
  let llmOutput = {};
276
294
  if (missingPromptIndices.length > 0) {
277
- const results = await this._generateUncached(missingPromptIndices.map((i) => prompts[i]), callOptions, runnableConfig);
295
+ const results = await this._generateUncached(missingPromptIndices.map((i) => prompts[i]), callOptions, runnableConfig, startedRunManagers !== undefined
296
+ ? missingPromptIndices.map((i) => startedRunManagers?.[i])
297
+ : undefined);
278
298
  await Promise.all(results.generations.map(async (generation, index) => {
279
299
  const promptIndex = missingPromptIndices[index];
280
300
  generations[promptIndex] = generation;
@@ -55,7 +55,7 @@ export declare abstract class BaseLLM<CallOptions extends BaseLLMCallOptions = B
55
55
  invocationParams(_options?: this["ParsedCallOptions"]): any;
56
56
  _flattenLLMResult(llmResult: LLMResult): LLMResult[];
57
57
  /** @ignore */
58
- _generateUncached(prompts: string[], parsedOptions: this["ParsedCallOptions"], handledOptions: BaseCallbackConfig): Promise<LLMResult>;
58
+ _generateUncached(prompts: string[], parsedOptions: this["ParsedCallOptions"], handledOptions: BaseCallbackConfig, startedRunManagers?: CallbackManagerForLLMRun[]): Promise<LLMResult>;
59
59
  _generateCached({ prompts, cache, llmStringKey, parsedOptions, handledOptions, runId, }: {
60
60
  prompts: string[];
61
61
  cache: BaseCache<Generation[]>;
@@ -65,6 +65,7 @@ export declare abstract class BaseLLM<CallOptions extends BaseLLMCallOptions = B
65
65
  runId?: string;
66
66
  }): Promise<LLMResult & {
67
67
  missingPromptIndices: number[];
68
+ startedRunManagers?: CallbackManagerForLLMRun[];
68
69
  }>;
69
70
  /**
70
71
  * Run the LLM on the given prompts and input, handling caching.
@@ -123,14 +123,21 @@ export class BaseLLM extends BaseLanguageModel {
123
123
  return llmResults;
124
124
  }
125
125
  /** @ignore */
126
- async _generateUncached(prompts, parsedOptions, handledOptions) {
127
- const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
128
- const extra = {
129
- options: parsedOptions,
130
- invocation_params: this?.invocationParams(parsedOptions),
131
- batch_size: prompts.length,
132
- };
133
- const runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions?.runName);
126
+ async _generateUncached(prompts, parsedOptions, handledOptions, startedRunManagers) {
127
+ let runManagers;
128
+ if (startedRunManagers !== undefined &&
129
+ startedRunManagers.length === prompts.length) {
130
+ runManagers = startedRunManagers;
131
+ }
132
+ else {
133
+ const callbackManager_ = await CallbackManager.configure(handledOptions.callbacks, this.callbacks, handledOptions.tags, this.tags, handledOptions.metadata, this.metadata, { verbose: this.verbose });
134
+ const extra = {
135
+ options: parsedOptions,
136
+ invocation_params: this?.invocationParams(parsedOptions),
137
+ batch_size: prompts.length,
138
+ };
139
+ runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, handledOptions.runId, undefined, extra, undefined, undefined, handledOptions?.runName);
140
+ }
134
141
  // Even if stream is not explicitly called, check if model is implicitly
135
142
  // called from streamEvents() or streamLog() to get all streamed events.
136
143
  // Bail out if _streamResponseChunks not overridden
@@ -188,7 +195,6 @@ export class BaseLLM extends BaseLanguageModel {
188
195
  options: parsedOptions,
189
196
  invocation_params: this?.invocationParams(parsedOptions),
190
197
  batch_size: prompts.length,
191
- cached: true,
192
198
  };
193
199
  const runManagers = await callbackManager_?.handleLLMStart(this.toJSON(), prompts, runId, undefined, extra, undefined, undefined, handledOptions?.runName);
194
200
  // generate results
@@ -211,23 +217,35 @@ export class BaseLLM extends BaseLanguageModel {
211
217
  await Promise.all(cachedResults.map(async ({ result: promiseResult, runManager }, i) => {
212
218
  if (promiseResult.status === "fulfilled") {
213
219
  const result = promiseResult.value;
214
- generations[i] = result;
220
+ generations[i] = result.map((result) => {
221
+ // eslint-disable-next-line no-param-reassign
222
+ result.generationInfo = {
223
+ ...result.generationInfo,
224
+ tokenUsage: {},
225
+ };
226
+ return result;
227
+ });
215
228
  if (result.length) {
216
229
  await runManager?.handleLLMNewToken(result[0].text);
217
230
  }
218
231
  return runManager?.handleLLMEnd({
219
232
  generations: [result],
233
+ }, undefined, undefined, undefined, {
234
+ cached: true,
220
235
  });
221
236
  }
222
237
  else {
223
238
  // status === "rejected"
224
- await runManager?.handleLLMError(promiseResult.reason);
239
+ await runManager?.handleLLMError(promiseResult.reason, undefined, undefined, undefined, {
240
+ cached: true,
241
+ });
225
242
  return Promise.reject(promiseResult.reason);
226
243
  }
227
244
  }));
228
245
  const output = {
229
246
  generations,
230
247
  missingPromptIndices,
248
+ startedRunManagers: runManagers,
231
249
  };
232
250
  // This defines RUN_KEY as a non-enumerable property on the output object
233
251
  // so that it is not serialized when the output is stringified, and so that
@@ -261,7 +279,7 @@ export class BaseLLM extends BaseLanguageModel {
261
279
  }
262
280
  const { cache } = this;
263
281
  const llmStringKey = this._getSerializedCacheKeyParametersForCall(callOptions);
264
- const { generations, missingPromptIndices } = await this._generateCached({
282
+ const { generations, missingPromptIndices, startedRunManagers } = await this._generateCached({
265
283
  prompts,
266
284
  cache,
267
285
  llmStringKey,
@@ -271,7 +289,9 @@ export class BaseLLM extends BaseLanguageModel {
271
289
  });
272
290
  let llmOutput = {};
273
291
  if (missingPromptIndices.length > 0) {
274
- const results = await this._generateUncached(missingPromptIndices.map((i) => prompts[i]), callOptions, runnableConfig);
292
+ const results = await this._generateUncached(missingPromptIndices.map((i) => prompts[i]), callOptions, runnableConfig, startedRunManagers !== undefined
293
+ ? missingPromptIndices.map((i) => startedRunManagers?.[i])
294
+ : undefined);
275
295
  await Promise.all(results.generations.map(async (generation, index) => {
276
296
  const promptIndex = missingPromptIndices[index];
277
297
  generations[promptIndex] = generation;
@@ -178,7 +178,7 @@ class BaseTracer extends base_js_1.BaseCallbackHandler {
178
178
  await this.onLLMStart?.(run);
179
179
  return run;
180
180
  }
181
- async handleLLMEnd(output, runId) {
181
+ async handleLLMEnd(output, runId, _parentRunId, _tags, extraParams) {
182
182
  const run = this.runMap.get(runId);
183
183
  if (!run || run?.run_type !== "llm") {
184
184
  throw new Error("No LLM run to end.");
@@ -189,11 +189,12 @@ class BaseTracer extends base_js_1.BaseCallbackHandler {
189
189
  name: "end",
190
190
  time: new Date(run.end_time).toISOString(),
191
191
  });
192
+ run.extra = { ...run.extra, ...extraParams };
192
193
  await this.onLLMEnd?.(run);
193
194
  await this._endTrace(run);
194
195
  return run;
195
196
  }
196
- async handleLLMError(error, runId) {
197
+ async handleLLMError(error, runId, _parentRunId, _tags, extraParams) {
197
198
  const run = this.runMap.get(runId);
198
199
  if (!run || run?.run_type !== "llm") {
199
200
  throw new Error("No LLM run to end.");
@@ -204,6 +205,7 @@ class BaseTracer extends base_js_1.BaseCallbackHandler {
204
205
  name: "error",
205
206
  time: new Date(run.end_time).toISOString(),
206
207
  });
208
+ run.extra = { ...run.extra, ...extraParams };
207
209
  await this.onLLMError?.(run);
208
210
  await this._endTrace(run);
209
211
  return run;
@@ -124,8 +124,8 @@ export declare abstract class BaseTracer extends BaseCallbackHandler {
124
124
  attachments?: import("langsmith/schemas").Attachments | undefined;
125
125
  };
126
126
  handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: KVMap, tags?: string[], metadata?: KVMap, name?: string): Promise<Run>;
127
- handleLLMEnd(output: LLMResult, runId: string): Promise<Run>;
128
- handleLLMError(error: unknown, runId: string): Promise<Run>;
127
+ handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string, _tags?: string[], extraParams?: Record<string, unknown>): Promise<Run>;
128
+ handleLLMError(error: unknown, runId: string, _parentRunId?: string, _tags?: string[], extraParams?: Record<string, unknown>): Promise<Run>;
129
129
  /**
130
130
  * Create and add a run to the run map for chain start events.
131
131
  * This must sometimes be done synchronously to avoid race conditions
@@ -174,7 +174,7 @@ export class BaseTracer extends BaseCallbackHandler {
174
174
  await this.onLLMStart?.(run);
175
175
  return run;
176
176
  }
177
- async handleLLMEnd(output, runId) {
177
+ async handleLLMEnd(output, runId, _parentRunId, _tags, extraParams) {
178
178
  const run = this.runMap.get(runId);
179
179
  if (!run || run?.run_type !== "llm") {
180
180
  throw new Error("No LLM run to end.");
@@ -185,11 +185,12 @@ export class BaseTracer extends BaseCallbackHandler {
185
185
  name: "end",
186
186
  time: new Date(run.end_time).toISOString(),
187
187
  });
188
+ run.extra = { ...run.extra, ...extraParams };
188
189
  await this.onLLMEnd?.(run);
189
190
  await this._endTrace(run);
190
191
  return run;
191
192
  }
192
- async handleLLMError(error, runId) {
193
+ async handleLLMError(error, runId, _parentRunId, _tags, extraParams) {
193
194
  const run = this.runMap.get(runId);
194
195
  if (!run || run?.run_type !== "llm") {
195
196
  throw new Error("No LLM run to end.");
@@ -200,6 +201,7 @@ export class BaseTracer extends BaseCallbackHandler {
200
201
  name: "error",
201
202
  time: new Date(run.end_time).toISOString(),
202
203
  });
204
+ run.extra = { ...run.extra, ...extraParams };
203
205
  await this.onLLMError?.(run);
204
206
  await this._endTrace(run);
205
207
  return run;
@@ -72,6 +72,7 @@ class LangChainTracer extends base_js_1.BaseTracer {
72
72
  trace_id: run.trace_id,
73
73
  dotted_order: run.dotted_order,
74
74
  parent_run_id: run.parent_run_id,
75
+ extra: run.extra,
75
76
  };
76
77
  await this.client.updateRun(run.id, runUpdate);
77
78
  }
@@ -69,6 +69,7 @@ export class LangChainTracer extends BaseTracer {
69
69
  trace_id: run.trace_id,
70
70
  dotted_order: run.dotted_order,
71
71
  parent_run_id: run.parent_run_id,
72
+ extra: run.extra,
72
73
  };
73
74
  await this.client.updateRun(run.id, runUpdate);
74
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.3.31",
3
+ "version": "0.3.33",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {
@@ -38,7 +38,7 @@
38
38
  "camelcase": "6",
39
39
  "decamelize": "1.2.0",
40
40
  "js-tiktoken": "^1.0.12",
41
- "langsmith": "^0.2.8",
41
+ "langsmith": ">=0.2.8 <0.4.0",
42
42
  "mustache": "^4.2.0",
43
43
  "p-queue": "^6.6.2",
44
44
  "p-retry": "4",