@posthog/ai 5.2.2 → 6.0.0

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.
Files changed (60) hide show
  1. package/LICENSE +245 -0
  2. package/{lib → dist}/anthropic/index.cjs +44 -17
  3. package/dist/anthropic/index.cjs.map +1 -0
  4. package/{lib → dist}/anthropic/index.mjs +41 -10
  5. package/dist/anthropic/index.mjs.map +1 -0
  6. package/{lib → dist}/gemini/index.cjs +68 -26
  7. package/dist/gemini/index.cjs.map +1 -0
  8. package/{lib → dist}/gemini/index.d.ts +0 -1
  9. package/{lib → dist}/gemini/index.mjs +67 -25
  10. package/dist/gemini/index.mjs.map +1 -0
  11. package/{lib → dist}/index.cjs +875 -601
  12. package/dist/index.cjs.map +1 -0
  13. package/{lib → dist}/index.d.ts +3 -3
  14. package/{lib → dist}/index.mjs +859 -579
  15. package/dist/index.mjs.map +1 -0
  16. package/{lib → dist}/langchain/index.cjs +178 -118
  17. package/dist/langchain/index.cjs.map +1 -0
  18. package/{lib → dist}/langchain/index.d.ts +1 -0
  19. package/{lib → dist}/langchain/index.mjs +175 -112
  20. package/dist/langchain/index.mjs.map +1 -0
  21. package/{lib → dist}/openai/index.cjs +113 -6
  22. package/dist/openai/index.cjs.map +1 -0
  23. package/{lib → dist}/openai/index.mjs +112 -5
  24. package/dist/openai/index.mjs.map +1 -0
  25. package/{lib → dist}/vercel/index.cjs +117 -82
  26. package/dist/vercel/index.cjs.map +1 -0
  27. package/{lib → dist}/vercel/index.d.ts +2 -2
  28. package/{lib → dist}/vercel/index.mjs +118 -81
  29. package/dist/vercel/index.mjs.map +1 -0
  30. package/package.json +45 -35
  31. package/CHANGELOG.md +0 -89
  32. package/index.ts +0 -1
  33. package/lib/anthropic/index.cjs.map +0 -1
  34. package/lib/anthropic/index.mjs.map +0 -1
  35. package/lib/gemini/index.cjs.map +0 -1
  36. package/lib/gemini/index.mjs.map +0 -1
  37. package/lib/index.cjs.map +0 -1
  38. package/lib/index.mjs.map +0 -1
  39. package/lib/langchain/index.cjs.map +0 -1
  40. package/lib/langchain/index.mjs.map +0 -1
  41. package/lib/openai/index.cjs.map +0 -1
  42. package/lib/openai/index.mjs.map +0 -1
  43. package/lib/vercel/index.cjs.map +0 -1
  44. package/lib/vercel/index.mjs.map +0 -1
  45. package/src/anthropic/index.ts +0 -211
  46. package/src/gemini/index.ts +0 -254
  47. package/src/index.ts +0 -13
  48. package/src/langchain/callbacks.ts +0 -640
  49. package/src/langchain/index.ts +0 -1
  50. package/src/openai/azure.ts +0 -481
  51. package/src/openai/index.ts +0 -498
  52. package/src/utils.ts +0 -287
  53. package/src/vercel/index.ts +0 -1
  54. package/src/vercel/middleware.ts +0 -393
  55. package/tests/callbacks.test.ts +0 -48
  56. package/tests/gemini.test.ts +0 -344
  57. package/tests/openai.test.ts +0 -403
  58. package/tsconfig.json +0 -10
  59. /package/{lib → dist}/anthropic/index.d.ts +0 -0
  60. /package/{lib → dist}/openai/index.d.ts +0 -0
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var openai = require('openai');
6
4
  var uuid = require('uuid');
7
5
  var buffer = require('buffer');
@@ -9,28 +7,24 @@ var ai = require('ai');
9
7
  var AnthropicOriginal = require('@anthropic-ai/sdk');
10
8
  var genai = require('@google/genai');
11
9
 
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
-
14
- function _interopNamespace(e) {
15
- if (e && e.__esModule) return e;
16
- var n = Object.create(null);
17
- if (e) {
18
- Object.keys(e).forEach(function (k) {
19
- if (k !== 'default') {
20
- var d = Object.getOwnPropertyDescriptor(e, k);
21
- Object.defineProperty(n, k, d.get ? d : {
22
- enumerable: true,
23
- get: function () { return e[k]; }
10
+ function _interopNamespaceDefault(e) {
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
24
21
  });
25
- }
26
- });
27
- }
28
- n["default"] = e;
29
- return Object.freeze(n);
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
30
25
  }
31
26
 
32
- var uuid__namespace = /*#__PURE__*/_interopNamespace(uuid);
33
- var AnthropicOriginal__default = /*#__PURE__*/_interopDefaultLegacy(AnthropicOriginal);
27
+ var uuid__namespace = /*#__PURE__*/_interopNamespaceDefault(uuid);
34
28
 
35
29
  // limit large outputs by truncating to 200kb (approx 200k bytes)
36
30
  const MAX_OUTPUT_SIZE = 200000;
@@ -49,32 +43,173 @@ const getModelParams = params => {
49
43
  return modelParams;
50
44
  };
51
45
  const formatResponseAnthropic = response => {
52
- // Example approach if "response.content" holds array of text segments, etc.
53
46
  const output = [];
47
+ const content = [];
54
48
  for (const choice of response.content ?? []) {
55
- if (choice?.text) {
56
- output.push({
57
- role: 'assistant',
58
- content: choice.text
49
+ if (choice?.type === 'text' && choice?.text) {
50
+ content.push({
51
+ type: 'text',
52
+ text: choice.text
53
+ });
54
+ } else if (choice?.type === 'tool_use' && choice?.name && choice?.id) {
55
+ content.push({
56
+ type: 'function',
57
+ id: choice.id,
58
+ function: {
59
+ name: choice.name,
60
+ arguments: choice.input || {}
61
+ }
59
62
  });
60
63
  }
61
64
  }
65
+ if (content.length > 0) {
66
+ output.push({
67
+ role: 'assistant',
68
+ content
69
+ });
70
+ }
62
71
  return output;
63
72
  };
64
73
  const formatResponseOpenAI = response => {
65
74
  const output = [];
66
- for (const choice of response.choices ?? []) {
67
- if (choice.message?.content) {
75
+ if (response.choices) {
76
+ for (const choice of response.choices) {
77
+ const content = [];
78
+ let role = 'assistant';
79
+ if (choice.message) {
80
+ if (choice.message.role) {
81
+ role = choice.message.role;
82
+ }
83
+ if (choice.message.content) {
84
+ content.push({
85
+ type: 'text',
86
+ text: choice.message.content
87
+ });
88
+ }
89
+ if (choice.message.tool_calls) {
90
+ for (const toolCall of choice.message.tool_calls) {
91
+ content.push({
92
+ type: 'function',
93
+ id: toolCall.id,
94
+ function: {
95
+ name: toolCall.function.name,
96
+ arguments: toolCall.function.arguments
97
+ }
98
+ });
99
+ }
100
+ }
101
+ }
102
+ if (content.length > 0) {
103
+ output.push({
104
+ role,
105
+ content
106
+ });
107
+ }
108
+ }
109
+ }
110
+ // Handle Responses API format
111
+ if (response.output) {
112
+ const content = [];
113
+ let role = 'assistant';
114
+ for (const item of response.output) {
115
+ if (item.type === 'message') {
116
+ role = item.role;
117
+ if (item.content && Array.isArray(item.content)) {
118
+ for (const contentItem of item.content) {
119
+ if (contentItem.type === 'output_text' && contentItem.text) {
120
+ content.push({
121
+ type: 'text',
122
+ text: contentItem.text
123
+ });
124
+ } else if (contentItem.text) {
125
+ content.push({
126
+ type: 'text',
127
+ text: contentItem.text
128
+ });
129
+ } else if (contentItem.type === 'input_image' && contentItem.image_url) {
130
+ content.push({
131
+ type: 'image',
132
+ image: contentItem.image_url
133
+ });
134
+ }
135
+ }
136
+ } else if (item.content) {
137
+ content.push({
138
+ type: 'text',
139
+ text: String(item.content)
140
+ });
141
+ }
142
+ } else if (item.type === 'function_call') {
143
+ content.push({
144
+ type: 'function',
145
+ id: item.call_id || item.id || '',
146
+ function: {
147
+ name: item.name,
148
+ arguments: item.arguments || {}
149
+ }
150
+ });
151
+ }
152
+ }
153
+ if (content.length > 0) {
68
154
  output.push({
69
- role: choice.message.role,
70
- content: choice.message.content
155
+ role,
156
+ content
71
157
  });
72
158
  }
73
159
  }
74
160
  return output;
75
161
  };
162
+ const formatResponseGemini = response => {
163
+ const output = [];
164
+ if (response.candidates && Array.isArray(response.candidates)) {
165
+ for (const candidate of response.candidates) {
166
+ if (candidate.content && candidate.content.parts) {
167
+ const content = [];
168
+ for (const part of candidate.content.parts) {
169
+ if (part.text) {
170
+ content.push({
171
+ type: 'text',
172
+ text: part.text
173
+ });
174
+ } else if (part.functionCall) {
175
+ content.push({
176
+ type: 'function',
177
+ function: {
178
+ name: part.functionCall.name,
179
+ arguments: part.functionCall.args
180
+ }
181
+ });
182
+ }
183
+ }
184
+ if (content.length > 0) {
185
+ output.push({
186
+ role: 'assistant',
187
+ content
188
+ });
189
+ }
190
+ } else if (candidate.text) {
191
+ output.push({
192
+ role: 'assistant',
193
+ content: [{
194
+ type: 'text',
195
+ text: candidate.text
196
+ }]
197
+ });
198
+ }
199
+ }
200
+ } else if (response.text) {
201
+ output.push({
202
+ role: 'assistant',
203
+ content: [{
204
+ type: 'text',
205
+ text: response.text
206
+ }]
207
+ });
208
+ }
209
+ return output;
210
+ };
76
211
  const mergeSystemPrompt = (params, provider) => {
77
- if (provider == 'anthropic') {
212
+ {
78
213
  const messages = params.messages || [];
79
214
  if (!params.system) {
80
215
  return messages;
@@ -85,7 +220,6 @@ const mergeSystemPrompt = (params, provider) => {
85
220
  content: systemMessage
86
221
  }, ...messages];
87
222
  }
88
- return params.messages;
89
223
  };
90
224
  const withPrivacyMode = (client, privacyMode, input) => {
91
225
  return client.privacy_mode || privacyMode ? null : input;
@@ -103,6 +237,35 @@ const truncate = str => {
103
237
  return str;
104
238
  }
105
239
  };
240
+ /**
241
+ * Extract available tool calls from the request parameters.
242
+ * These are the tools provided to the LLM, not the tool calls in the response.
243
+ */
244
+ const extractAvailableToolCalls = (provider, params) => {
245
+ if (provider === 'anthropic') {
246
+ if (params.tools) {
247
+ return params.tools;
248
+ }
249
+ return null;
250
+ } else if (provider === 'gemini') {
251
+ if (params.config && params.config.tools) {
252
+ return params.config.tools;
253
+ }
254
+ return null;
255
+ } else if (provider === 'openai') {
256
+ if (params.tools) {
257
+ return params.tools;
258
+ }
259
+ return null;
260
+ } else if (provider === 'vercel') {
261
+ // Vercel AI SDK stores tools in params.mode.tools when mode type is 'regular'
262
+ if (params.mode?.type === 'regular' && params.mode.tools) {
263
+ return params.mode.tools;
264
+ }
265
+ return null;
266
+ }
267
+ return null;
268
+ };
106
269
  function sanitizeValues(obj) {
107
270
  if (obj === undefined || obj === null) {
108
271
  return obj;
@@ -222,13 +385,13 @@ class PostHogOpenAI extends openai.OpenAI {
222
385
  this.responses = new WrappedResponses$1(this, this.phClient);
223
386
  }
224
387
  }
225
- class WrappedChat$1 extends Chat {
388
+ let WrappedChat$1 = class WrappedChat extends Chat {
226
389
  constructor(parentClient, phClient) {
227
390
  super(parentClient);
228
391
  this.completions = new WrappedCompletions$1(parentClient, phClient);
229
392
  }
230
- }
231
- class WrappedCompletions$1 extends Completions {
393
+ };
394
+ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
232
395
  constructor(client, phClient) {
233
396
  super(client);
234
397
  this.phClient = phClient;
@@ -272,6 +435,7 @@ class WrappedCompletions$1 extends Completions {
272
435
  }
273
436
  }
274
437
  const latency = (Date.now() - startTime) / 1000;
438
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
275
439
  await sendEventToPosthog({
276
440
  client: this.phClient,
277
441
  distinctId: posthogDistinctId,
@@ -288,6 +452,7 @@ class WrappedCompletions$1 extends Completions {
288
452
  params: body,
289
453
  httpStatus: 200,
290
454
  usage,
455
+ tools: availableTools,
291
456
  captureImmediate: posthogCaptureImmediate
292
457
  });
293
458
  } catch (error) {
@@ -322,6 +487,7 @@ class WrappedCompletions$1 extends Completions {
322
487
  const wrappedPromise = parentPromise.then(async result => {
323
488
  if ('choices' in result) {
324
489
  const latency = (Date.now() - startTime) / 1000;
490
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
325
491
  await sendEventToPosthog({
326
492
  client: this.phClient,
327
493
  distinctId: posthogDistinctId,
@@ -340,6 +506,7 @@ class WrappedCompletions$1 extends Completions {
340
506
  reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
341
507
  cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
342
508
  },
509
+ tools: availableTools,
343
510
  captureImmediate: posthogCaptureImmediate
344
511
  });
345
512
  }
@@ -370,8 +537,8 @@ class WrappedCompletions$1 extends Completions {
370
537
  return wrappedPromise;
371
538
  }
372
539
  }
373
- }
374
- class WrappedResponses$1 extends Responses {
540
+ };
541
+ let WrappedResponses$1 = class WrappedResponses extends Responses {
375
542
  constructor(client, phClient) {
376
543
  super(client);
377
544
  this.phClient = phClient;
@@ -416,10 +583,12 @@ class WrappedResponses$1 extends Responses {
416
583
  }
417
584
  }
418
585
  const latency = (Date.now() - startTime) / 1000;
586
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
419
587
  await sendEventToPosthog({
420
588
  client: this.phClient,
421
589
  distinctId: posthogDistinctId,
422
590
  traceId,
591
+ //@ts-expect-error
423
592
  model: openAIParams.model,
424
593
  provider: 'openai',
425
594
  input: openAIParams.input,
@@ -429,6 +598,7 @@ class WrappedResponses$1 extends Responses {
429
598
  params: body,
430
599
  httpStatus: 200,
431
600
  usage,
601
+ tools: availableTools,
432
602
  captureImmediate: posthogCaptureImmediate
433
603
  });
434
604
  } catch (error) {
@@ -436,6 +606,7 @@ class WrappedResponses$1 extends Responses {
436
606
  client: this.phClient,
437
607
  distinctId: posthogDistinctId,
438
608
  traceId,
609
+ //@ts-expect-error
439
610
  model: openAIParams.model,
440
611
  provider: 'openai',
441
612
  input: openAIParams.input,
@@ -462,14 +633,18 @@ class WrappedResponses$1 extends Responses {
462
633
  const wrappedPromise = parentPromise.then(async result => {
463
634
  if ('output' in result) {
464
635
  const latency = (Date.now() - startTime) / 1000;
636
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
465
637
  await sendEventToPosthog({
466
638
  client: this.phClient,
467
639
  distinctId: posthogDistinctId,
468
640
  traceId,
641
+ //@ts-expect-error
469
642
  model: openAIParams.model,
470
643
  provider: 'openai',
471
644
  input: openAIParams.input,
472
- output: result.output,
645
+ output: formatResponseOpenAI({
646
+ output: result.output
647
+ }),
473
648
  latency,
474
649
  baseURL: this.baseURL ?? '',
475
650
  params: body,
@@ -480,6 +655,7 @@ class WrappedResponses$1 extends Responses {
480
655
  reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
481
656
  cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
482
657
  },
658
+ tools: availableTools,
483
659
  captureImmediate: posthogCaptureImmediate
484
660
  });
485
661
  }
@@ -489,6 +665,7 @@ class WrappedResponses$1 extends Responses {
489
665
  client: this.phClient,
490
666
  distinctId: posthogDistinctId,
491
667
  traceId,
668
+ //@ts-expect-error
492
669
  model: openAIParams.model,
493
670
  provider: 'openai',
494
671
  input: openAIParams.input,
@@ -536,6 +713,7 @@ class WrappedResponses$1 extends Responses {
536
713
  client: this.phClient,
537
714
  distinctId: posthogDistinctId,
538
715
  traceId,
716
+ //@ts-expect-error
539
717
  model: openAIParams.model,
540
718
  provider: 'openai',
541
719
  input: openAIParams.input,
@@ -558,6 +736,7 @@ class WrappedResponses$1 extends Responses {
558
736
  client: this.phClient,
559
737
  distinctId: posthogDistinctId,
560
738
  traceId,
739
+ //@ts-expect-error
561
740
  model: openAIParams.model,
562
741
  provider: 'openai',
563
742
  input: openAIParams.input,
@@ -582,7 +761,7 @@ class WrappedResponses$1 extends Responses {
582
761
  originalSelf.create = tempCreate;
583
762
  }
584
763
  }
585
- }
764
+ };
586
765
 
587
766
  class PostHogAzureOpenAI extends openai.AzureOpenAI {
588
767
  constructor(config) {
@@ -793,6 +972,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
793
972
  client: this.phClient,
794
973
  distinctId: posthogDistinctId,
795
974
  traceId,
975
+ //@ts-expect-error
796
976
  model: openAIParams.model,
797
977
  provider: 'azure',
798
978
  input: openAIParams.input,
@@ -809,6 +989,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
809
989
  client: this.phClient,
810
990
  distinctId: posthogDistinctId,
811
991
  traceId,
992
+ //@ts-expect-error
812
993
  model: openAIParams.model,
813
994
  provider: 'azure',
814
995
  input: openAIParams.input,
@@ -839,6 +1020,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
839
1020
  client: this.phClient,
840
1021
  distinctId: posthogDistinctId,
841
1022
  traceId,
1023
+ //@ts-expect-error
842
1024
  model: openAIParams.model,
843
1025
  provider: 'azure',
844
1026
  input: openAIParams.input,
@@ -862,6 +1044,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
862
1044
  client: this.phClient,
863
1045
  distinctId: posthogDistinctId,
864
1046
  traceId,
1047
+ //@ts-expect-error
865
1048
  model: openAIParams.model,
866
1049
  provider: 'azure',
867
1050
  input: openAIParams.input,
@@ -903,6 +1086,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
903
1086
  client: this.phClient,
904
1087
  distinctId: posthogDistinctId,
905
1088
  traceId,
1089
+ //@ts-expect-error
906
1090
  model: openAIParams.model,
907
1091
  provider: 'azure',
908
1092
  input: openAIParams.input,
@@ -925,6 +1109,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
925
1109
  client: this.phClient,
926
1110
  distinctId: posthogDistinctId,
927
1111
  traceId,
1112
+ //@ts-expect-error
928
1113
  model: openAIParams.model,
929
1114
  provider: 'azure',
930
1115
  input: openAIParams.input,
@@ -950,7 +1135,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
950
1135
  const mapVercelParams = params => {
951
1136
  return {
952
1137
  temperature: params.temperature,
953
- max_tokens: params.maxTokens,
1138
+ max_output_tokens: params.maxOutputTokens,
954
1139
  top_p: params.topP,
955
1140
  frequency_penalty: params.frequencyPenalty,
956
1141
  presence_penalty: params.presencePenalty,
@@ -958,78 +1143,67 @@ const mapVercelParams = params => {
958
1143
  stream: params.stream
959
1144
  };
960
1145
  };
961
- const mapVercelPrompt = prompt => {
962
- // normalize single inputs into an array of messages
963
- let promptsArray;
964
- if (typeof prompt === 'string') {
965
- promptsArray = [{
966
- role: 'user',
967
- content: prompt
968
- }];
969
- } else if (!Array.isArray(prompt)) {
970
- promptsArray = [prompt];
971
- } else {
972
- promptsArray = prompt;
973
- }
1146
+ const mapVercelPrompt = messages => {
974
1147
  // Map and truncate individual content
975
- const inputs = promptsArray.map(p => {
976
- let content = {};
977
- if (Array.isArray(p.content)) {
978
- content = p.content.map(c => {
979
- if (c.type === 'text') {
980
- return {
981
- type: 'text',
982
- content: truncate(c.text)
983
- };
984
- } else if (c.type === 'image') {
985
- return {
986
- type: 'image',
987
- content: {
988
- // if image is a url use it, or use "none supported"
989
- image: c.image instanceof URL ? c.image.toString() : 'raw images not supported',
990
- mimeType: c.mimeType
991
- }
992
- };
993
- } else if (c.type === 'file') {
994
- return {
995
- type: 'file',
996
- content: {
1148
+ const inputs = messages.map(message => {
1149
+ let content;
1150
+ // Handle system role which has string content
1151
+ if (message.role === 'system') {
1152
+ content = [{
1153
+ type: 'text',
1154
+ text: truncate(String(message.content))
1155
+ }];
1156
+ } else {
1157
+ // Handle other roles which have array content
1158
+ if (Array.isArray(message.content)) {
1159
+ content = message.content.map(c => {
1160
+ if (c.type === 'text') {
1161
+ return {
1162
+ type: 'text',
1163
+ text: truncate(c.text)
1164
+ };
1165
+ } else if (c.type === 'file') {
1166
+ return {
1167
+ type: 'file',
997
1168
  file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',
998
- mimeType: c.mimeType
999
- }
1000
- };
1001
- } else if (c.type === 'tool-call') {
1002
- return {
1003
- type: 'tool-call',
1004
- content: {
1169
+ mediaType: c.mediaType
1170
+ };
1171
+ } else if (c.type === 'reasoning') {
1172
+ return {
1173
+ type: 'reasoning',
1174
+ text: truncate(c.reasoning)
1175
+ };
1176
+ } else if (c.type === 'tool-call') {
1177
+ return {
1178
+ type: 'tool-call',
1005
1179
  toolCallId: c.toolCallId,
1006
1180
  toolName: c.toolName,
1007
- args: c.args
1008
- }
1009
- };
1010
- } else if (c.type === 'tool-result') {
1011
- return {
1012
- type: 'tool-result',
1013
- content: {
1181
+ input: c.input
1182
+ };
1183
+ } else if (c.type === 'tool-result') {
1184
+ return {
1185
+ type: 'tool-result',
1014
1186
  toolCallId: c.toolCallId,
1015
1187
  toolName: c.toolName,
1016
- result: c.result,
1188
+ output: c.output,
1017
1189
  isError: c.isError
1018
- }
1190
+ };
1191
+ }
1192
+ return {
1193
+ type: 'text',
1194
+ text: ''
1019
1195
  };
1020
- }
1021
- return {
1022
- content: ''
1023
- };
1024
- });
1025
- } else {
1026
- content = {
1027
- type: 'text',
1028
- text: truncate(p.content)
1029
- };
1196
+ });
1197
+ } else {
1198
+ // Fallback for non-array content
1199
+ content = [{
1200
+ type: 'text',
1201
+ text: truncate(String(message.content))
1202
+ }];
1203
+ }
1030
1204
  }
1031
1205
  return {
1032
- role: p.role,
1206
+ role: message.role,
1033
1207
  content
1034
1208
  };
1035
1209
  });
@@ -1061,7 +1235,32 @@ const mapVercelPrompt = prompt => {
1061
1235
  return inputs;
1062
1236
  };
1063
1237
  const mapVercelOutput = result => {
1064
- // normalize string results to object
1238
+ const content = [];
1239
+ if (result.text) {
1240
+ content.push({
1241
+ type: 'text',
1242
+ text: truncate(result.text)
1243
+ });
1244
+ }
1245
+ if (result.toolCalls && Array.isArray(result.toolCalls)) {
1246
+ for (const toolCall of result.toolCalls) {
1247
+ content.push({
1248
+ type: 'function',
1249
+ id: toolCall.toolCallId,
1250
+ function: {
1251
+ name: toolCall.toolName,
1252
+ arguments: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args)
1253
+ }
1254
+ });
1255
+ }
1256
+ }
1257
+ if (content.length > 0) {
1258
+ return [{
1259
+ role: 'assistant',
1260
+ content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
1261
+ }];
1262
+ }
1263
+ // Fallback to original behavior for other result types TODO: check if we can remove this
1065
1264
  const normalizedResult = typeof result === 'string' ? {
1066
1265
  text: result
1067
1266
  } : result;
@@ -1072,8 +1271,8 @@ const mapVercelOutput = result => {
1072
1271
  ...(normalizedResult.object ? {
1073
1272
  object: normalizedResult.object
1074
1273
  } : {}),
1075
- ...(normalizedResult.reasoning ? {
1076
- reasoning: normalizedResult.reasoning
1274
+ ...(normalizedResult.reasoningText ? {
1275
+ reasoning: normalizedResult.reasoningText
1077
1276
  } : {}),
1078
1277
  ...(normalizedResult.response ? {
1079
1278
  response: normalizedResult.response
@@ -1132,14 +1331,14 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1132
1331
  ...options,
1133
1332
  ...mapVercelParams(params)
1134
1333
  };
1334
+ const availableTools = extractAvailableToolCalls('vercel', params);
1135
1335
  try {
1136
1336
  const result = await doGenerate();
1137
- const latency = (Date.now() - startTime) / 1000;
1138
1337
  const modelId = options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
1139
1338
  const provider = options.posthogProviderOverride ?? extractProvider(model);
1140
1339
  const baseURL = ''; // cannot currently get baseURL from vercel
1141
1340
  const content = mapVercelOutput(result);
1142
- // let tools = result.toolCalls
1341
+ const latency = (Date.now() - startTime) / 1000;
1143
1342
  const providerMetadata = result.providerMetadata;
1144
1343
  const additionalTokenValues = {
1145
1344
  ...(providerMetadata?.openai?.reasoningTokens ? {
@@ -1160,19 +1359,17 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1160
1359
  model: modelId,
1161
1360
  provider: provider,
1162
1361
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
1163
- output: [{
1164
- content,
1165
- role: 'assistant'
1166
- }],
1362
+ output: content,
1167
1363
  latency,
1168
1364
  baseURL,
1169
1365
  params: mergedParams,
1170
1366
  httpStatus: 200,
1171
1367
  usage: {
1172
- inputTokens: result.usage.promptTokens,
1173
- outputTokens: result.usage.completionTokens,
1368
+ inputTokens: result.usage.inputTokens,
1369
+ outputTokens: result.usage.outputTokens,
1174
1370
  ...additionalTokenValues
1175
1371
  },
1372
+ tools: availableTools,
1176
1373
  captureImmediate: options.posthogCaptureImmediate
1177
1374
  });
1178
1375
  return result;
@@ -1196,6 +1393,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1196
1393
  },
1197
1394
  isError: true,
1198
1395
  error: truncate(JSON.stringify(error)),
1396
+ tools: availableTools,
1199
1397
  captureImmediate: options.posthogCaptureImmediate
1200
1398
  });
1201
1399
  throw error;
@@ -1207,6 +1405,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1207
1405
  }) => {
1208
1406
  const startTime = Date.now();
1209
1407
  let generatedText = '';
1408
+ let reasoningText = '';
1210
1409
  let usage = {};
1211
1410
  const mergedParams = {
1212
1411
  ...options,
@@ -1214,6 +1413,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1214
1413
  };
1215
1414
  const modelId = options.posthogModelOverride ?? model.modelId;
1216
1415
  const provider = options.posthogProviderOverride ?? extractProvider(model);
1416
+ const availableTools = extractAvailableToolCalls('vercel', params);
1217
1417
  const baseURL = ''; // cannot currently get baseURL from vercel
1218
1418
  try {
1219
1419
  const {
@@ -1222,13 +1422,17 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1222
1422
  } = await doStream();
1223
1423
  const transformStream = new TransformStream({
1224
1424
  transform(chunk, controller) {
1425
+ // Handle new v5 streaming patterns
1225
1426
  if (chunk.type === 'text-delta') {
1226
- generatedText += chunk.textDelta;
1427
+ generatedText += chunk.delta;
1428
+ }
1429
+ if (chunk.type === 'reasoning-delta') {
1430
+ reasoningText += chunk.delta; // New in v5
1227
1431
  }
1228
1432
  if (chunk.type === 'finish') {
1229
1433
  usage = {
1230
- inputTokens: chunk.usage?.promptTokens,
1231
- outputTokens: chunk.usage?.completionTokens
1434
+ inputTokens: chunk.usage?.inputTokens,
1435
+ outputTokens: chunk.usage?.outputTokens
1232
1436
  };
1233
1437
  if (chunk.providerMetadata?.openai?.reasoningTokens) {
1234
1438
  usage.reasoningTokens = chunk.providerMetadata.openai.reasoningTokens;
@@ -1247,6 +1451,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1247
1451
  },
1248
1452
  flush: async () => {
1249
1453
  const latency = (Date.now() - startTime) / 1000;
1454
+ const outputContent = reasoningText ? `${reasoningText}\n\n${generatedText}` : generatedText;
1250
1455
  await sendEventToPosthog({
1251
1456
  client: phClient,
1252
1457
  distinctId: options.posthogDistinctId,
@@ -1255,7 +1460,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1255
1460
  provider: provider,
1256
1461
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
1257
1462
  output: [{
1258
- content: generatedText,
1463
+ content: outputContent,
1259
1464
  role: 'assistant'
1260
1465
  }],
1261
1466
  latency,
@@ -1263,6 +1468,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1263
1468
  params: mergedParams,
1264
1469
  httpStatus: 200,
1265
1470
  usage,
1471
+ tools: availableTools,
1266
1472
  captureImmediate: options.posthogCaptureImmediate
1267
1473
  });
1268
1474
  }
@@ -1290,6 +1496,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1290
1496
  },
1291
1497
  isError: true,
1292
1498
  error: truncate(JSON.stringify(error)),
1499
+ tools: availableTools,
1293
1500
  captureImmediate: options.posthogCaptureImmediate
1294
1501
  });
1295
1502
  throw error;
@@ -1305,14 +1512,14 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1305
1512
  posthogTraceId: traceId,
1306
1513
  posthogDistinctId: options.posthogDistinctId
1307
1514
  });
1308
- const wrappedModel = ai.experimental_wrapLanguageModel({
1515
+ const wrappedModel = ai.wrapLanguageModel({
1309
1516
  model,
1310
1517
  middleware
1311
1518
  });
1312
1519
  return wrappedModel;
1313
1520
  };
1314
1521
 
1315
- class PostHogAnthropic extends AnthropicOriginal__default["default"] {
1522
+ class PostHogAnthropic extends AnthropicOriginal {
1316
1523
  constructor(config) {
1317
1524
  const {
1318
1525
  posthog,
@@ -1323,7 +1530,7 @@ class PostHogAnthropic extends AnthropicOriginal__default["default"] {
1323
1530
  this.messages = new WrappedMessages(this, this.phClient);
1324
1531
  }
1325
1532
  }
1326
- class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1533
+ class WrappedMessages extends AnthropicOriginal.Messages {
1327
1534
  constructor(parentClient, phClient) {
1328
1535
  super(parentClient);
1329
1536
  this.phClient = phClient;
@@ -1372,6 +1579,7 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1372
1579
  }
1373
1580
  }
1374
1581
  const latency = (Date.now() - startTime) / 1000;
1582
+ const availableTools = extractAvailableToolCalls('anthropic', anthropicParams);
1375
1583
  await sendEventToPosthog({
1376
1584
  client: this.phClient,
1377
1585
  distinctId: posthogDistinctId,
@@ -1388,6 +1596,7 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1388
1596
  params: body,
1389
1597
  httpStatus: 200,
1390
1598
  usage,
1599
+ tools: availableTools,
1391
1600
  captureImmediate: posthogCaptureImmediate
1392
1601
  });
1393
1602
  } catch (error) {
@@ -1398,7 +1607,7 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1398
1607
  traceId,
1399
1608
  model: anthropicParams.model,
1400
1609
  provider: 'anthropic',
1401
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1610
+ input: mergeSystemPrompt(anthropicParams),
1402
1611
  output: [],
1403
1612
  latency: 0,
1404
1613
  baseURL: this.baseURL ?? '',
@@ -1423,13 +1632,14 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1423
1632
  const wrappedPromise = parentPromise.then(async result => {
1424
1633
  if ('content' in result) {
1425
1634
  const latency = (Date.now() - startTime) / 1000;
1635
+ const availableTools = extractAvailableToolCalls('anthropic', anthropicParams);
1426
1636
  await sendEventToPosthog({
1427
1637
  client: this.phClient,
1428
1638
  distinctId: posthogDistinctId,
1429
1639
  traceId,
1430
1640
  model: anthropicParams.model,
1431
1641
  provider: 'anthropic',
1432
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1642
+ input: mergeSystemPrompt(anthropicParams),
1433
1643
  output: formatResponseAnthropic(result),
1434
1644
  latency,
1435
1645
  baseURL: this.baseURL ?? '',
@@ -1441,6 +1651,7 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1441
1651
  cacheCreationInputTokens: result.usage.cache_creation_input_tokens ?? 0,
1442
1652
  cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0
1443
1653
  },
1654
+ tools: availableTools,
1444
1655
  captureImmediate: posthogCaptureImmediate
1445
1656
  });
1446
1657
  }
@@ -1452,7 +1663,7 @@ class WrappedMessages extends AnthropicOriginal__default["default"].Messages {
1452
1663
  traceId,
1453
1664
  model: anthropicParams.model,
1454
1665
  provider: 'anthropic',
1455
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1666
+ input: mergeSystemPrompt(anthropicParams),
1456
1667
  output: [],
1457
1668
  latency: 0,
1458
1669
  baseURL: this.baseURL ?? '',
@@ -1503,6 +1714,7 @@ class WrappedModels {
1503
1714
  try {
1504
1715
  const response = await this.client.models.generateContent(geminiParams);
1505
1716
  const latency = (Date.now() - startTime) / 1000;
1717
+ const availableTools = extractAvailableToolCalls('gemini', geminiParams);
1506
1718
  await sendEventToPosthog({
1507
1719
  client: this.phClient,
1508
1720
  distinctId: posthogDistinctId,
@@ -1510,7 +1722,7 @@ class WrappedModels {
1510
1722
  model: geminiParams.model,
1511
1723
  provider: 'gemini',
1512
1724
  input: this.formatInput(geminiParams.contents),
1513
- output: this.formatOutput(response),
1725
+ output: formatResponseGemini(response),
1514
1726
  latency,
1515
1727
  baseURL: 'https://generativelanguage.googleapis.com',
1516
1728
  params: params,
@@ -1519,6 +1731,7 @@ class WrappedModels {
1519
1731
  inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
1520
1732
  outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
1521
1733
  },
1734
+ tools: availableTools,
1522
1735
  captureImmediate: posthogCaptureImmediate
1523
1736
  });
1524
1737
  return response;
@@ -1578,6 +1791,7 @@ class WrappedModels {
1578
1791
  yield chunk;
1579
1792
  }
1580
1793
  const latency = (Date.now() - startTime) / 1000;
1794
+ const availableTools = extractAvailableToolCalls('gemini', geminiParams);
1581
1795
  await sendEventToPosthog({
1582
1796
  client: this.phClient,
1583
1797
  distinctId: posthogDistinctId,
@@ -1594,6 +1808,7 @@ class WrappedModels {
1594
1808
  params: params,
1595
1809
  httpStatus: 200,
1596
1810
  usage,
1811
+ tools: availableTools,
1597
1812
  captureImmediate: posthogCaptureImmediate
1598
1813
  });
1599
1814
  } catch (error) {
@@ -1675,487 +1890,523 @@ class WrappedModels {
1675
1890
  content: String(contents)
1676
1891
  }];
1677
1892
  }
1678
- formatOutput(response) {
1679
- if (response.text) {
1680
- return [{
1681
- role: 'assistant',
1682
- content: response.text
1683
- }];
1684
- }
1685
- if (response.candidates && Array.isArray(response.candidates)) {
1686
- return response.candidates.map(candidate => {
1687
- if (candidate.content && candidate.content.parts) {
1688
- const text = candidate.content.parts.filter(part => part.text).map(part => part.text).join('');
1689
- return {
1690
- role: 'assistant',
1691
- content: text
1692
- };
1693
- }
1694
- return {
1695
- role: 'assistant',
1696
- content: String(candidate)
1697
- };
1698
- });
1699
- }
1700
- return [];
1701
- }
1702
1893
  }
1703
1894
 
1704
- var decamelize = function (str, sep) {
1705
- if (typeof str !== 'string') {
1706
- throw new TypeError('Expected a string');
1707
- }
1708
- sep = typeof sep === 'undefined' ? '_' : sep;
1709
- return str
1710
- .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2')
1711
- .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2')
1712
- .toLowerCase();
1713
- };
1895
+ function getDefaultExportFromCjs (x) {
1896
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1897
+ }
1898
+
1899
+ var decamelize;
1900
+ var hasRequiredDecamelize;
1901
+
1902
+ function requireDecamelize () {
1903
+ if (hasRequiredDecamelize) return decamelize;
1904
+ hasRequiredDecamelize = 1;
1905
+ decamelize = function (str, sep) {
1906
+ if (typeof str !== 'string') {
1907
+ throw new TypeError('Expected a string');
1908
+ }
1909
+
1910
+ sep = typeof sep === 'undefined' ? '_' : sep;
1911
+
1912
+ return str
1913
+ .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2')
1914
+ .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2')
1915
+ .toLowerCase();
1916
+ };
1917
+ return decamelize;
1918
+ }
1919
+
1920
+ var decamelizeExports = requireDecamelize();
1921
+ var snakeCase = /*@__PURE__*/getDefaultExportFromCjs(decamelizeExports);
1714
1922
 
1715
1923
  var camelcase = {exports: {}};
1716
1924
 
1717
- const UPPERCASE = /[\p{Lu}]/u;
1718
- const LOWERCASE = /[\p{Ll}]/u;
1719
- const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
1720
- const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
1721
- const SEPARATORS = /[_.\- ]+/;
1722
- const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
1723
- const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
1724
- const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
1725
- const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
1726
- let isLastCharLower = false;
1727
- let isLastCharUpper = false;
1728
- let isLastLastCharUpper = false;
1729
- for (let i = 0; i < string.length; i++) {
1730
- const character = string[i];
1731
- if (isLastCharLower && UPPERCASE.test(character)) {
1732
- string = string.slice(0, i) + '-' + string.slice(i);
1733
- isLastCharLower = false;
1734
- isLastLastCharUpper = isLastCharUpper;
1735
- isLastCharUpper = true;
1736
- i++;
1737
- }
1738
- else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
1739
- string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
1740
- isLastLastCharUpper = isLastCharUpper;
1741
- isLastCharUpper = false;
1742
- isLastCharLower = true;
1743
- }
1744
- else {
1745
- isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
1746
- isLastLastCharUpper = isLastCharUpper;
1747
- isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
1748
- }
1749
- }
1750
- return string;
1751
- };
1752
- const preserveConsecutiveUppercase = (input, toLowerCase) => {
1753
- LEADING_CAPITAL.lastIndex = 0;
1754
- return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
1755
- };
1756
- const postProcess = (input, toUpperCase) => {
1757
- SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
1758
- NUMBERS_AND_IDENTIFIER.lastIndex = 0;
1759
- return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
1760
- .replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
1761
- };
1762
- const camelCase = (input, options) => {
1763
- if (!(typeof input === 'string' || Array.isArray(input))) {
1764
- throw new TypeError('Expected the input to be `string | string[]`');
1765
- }
1766
- options = {
1767
- pascalCase: false,
1768
- preserveConsecutiveUppercase: false,
1769
- ...options
1770
- };
1771
- if (Array.isArray(input)) {
1772
- input = input.map(x => x.trim())
1773
- .filter(x => x.length)
1774
- .join('-');
1775
- }
1776
- else {
1777
- input = input.trim();
1778
- }
1779
- if (input.length === 0) {
1780
- return '';
1781
- }
1782
- const toLowerCase = options.locale === false ?
1783
- string => string.toLowerCase() :
1784
- string => string.toLocaleLowerCase(options.locale);
1785
- const toUpperCase = options.locale === false ?
1786
- string => string.toUpperCase() :
1787
- string => string.toLocaleUpperCase(options.locale);
1788
- if (input.length === 1) {
1789
- return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
1790
- }
1791
- const hasUpperCase = input !== toLowerCase(input);
1792
- if (hasUpperCase) {
1793
- input = preserveCamelCase(input, toLowerCase, toUpperCase);
1794
- }
1795
- input = input.replace(LEADING_SEPARATORS, '');
1796
- if (options.preserveConsecutiveUppercase) {
1797
- input = preserveConsecutiveUppercase(input, toLowerCase);
1798
- }
1799
- else {
1800
- input = toLowerCase(input);
1801
- }
1802
- if (options.pascalCase) {
1803
- input = toUpperCase(input.charAt(0)) + input.slice(1);
1804
- }
1805
- return postProcess(input, toUpperCase);
1806
- };
1807
- camelcase.exports = camelCase;
1808
- // TODO: Remove this for the next major release
1809
- camelcase.exports.default = camelCase;
1925
+ var hasRequiredCamelcase;
1926
+
1927
+ function requireCamelcase () {
1928
+ if (hasRequiredCamelcase) return camelcase.exports;
1929
+ hasRequiredCamelcase = 1;
1930
+
1931
+ const UPPERCASE = /[\p{Lu}]/u;
1932
+ const LOWERCASE = /[\p{Ll}]/u;
1933
+ const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
1934
+ const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
1935
+ const SEPARATORS = /[_.\- ]+/;
1936
+
1937
+ const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
1938
+ const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
1939
+ const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
1940
+
1941
+ const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
1942
+ let isLastCharLower = false;
1943
+ let isLastCharUpper = false;
1944
+ let isLastLastCharUpper = false;
1945
+
1946
+ for (let i = 0; i < string.length; i++) {
1947
+ const character = string[i];
1948
+
1949
+ if (isLastCharLower && UPPERCASE.test(character)) {
1950
+ string = string.slice(0, i) + '-' + string.slice(i);
1951
+ isLastCharLower = false;
1952
+ isLastLastCharUpper = isLastCharUpper;
1953
+ isLastCharUpper = true;
1954
+ i++;
1955
+ } else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
1956
+ string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
1957
+ isLastLastCharUpper = isLastCharUpper;
1958
+ isLastCharUpper = false;
1959
+ isLastCharLower = true;
1960
+ } else {
1961
+ isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
1962
+ isLastLastCharUpper = isLastCharUpper;
1963
+ isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
1964
+ }
1965
+ }
1966
+
1967
+ return string;
1968
+ };
1969
+
1970
+ const preserveConsecutiveUppercase = (input, toLowerCase) => {
1971
+ LEADING_CAPITAL.lastIndex = 0;
1972
+
1973
+ return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
1974
+ };
1810
1975
 
1811
- function keyToJson(key, map) {
1812
- return map?.[key] || decamelize(key);
1813
- }
1814
- function mapKeys(fields, mapper, map) {
1815
- const mapped = {};
1816
- for (const key in fields) {
1817
- if (Object.hasOwn(fields, key)) {
1818
- mapped[mapper(key, map)] = fields[key];
1819
- }
1820
- }
1821
- return mapped;
1976
+ const postProcess = (input, toUpperCase) => {
1977
+ SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
1978
+ NUMBERS_AND_IDENTIFIER.lastIndex = 0;
1979
+
1980
+ return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
1981
+ .replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
1982
+ };
1983
+
1984
+ const camelCase = (input, options) => {
1985
+ if (!(typeof input === 'string' || Array.isArray(input))) {
1986
+ throw new TypeError('Expected the input to be `string | string[]`');
1987
+ }
1988
+
1989
+ options = {
1990
+ pascalCase: false,
1991
+ preserveConsecutiveUppercase: false,
1992
+ ...options
1993
+ };
1994
+
1995
+ if (Array.isArray(input)) {
1996
+ input = input.map(x => x.trim())
1997
+ .filter(x => x.length)
1998
+ .join('-');
1999
+ } else {
2000
+ input = input.trim();
2001
+ }
2002
+
2003
+ if (input.length === 0) {
2004
+ return '';
2005
+ }
2006
+
2007
+ const toLowerCase = options.locale === false ?
2008
+ string => string.toLowerCase() :
2009
+ string => string.toLocaleLowerCase(options.locale);
2010
+ const toUpperCase = options.locale === false ?
2011
+ string => string.toUpperCase() :
2012
+ string => string.toLocaleUpperCase(options.locale);
2013
+
2014
+ if (input.length === 1) {
2015
+ return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
2016
+ }
2017
+
2018
+ const hasUpperCase = input !== toLowerCase(input);
2019
+
2020
+ if (hasUpperCase) {
2021
+ input = preserveCamelCase(input, toLowerCase, toUpperCase);
2022
+ }
2023
+
2024
+ input = input.replace(LEADING_SEPARATORS, '');
2025
+
2026
+ if (options.preserveConsecutiveUppercase) {
2027
+ input = preserveConsecutiveUppercase(input, toLowerCase);
2028
+ } else {
2029
+ input = toLowerCase(input);
2030
+ }
2031
+
2032
+ if (options.pascalCase) {
2033
+ input = toUpperCase(input.charAt(0)) + input.slice(1);
2034
+ }
2035
+
2036
+ return postProcess(input, toUpperCase);
2037
+ };
2038
+
2039
+ camelcase.exports = camelCase;
2040
+ // TODO: Remove this for the next major release
2041
+ camelcase.exports.default = camelCase;
2042
+ return camelcase.exports;
1822
2043
  }
1823
2044
 
1824
- function shallowCopy(obj) {
1825
- return Array.isArray(obj) ? [...obj] : { ...obj };
1826
- }
1827
- function replaceSecrets(root, secretsMap) {
1828
- const result = shallowCopy(root);
1829
- for (const [path, secretId] of Object.entries(secretsMap)) {
1830
- const [last, ...partsReverse] = path.split(".").reverse();
1831
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1832
- let current = result;
1833
- for (const part of partsReverse.reverse()) {
1834
- if (current[part] === undefined) {
1835
- break;
1836
- }
1837
- current[part] = shallowCopy(current[part]);
1838
- current = current[part];
1839
- }
1840
- if (current[last] !== undefined) {
1841
- current[last] = {
1842
- lc: 1,
1843
- type: "secret",
1844
- id: [secretId],
1845
- };
1846
- }
1847
- }
1848
- return result;
1849
- }
1850
- /**
1851
- * Get a unique name for the module, rather than parent class implementations.
1852
- * Should not be subclassed, subclass lc_name above instead.
1853
- */
1854
- function get_lc_unique_name(
1855
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
1856
- serializableClass) {
1857
- // "super" here would refer to the parent class of Serializable,
1858
- // when we want the parent class of the module actually calling this method.
1859
- const parentClass = Object.getPrototypeOf(serializableClass);
1860
- const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
1861
- (typeof parentClass.lc_name !== "function" ||
1862
- serializableClass.lc_name() !== parentClass.lc_name());
1863
- if (lcNameIsSubclassed) {
1864
- return serializableClass.lc_name();
1865
- }
1866
- else {
1867
- return serializableClass.name;
1868
- }
1869
- }
1870
- class Serializable {
1871
- /**
1872
- * The name of the serializable. Override to provide an alias or
1873
- * to preserve the serialized module name in minified environments.
1874
- *
1875
- * Implemented as a static method to support loading logic.
1876
- */
1877
- static lc_name() {
1878
- return this.name;
1879
- }
1880
- /**
1881
- * The final serialized identifier for the module.
1882
- */
1883
- get lc_id() {
1884
- return [
1885
- ...this.lc_namespace,
1886
- get_lc_unique_name(this.constructor),
1887
- ];
1888
- }
1889
- /**
1890
- * A map of secrets, which will be omitted from serialization.
1891
- * Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
1892
- * Values are the secret ids, which will be used when deserializing.
1893
- */
1894
- get lc_secrets() {
1895
- return undefined;
1896
- }
1897
- /**
1898
- * A map of additional attributes to merge with constructor args.
1899
- * Keys are the attribute names, e.g. "foo".
1900
- * Values are the attribute values, which will be serialized.
1901
- * These attributes need to be accepted by the constructor as arguments.
1902
- */
1903
- get lc_attributes() {
1904
- return undefined;
1905
- }
1906
- /**
1907
- * A map of aliases for constructor args.
1908
- * Keys are the attribute names, e.g. "foo".
1909
- * Values are the alias that will replace the key in serialization.
1910
- * This is used to eg. make argument names match Python.
1911
- */
1912
- get lc_aliases() {
1913
- return undefined;
1914
- }
1915
- constructor(kwargs, ..._args) {
1916
- Object.defineProperty(this, "lc_serializable", {
1917
- enumerable: true,
1918
- configurable: true,
1919
- writable: true,
1920
- value: false
1921
- });
1922
- Object.defineProperty(this, "lc_kwargs", {
1923
- enumerable: true,
1924
- configurable: true,
1925
- writable: true,
1926
- value: void 0
1927
- });
1928
- this.lc_kwargs = kwargs || {};
1929
- }
1930
- toJSON() {
1931
- if (!this.lc_serializable) {
1932
- return this.toJSONNotImplemented();
1933
- }
1934
- if (
1935
- // eslint-disable-next-line no-instanceof/no-instanceof
1936
- this.lc_kwargs instanceof Serializable ||
1937
- typeof this.lc_kwargs !== "object" ||
1938
- Array.isArray(this.lc_kwargs)) {
1939
- // We do not support serialization of classes with arg not a POJO
1940
- // I'm aware the check above isn't as strict as it could be
1941
- return this.toJSONNotImplemented();
1942
- }
1943
- const aliases = {};
1944
- const secrets = {};
1945
- const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
1946
- acc[key] = key in this ? this[key] : this.lc_kwargs[key];
1947
- return acc;
1948
- }, {});
1949
- // get secrets, attributes and aliases from all superclasses
1950
- for (
1951
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1952
- let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
1953
- Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
1954
- Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
1955
- Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
1956
- }
1957
- // include all secrets used, even if not in kwargs,
1958
- // will be replaced with sentinel value in replaceSecrets
1959
- Object.keys(secrets).forEach((keyPath) => {
1960
- // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
1961
- let read = this;
1962
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1963
- let write = kwargs;
1964
- const [last, ...partsReverse] = keyPath.split(".").reverse();
1965
- for (const key of partsReverse.reverse()) {
1966
- if (!(key in read) || read[key] === undefined)
1967
- return;
1968
- if (!(key in write) || write[key] === undefined) {
1969
- if (typeof read[key] === "object" && read[key] != null) {
1970
- write[key] = {};
1971
- }
1972
- else if (Array.isArray(read[key])) {
1973
- write[key] = [];
1974
- }
1975
- }
1976
- read = read[key];
1977
- write = write[key];
1978
- }
1979
- if (last in read && read[last] !== undefined) {
1980
- write[last] = write[last] || read[last];
1981
- }
1982
- });
1983
- return {
1984
- lc: 1,
1985
- type: "constructor",
1986
- id: this.lc_id,
1987
- kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
1988
- };
1989
- }
1990
- toJSONNotImplemented() {
1991
- return {
1992
- lc: 1,
1993
- type: "not_implemented",
1994
- id: this.lc_id,
1995
- };
1996
- }
2045
+ requireCamelcase();
2046
+
2047
+ function keyToJson(key, map) {
2048
+ return map?.[key] || snakeCase(key);
2049
+ }
2050
+ function mapKeys(fields, mapper, map) {
2051
+ const mapped = {};
2052
+ for (const key in fields) {
2053
+ if (Object.hasOwn(fields, key)) {
2054
+ mapped[mapper(key, map)] = fields[key];
2055
+ }
2056
+ }
2057
+ return mapped;
1997
2058
  }
1998
2059
 
1999
- // Supabase Edge Function provides a `Deno` global object
2000
- // without `version` property
2001
- const isDeno = () => typeof Deno !== "undefined";
2002
- function getEnvironmentVariable(name) {
2003
- // Certain Deno setups will throw an error if you try to access environment variables
2004
- // https://github.com/langchain-ai/langchainjs/issues/1412
2005
- try {
2006
- if (typeof process !== "undefined") {
2007
- // eslint-disable-next-line no-process-env
2008
- return process.env?.[name];
2009
- }
2010
- else if (isDeno()) {
2011
- return Deno?.env.get(name);
2012
- }
2013
- else {
2014
- return undefined;
2015
- }
2016
- }
2017
- catch (e) {
2018
- return undefined;
2019
- }
2060
+ function shallowCopy(obj) {
2061
+ return Array.isArray(obj) ? [...obj] : { ...obj };
2062
+ }
2063
+ function replaceSecrets(root, secretsMap) {
2064
+ const result = shallowCopy(root);
2065
+ for (const [path, secretId] of Object.entries(secretsMap)) {
2066
+ const [last, ...partsReverse] = path.split(".").reverse();
2067
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2068
+ let current = result;
2069
+ for (const part of partsReverse.reverse()) {
2070
+ if (current[part] === undefined) {
2071
+ break;
2072
+ }
2073
+ current[part] = shallowCopy(current[part]);
2074
+ current = current[part];
2075
+ }
2076
+ if (current[last] !== undefined) {
2077
+ current[last] = {
2078
+ lc: 1,
2079
+ type: "secret",
2080
+ id: [secretId],
2081
+ };
2082
+ }
2083
+ }
2084
+ return result;
2085
+ }
2086
+ /**
2087
+ * Get a unique name for the module, rather than parent class implementations.
2088
+ * Should not be subclassed, subclass lc_name above instead.
2089
+ */
2090
+ function get_lc_unique_name(
2091
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
2092
+ serializableClass) {
2093
+ // "super" here would refer to the parent class of Serializable,
2094
+ // when we want the parent class of the module actually calling this method.
2095
+ const parentClass = Object.getPrototypeOf(serializableClass);
2096
+ const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
2097
+ (typeof parentClass.lc_name !== "function" ||
2098
+ serializableClass.lc_name() !== parentClass.lc_name());
2099
+ if (lcNameIsSubclassed) {
2100
+ return serializableClass.lc_name();
2101
+ }
2102
+ else {
2103
+ return serializableClass.name;
2104
+ }
2105
+ }
2106
+ class Serializable {
2107
+ /**
2108
+ * The name of the serializable. Override to provide an alias or
2109
+ * to preserve the serialized module name in minified environments.
2110
+ *
2111
+ * Implemented as a static method to support loading logic.
2112
+ */
2113
+ static lc_name() {
2114
+ return this.name;
2115
+ }
2116
+ /**
2117
+ * The final serialized identifier for the module.
2118
+ */
2119
+ get lc_id() {
2120
+ return [
2121
+ ...this.lc_namespace,
2122
+ get_lc_unique_name(this.constructor),
2123
+ ];
2124
+ }
2125
+ /**
2126
+ * A map of secrets, which will be omitted from serialization.
2127
+ * Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
2128
+ * Values are the secret ids, which will be used when deserializing.
2129
+ */
2130
+ get lc_secrets() {
2131
+ return undefined;
2132
+ }
2133
+ /**
2134
+ * A map of additional attributes to merge with constructor args.
2135
+ * Keys are the attribute names, e.g. "foo".
2136
+ * Values are the attribute values, which will be serialized.
2137
+ * These attributes need to be accepted by the constructor as arguments.
2138
+ */
2139
+ get lc_attributes() {
2140
+ return undefined;
2141
+ }
2142
+ /**
2143
+ * A map of aliases for constructor args.
2144
+ * Keys are the attribute names, e.g. "foo".
2145
+ * Values are the alias that will replace the key in serialization.
2146
+ * This is used to eg. make argument names match Python.
2147
+ */
2148
+ get lc_aliases() {
2149
+ return undefined;
2150
+ }
2151
+ /**
2152
+ * A manual list of keys that should be serialized.
2153
+ * If not overridden, all fields passed into the constructor will be serialized.
2154
+ */
2155
+ get lc_serializable_keys() {
2156
+ return undefined;
2157
+ }
2158
+ constructor(kwargs, ..._args) {
2159
+ Object.defineProperty(this, "lc_serializable", {
2160
+ enumerable: true,
2161
+ configurable: true,
2162
+ writable: true,
2163
+ value: false
2164
+ });
2165
+ Object.defineProperty(this, "lc_kwargs", {
2166
+ enumerable: true,
2167
+ configurable: true,
2168
+ writable: true,
2169
+ value: void 0
2170
+ });
2171
+ if (this.lc_serializable_keys !== undefined) {
2172
+ this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
2173
+ }
2174
+ else {
2175
+ this.lc_kwargs = kwargs ?? {};
2176
+ }
2177
+ }
2178
+ toJSON() {
2179
+ if (!this.lc_serializable) {
2180
+ return this.toJSONNotImplemented();
2181
+ }
2182
+ if (
2183
+ // eslint-disable-next-line no-instanceof/no-instanceof
2184
+ this.lc_kwargs instanceof Serializable ||
2185
+ typeof this.lc_kwargs !== "object" ||
2186
+ Array.isArray(this.lc_kwargs)) {
2187
+ // We do not support serialization of classes with arg not a POJO
2188
+ // I'm aware the check above isn't as strict as it could be
2189
+ return this.toJSONNotImplemented();
2190
+ }
2191
+ const aliases = {};
2192
+ const secrets = {};
2193
+ const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
2194
+ acc[key] = key in this ? this[key] : this.lc_kwargs[key];
2195
+ return acc;
2196
+ }, {});
2197
+ // get secrets, attributes and aliases from all superclasses
2198
+ for (
2199
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
2200
+ let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
2201
+ Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
2202
+ Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
2203
+ Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
2204
+ }
2205
+ // include all secrets used, even if not in kwargs,
2206
+ // will be replaced with sentinel value in replaceSecrets
2207
+ Object.keys(secrets).forEach((keyPath) => {
2208
+ // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
2209
+ let read = this;
2210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2211
+ let write = kwargs;
2212
+ const [last, ...partsReverse] = keyPath.split(".").reverse();
2213
+ for (const key of partsReverse.reverse()) {
2214
+ if (!(key in read) || read[key] === undefined)
2215
+ return;
2216
+ if (!(key in write) || write[key] === undefined) {
2217
+ if (typeof read[key] === "object" && read[key] != null) {
2218
+ write[key] = {};
2219
+ }
2220
+ else if (Array.isArray(read[key])) {
2221
+ write[key] = [];
2222
+ }
2223
+ }
2224
+ read = read[key];
2225
+ write = write[key];
2226
+ }
2227
+ if (last in read && read[last] !== undefined) {
2228
+ write[last] = write[last] || read[last];
2229
+ }
2230
+ });
2231
+ return {
2232
+ lc: 1,
2233
+ type: "constructor",
2234
+ id: this.lc_id,
2235
+ kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
2236
+ };
2237
+ }
2238
+ toJSONNotImplemented() {
2239
+ return {
2240
+ lc: 1,
2241
+ type: "not_implemented",
2242
+ id: this.lc_id,
2243
+ };
2244
+ }
2020
2245
  }
2021
2246
 
2022
- /**
2023
- * Abstract class that provides a set of optional methods that can be
2024
- * overridden in derived classes to handle various events during the
2025
- * execution of a LangChain application.
2026
- */
2027
- class BaseCallbackHandlerMethodsClass {
2028
- }
2029
- /**
2030
- * Abstract base class for creating callback handlers in the LangChain
2031
- * framework. It provides a set of optional methods that can be overridden
2032
- * in derived classes to handle various events during the execution of a
2033
- * LangChain application.
2034
- */
2035
- class BaseCallbackHandler extends BaseCallbackHandlerMethodsClass {
2036
- get lc_namespace() {
2037
- return ["langchain_core", "callbacks", this.name];
2038
- }
2039
- get lc_secrets() {
2040
- return undefined;
2041
- }
2042
- get lc_attributes() {
2043
- return undefined;
2044
- }
2045
- get lc_aliases() {
2046
- return undefined;
2047
- }
2048
- /**
2049
- * The name of the serializable. Override to provide an alias or
2050
- * to preserve the serialized module name in minified environments.
2051
- *
2052
- * Implemented as a static method to support loading logic.
2053
- */
2054
- static lc_name() {
2055
- return this.name;
2056
- }
2057
- /**
2058
- * The final serialized identifier for the module.
2059
- */
2060
- get lc_id() {
2061
- return [
2062
- ...this.lc_namespace,
2063
- get_lc_unique_name(this.constructor),
2064
- ];
2065
- }
2066
- constructor(input) {
2067
- super();
2068
- Object.defineProperty(this, "lc_serializable", {
2069
- enumerable: true,
2070
- configurable: true,
2071
- writable: true,
2072
- value: false
2073
- });
2074
- Object.defineProperty(this, "lc_kwargs", {
2075
- enumerable: true,
2076
- configurable: true,
2077
- writable: true,
2078
- value: void 0
2079
- });
2080
- Object.defineProperty(this, "ignoreLLM", {
2081
- enumerable: true,
2082
- configurable: true,
2083
- writable: true,
2084
- value: false
2085
- });
2086
- Object.defineProperty(this, "ignoreChain", {
2087
- enumerable: true,
2088
- configurable: true,
2089
- writable: true,
2090
- value: false
2091
- });
2092
- Object.defineProperty(this, "ignoreAgent", {
2093
- enumerable: true,
2094
- configurable: true,
2095
- writable: true,
2096
- value: false
2097
- });
2098
- Object.defineProperty(this, "ignoreRetriever", {
2099
- enumerable: true,
2100
- configurable: true,
2101
- writable: true,
2102
- value: false
2103
- });
2104
- Object.defineProperty(this, "ignoreCustomEvent", {
2105
- enumerable: true,
2106
- configurable: true,
2107
- writable: true,
2108
- value: false
2109
- });
2110
- Object.defineProperty(this, "raiseError", {
2111
- enumerable: true,
2112
- configurable: true,
2113
- writable: true,
2114
- value: false
2115
- });
2116
- Object.defineProperty(this, "awaitHandlers", {
2117
- enumerable: true,
2118
- configurable: true,
2119
- writable: true,
2120
- value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
2121
- });
2122
- this.lc_kwargs = input || {};
2123
- if (input) {
2124
- this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
2125
- this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
2126
- this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
2127
- this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
2128
- this.ignoreCustomEvent =
2129
- input.ignoreCustomEvent ?? this.ignoreCustomEvent;
2130
- this.raiseError = input.raiseError ?? this.raiseError;
2131
- this.awaitHandlers =
2132
- this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
2133
- }
2134
- }
2135
- copy() {
2136
- return new this.constructor(this);
2137
- }
2138
- toJSON() {
2139
- return Serializable.prototype.toJSON.call(this);
2140
- }
2141
- toJSONNotImplemented() {
2142
- return Serializable.prototype.toJSONNotImplemented.call(this);
2143
- }
2144
- static fromMethods(methods) {
2145
- class Handler extends BaseCallbackHandler {
2146
- constructor() {
2147
- super();
2148
- Object.defineProperty(this, "name", {
2149
- enumerable: true,
2150
- configurable: true,
2151
- writable: true,
2152
- value: uuid__namespace.v4()
2153
- });
2154
- Object.assign(this, methods);
2155
- }
2156
- }
2157
- return new Handler();
2158
- }
2247
+ // Supabase Edge Function provides a `Deno` global object
2248
+ // without `version` property
2249
+ const isDeno = () => typeof Deno !== "undefined";
2250
+ function getEnvironmentVariable(name) {
2251
+ // Certain Deno setups will throw an error if you try to access environment variables
2252
+ // https://github.com/langchain-ai/langchainjs/issues/1412
2253
+ try {
2254
+ if (typeof process !== "undefined") {
2255
+ // eslint-disable-next-line no-process-env
2256
+ return process.env?.[name];
2257
+ }
2258
+ else if (isDeno()) {
2259
+ return Deno?.env.get(name);
2260
+ }
2261
+ else {
2262
+ return undefined;
2263
+ }
2264
+ }
2265
+ catch (e) {
2266
+ return undefined;
2267
+ }
2268
+ }
2269
+
2270
+ /**
2271
+ * Abstract class that provides a set of optional methods that can be
2272
+ * overridden in derived classes to handle various events during the
2273
+ * execution of a LangChain application.
2274
+ */
2275
+ class BaseCallbackHandlerMethodsClass {
2276
+ }
2277
+ /**
2278
+ * Abstract base class for creating callback handlers in the LangChain
2279
+ * framework. It provides a set of optional methods that can be overridden
2280
+ * in derived classes to handle various events during the execution of a
2281
+ * LangChain application.
2282
+ */
2283
+ class BaseCallbackHandler extends BaseCallbackHandlerMethodsClass {
2284
+ get lc_namespace() {
2285
+ return ["langchain_core", "callbacks", this.name];
2286
+ }
2287
+ get lc_secrets() {
2288
+ return undefined;
2289
+ }
2290
+ get lc_attributes() {
2291
+ return undefined;
2292
+ }
2293
+ get lc_aliases() {
2294
+ return undefined;
2295
+ }
2296
+ get lc_serializable_keys() {
2297
+ return undefined;
2298
+ }
2299
+ /**
2300
+ * The name of the serializable. Override to provide an alias or
2301
+ * to preserve the serialized module name in minified environments.
2302
+ *
2303
+ * Implemented as a static method to support loading logic.
2304
+ */
2305
+ static lc_name() {
2306
+ return this.name;
2307
+ }
2308
+ /**
2309
+ * The final serialized identifier for the module.
2310
+ */
2311
+ get lc_id() {
2312
+ return [
2313
+ ...this.lc_namespace,
2314
+ get_lc_unique_name(this.constructor),
2315
+ ];
2316
+ }
2317
+ constructor(input) {
2318
+ super();
2319
+ Object.defineProperty(this, "lc_serializable", {
2320
+ enumerable: true,
2321
+ configurable: true,
2322
+ writable: true,
2323
+ value: false
2324
+ });
2325
+ Object.defineProperty(this, "lc_kwargs", {
2326
+ enumerable: true,
2327
+ configurable: true,
2328
+ writable: true,
2329
+ value: void 0
2330
+ });
2331
+ Object.defineProperty(this, "ignoreLLM", {
2332
+ enumerable: true,
2333
+ configurable: true,
2334
+ writable: true,
2335
+ value: false
2336
+ });
2337
+ Object.defineProperty(this, "ignoreChain", {
2338
+ enumerable: true,
2339
+ configurable: true,
2340
+ writable: true,
2341
+ value: false
2342
+ });
2343
+ Object.defineProperty(this, "ignoreAgent", {
2344
+ enumerable: true,
2345
+ configurable: true,
2346
+ writable: true,
2347
+ value: false
2348
+ });
2349
+ Object.defineProperty(this, "ignoreRetriever", {
2350
+ enumerable: true,
2351
+ configurable: true,
2352
+ writable: true,
2353
+ value: false
2354
+ });
2355
+ Object.defineProperty(this, "ignoreCustomEvent", {
2356
+ enumerable: true,
2357
+ configurable: true,
2358
+ writable: true,
2359
+ value: false
2360
+ });
2361
+ Object.defineProperty(this, "raiseError", {
2362
+ enumerable: true,
2363
+ configurable: true,
2364
+ writable: true,
2365
+ value: false
2366
+ });
2367
+ Object.defineProperty(this, "awaitHandlers", {
2368
+ enumerable: true,
2369
+ configurable: true,
2370
+ writable: true,
2371
+ value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
2372
+ });
2373
+ this.lc_kwargs = input || {};
2374
+ if (input) {
2375
+ this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
2376
+ this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
2377
+ this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
2378
+ this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
2379
+ this.ignoreCustomEvent =
2380
+ input.ignoreCustomEvent ?? this.ignoreCustomEvent;
2381
+ this.raiseError = input.raiseError ?? this.raiseError;
2382
+ this.awaitHandlers =
2383
+ this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
2384
+ }
2385
+ }
2386
+ copy() {
2387
+ return new this.constructor(this);
2388
+ }
2389
+ toJSON() {
2390
+ return Serializable.prototype.toJSON.call(this);
2391
+ }
2392
+ toJSONNotImplemented() {
2393
+ return Serializable.prototype.toJSONNotImplemented.call(this);
2394
+ }
2395
+ static fromMethods(methods) {
2396
+ class Handler extends BaseCallbackHandler {
2397
+ constructor() {
2398
+ super();
2399
+ Object.defineProperty(this, "name", {
2400
+ enumerable: true,
2401
+ configurable: true,
2402
+ writable: true,
2403
+ value: uuid__namespace.v4()
2404
+ });
2405
+ Object.assign(this, methods);
2406
+ }
2407
+ }
2408
+ return new Handler();
2409
+ }
2159
2410
  }
2160
2411
 
2161
2412
  class LangChainCallbackHandler extends BaseCallbackHandler {
@@ -2335,6 +2586,9 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2335
2586
  };
2336
2587
  if (extraParams) {
2337
2588
  generation.modelParams = getModelParams(extraParams.invocation_params);
2589
+ if (extraParams.invocation_params && extraParams.invocation_params.tools) {
2590
+ generation.tools = extraParams.invocation_params.tools;
2591
+ }
2338
2592
  }
2339
2593
  if (metadata) {
2340
2594
  if (metadata.ls_model_name) {
@@ -2441,7 +2695,7 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2441
2695
  $ai_base_url: run.baseUrl
2442
2696
  };
2443
2697
  if (run.tools) {
2444
- eventProperties['$ai_tools'] = withPrivacyMode(this.client, this.privacyMode, run.tools);
2698
+ eventProperties['$ai_tools'] = run.tools;
2445
2699
  }
2446
2700
  if (output instanceof Error) {
2447
2701
  eventProperties['$ai_http_status'] = output.status || 500;
@@ -2463,13 +2717,20 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2463
2717
  let completions;
2464
2718
  if (output.generations && Array.isArray(output.generations)) {
2465
2719
  const lastGeneration = output.generations[output.generations.length - 1];
2466
- if (Array.isArray(lastGeneration)) {
2467
- completions = lastGeneration.map(gen => {
2468
- return {
2469
- role: 'assistant',
2470
- content: gen.text
2471
- };
2472
- });
2720
+ if (Array.isArray(lastGeneration) && lastGeneration.length > 0) {
2721
+ // Check if this is a ChatGeneration by looking at the first item
2722
+ const isChatGeneration = 'message' in lastGeneration[0] && lastGeneration[0].message;
2723
+ if (isChatGeneration) {
2724
+ // For ChatGeneration, convert messages to dict format
2725
+ completions = lastGeneration.map(gen => {
2726
+ return this._convertMessageToDict(gen.message);
2727
+ });
2728
+ } else {
2729
+ // For non-ChatGeneration, extract raw response
2730
+ completions = lastGeneration.map(gen => {
2731
+ return this._extractRawResponse(gen);
2732
+ });
2733
+ }
2473
2734
  }
2474
2735
  }
2475
2736
  if (completions) {
@@ -2520,6 +2781,19 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2520
2781
  }
2521
2782
  }));
2522
2783
  }
2784
+ _extractRawResponse(generation) {
2785
+ // Extract the response from the last response of the LLM call
2786
+ // We return the text of the response if not empty
2787
+ if (generation.text != null && generation.text.trim() !== '') {
2788
+ return generation.text.trim();
2789
+ } else if (generation.message) {
2790
+ // Additional kwargs contains the response in case of tool usage
2791
+ return generation.message.additional_kwargs || generation.message.additionalKwargs || {};
2792
+ } else {
2793
+ // Not tool usage, some LLM responses can be simply empty
2794
+ return '';
2795
+ }
2796
+ }
2523
2797
  _convertMessageToDict(message) {
2524
2798
  let messageDict = {};
2525
2799
  const messageType = message.getType();