@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
@@ -2,7 +2,7 @@ import { OpenAI, AzureOpenAI } from 'openai';
2
2
  import * as uuid from 'uuid';
3
3
  import { v4 } from 'uuid';
4
4
  import { Buffer } from 'buffer';
5
- import { experimental_wrapLanguageModel } from 'ai';
5
+ import { wrapLanguageModel } from 'ai';
6
6
  import AnthropicOriginal from '@anthropic-ai/sdk';
7
7
  import { GoogleGenAI } from '@google/genai';
8
8
 
@@ -23,32 +23,173 @@ const getModelParams = params => {
23
23
  return modelParams;
24
24
  };
25
25
  const formatResponseAnthropic = response => {
26
- // Example approach if "response.content" holds array of text segments, etc.
27
26
  const output = [];
27
+ const content = [];
28
28
  for (const choice of response.content ?? []) {
29
- if (choice?.text) {
30
- output.push({
31
- role: 'assistant',
32
- content: choice.text
29
+ if (choice?.type === 'text' && choice?.text) {
30
+ content.push({
31
+ type: 'text',
32
+ text: choice.text
33
+ });
34
+ } else if (choice?.type === 'tool_use' && choice?.name && choice?.id) {
35
+ content.push({
36
+ type: 'function',
37
+ id: choice.id,
38
+ function: {
39
+ name: choice.name,
40
+ arguments: choice.input || {}
41
+ }
33
42
  });
34
43
  }
35
44
  }
45
+ if (content.length > 0) {
46
+ output.push({
47
+ role: 'assistant',
48
+ content
49
+ });
50
+ }
36
51
  return output;
37
52
  };
38
53
  const formatResponseOpenAI = response => {
39
54
  const output = [];
40
- for (const choice of response.choices ?? []) {
41
- if (choice.message?.content) {
55
+ if (response.choices) {
56
+ for (const choice of response.choices) {
57
+ const content = [];
58
+ let role = 'assistant';
59
+ if (choice.message) {
60
+ if (choice.message.role) {
61
+ role = choice.message.role;
62
+ }
63
+ if (choice.message.content) {
64
+ content.push({
65
+ type: 'text',
66
+ text: choice.message.content
67
+ });
68
+ }
69
+ if (choice.message.tool_calls) {
70
+ for (const toolCall of choice.message.tool_calls) {
71
+ content.push({
72
+ type: 'function',
73
+ id: toolCall.id,
74
+ function: {
75
+ name: toolCall.function.name,
76
+ arguments: toolCall.function.arguments
77
+ }
78
+ });
79
+ }
80
+ }
81
+ }
82
+ if (content.length > 0) {
83
+ output.push({
84
+ role,
85
+ content
86
+ });
87
+ }
88
+ }
89
+ }
90
+ // Handle Responses API format
91
+ if (response.output) {
92
+ const content = [];
93
+ let role = 'assistant';
94
+ for (const item of response.output) {
95
+ if (item.type === 'message') {
96
+ role = item.role;
97
+ if (item.content && Array.isArray(item.content)) {
98
+ for (const contentItem of item.content) {
99
+ if (contentItem.type === 'output_text' && contentItem.text) {
100
+ content.push({
101
+ type: 'text',
102
+ text: contentItem.text
103
+ });
104
+ } else if (contentItem.text) {
105
+ content.push({
106
+ type: 'text',
107
+ text: contentItem.text
108
+ });
109
+ } else if (contentItem.type === 'input_image' && contentItem.image_url) {
110
+ content.push({
111
+ type: 'image',
112
+ image: contentItem.image_url
113
+ });
114
+ }
115
+ }
116
+ } else if (item.content) {
117
+ content.push({
118
+ type: 'text',
119
+ text: String(item.content)
120
+ });
121
+ }
122
+ } else if (item.type === 'function_call') {
123
+ content.push({
124
+ type: 'function',
125
+ id: item.call_id || item.id || '',
126
+ function: {
127
+ name: item.name,
128
+ arguments: item.arguments || {}
129
+ }
130
+ });
131
+ }
132
+ }
133
+ if (content.length > 0) {
42
134
  output.push({
43
- role: choice.message.role,
44
- content: choice.message.content
135
+ role,
136
+ content
45
137
  });
46
138
  }
47
139
  }
48
140
  return output;
49
141
  };
142
+ const formatResponseGemini = response => {
143
+ const output = [];
144
+ if (response.candidates && Array.isArray(response.candidates)) {
145
+ for (const candidate of response.candidates) {
146
+ if (candidate.content && candidate.content.parts) {
147
+ const content = [];
148
+ for (const part of candidate.content.parts) {
149
+ if (part.text) {
150
+ content.push({
151
+ type: 'text',
152
+ text: part.text
153
+ });
154
+ } else if (part.functionCall) {
155
+ content.push({
156
+ type: 'function',
157
+ function: {
158
+ name: part.functionCall.name,
159
+ arguments: part.functionCall.args
160
+ }
161
+ });
162
+ }
163
+ }
164
+ if (content.length > 0) {
165
+ output.push({
166
+ role: 'assistant',
167
+ content
168
+ });
169
+ }
170
+ } else if (candidate.text) {
171
+ output.push({
172
+ role: 'assistant',
173
+ content: [{
174
+ type: 'text',
175
+ text: candidate.text
176
+ }]
177
+ });
178
+ }
179
+ }
180
+ } else if (response.text) {
181
+ output.push({
182
+ role: 'assistant',
183
+ content: [{
184
+ type: 'text',
185
+ text: response.text
186
+ }]
187
+ });
188
+ }
189
+ return output;
190
+ };
50
191
  const mergeSystemPrompt = (params, provider) => {
51
- if (provider == 'anthropic') {
192
+ {
52
193
  const messages = params.messages || [];
53
194
  if (!params.system) {
54
195
  return messages;
@@ -59,7 +200,6 @@ const mergeSystemPrompt = (params, provider) => {
59
200
  content: systemMessage
60
201
  }, ...messages];
61
202
  }
62
- return params.messages;
63
203
  };
64
204
  const withPrivacyMode = (client, privacyMode, input) => {
65
205
  return client.privacy_mode || privacyMode ? null : input;
@@ -77,6 +217,35 @@ const truncate = str => {
77
217
  return str;
78
218
  }
79
219
  };
220
+ /**
221
+ * Extract available tool calls from the request parameters.
222
+ * These are the tools provided to the LLM, not the tool calls in the response.
223
+ */
224
+ const extractAvailableToolCalls = (provider, params) => {
225
+ if (provider === 'anthropic') {
226
+ if (params.tools) {
227
+ return params.tools;
228
+ }
229
+ return null;
230
+ } else if (provider === 'gemini') {
231
+ if (params.config && params.config.tools) {
232
+ return params.config.tools;
233
+ }
234
+ return null;
235
+ } else if (provider === 'openai') {
236
+ if (params.tools) {
237
+ return params.tools;
238
+ }
239
+ return null;
240
+ } else if (provider === 'vercel') {
241
+ // Vercel AI SDK stores tools in params.mode.tools when mode type is 'regular'
242
+ if (params.mode?.type === 'regular' && params.mode.tools) {
243
+ return params.mode.tools;
244
+ }
245
+ return null;
246
+ }
247
+ return null;
248
+ };
80
249
  function sanitizeValues(obj) {
81
250
  if (obj === undefined || obj === null) {
82
251
  return obj;
@@ -196,13 +365,13 @@ class PostHogOpenAI extends OpenAI {
196
365
  this.responses = new WrappedResponses$1(this, this.phClient);
197
366
  }
198
367
  }
199
- class WrappedChat$1 extends Chat {
368
+ let WrappedChat$1 = class WrappedChat extends Chat {
200
369
  constructor(parentClient, phClient) {
201
370
  super(parentClient);
202
371
  this.completions = new WrappedCompletions$1(parentClient, phClient);
203
372
  }
204
- }
205
- class WrappedCompletions$1 extends Completions {
373
+ };
374
+ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
206
375
  constructor(client, phClient) {
207
376
  super(client);
208
377
  this.phClient = phClient;
@@ -246,6 +415,7 @@ class WrappedCompletions$1 extends Completions {
246
415
  }
247
416
  }
248
417
  const latency = (Date.now() - startTime) / 1000;
418
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
249
419
  await sendEventToPosthog({
250
420
  client: this.phClient,
251
421
  distinctId: posthogDistinctId,
@@ -262,6 +432,7 @@ class WrappedCompletions$1 extends Completions {
262
432
  params: body,
263
433
  httpStatus: 200,
264
434
  usage,
435
+ tools: availableTools,
265
436
  captureImmediate: posthogCaptureImmediate
266
437
  });
267
438
  } catch (error) {
@@ -296,6 +467,7 @@ class WrappedCompletions$1 extends Completions {
296
467
  const wrappedPromise = parentPromise.then(async result => {
297
468
  if ('choices' in result) {
298
469
  const latency = (Date.now() - startTime) / 1000;
470
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
299
471
  await sendEventToPosthog({
300
472
  client: this.phClient,
301
473
  distinctId: posthogDistinctId,
@@ -314,6 +486,7 @@ class WrappedCompletions$1 extends Completions {
314
486
  reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
315
487
  cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
316
488
  },
489
+ tools: availableTools,
317
490
  captureImmediate: posthogCaptureImmediate
318
491
  });
319
492
  }
@@ -344,8 +517,8 @@ class WrappedCompletions$1 extends Completions {
344
517
  return wrappedPromise;
345
518
  }
346
519
  }
347
- }
348
- class WrappedResponses$1 extends Responses {
520
+ };
521
+ let WrappedResponses$1 = class WrappedResponses extends Responses {
349
522
  constructor(client, phClient) {
350
523
  super(client);
351
524
  this.phClient = phClient;
@@ -390,10 +563,12 @@ class WrappedResponses$1 extends Responses {
390
563
  }
391
564
  }
392
565
  const latency = (Date.now() - startTime) / 1000;
566
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
393
567
  await sendEventToPosthog({
394
568
  client: this.phClient,
395
569
  distinctId: posthogDistinctId,
396
570
  traceId,
571
+ //@ts-expect-error
397
572
  model: openAIParams.model,
398
573
  provider: 'openai',
399
574
  input: openAIParams.input,
@@ -403,6 +578,7 @@ class WrappedResponses$1 extends Responses {
403
578
  params: body,
404
579
  httpStatus: 200,
405
580
  usage,
581
+ tools: availableTools,
406
582
  captureImmediate: posthogCaptureImmediate
407
583
  });
408
584
  } catch (error) {
@@ -410,6 +586,7 @@ class WrappedResponses$1 extends Responses {
410
586
  client: this.phClient,
411
587
  distinctId: posthogDistinctId,
412
588
  traceId,
589
+ //@ts-expect-error
413
590
  model: openAIParams.model,
414
591
  provider: 'openai',
415
592
  input: openAIParams.input,
@@ -436,14 +613,18 @@ class WrappedResponses$1 extends Responses {
436
613
  const wrappedPromise = parentPromise.then(async result => {
437
614
  if ('output' in result) {
438
615
  const latency = (Date.now() - startTime) / 1000;
616
+ const availableTools = extractAvailableToolCalls('openai', openAIParams);
439
617
  await sendEventToPosthog({
440
618
  client: this.phClient,
441
619
  distinctId: posthogDistinctId,
442
620
  traceId,
621
+ //@ts-expect-error
443
622
  model: openAIParams.model,
444
623
  provider: 'openai',
445
624
  input: openAIParams.input,
446
- output: result.output,
625
+ output: formatResponseOpenAI({
626
+ output: result.output
627
+ }),
447
628
  latency,
448
629
  baseURL: this.baseURL ?? '',
449
630
  params: body,
@@ -454,6 +635,7 @@ class WrappedResponses$1 extends Responses {
454
635
  reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
455
636
  cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
456
637
  },
638
+ tools: availableTools,
457
639
  captureImmediate: posthogCaptureImmediate
458
640
  });
459
641
  }
@@ -463,6 +645,7 @@ class WrappedResponses$1 extends Responses {
463
645
  client: this.phClient,
464
646
  distinctId: posthogDistinctId,
465
647
  traceId,
648
+ //@ts-expect-error
466
649
  model: openAIParams.model,
467
650
  provider: 'openai',
468
651
  input: openAIParams.input,
@@ -510,6 +693,7 @@ class WrappedResponses$1 extends Responses {
510
693
  client: this.phClient,
511
694
  distinctId: posthogDistinctId,
512
695
  traceId,
696
+ //@ts-expect-error
513
697
  model: openAIParams.model,
514
698
  provider: 'openai',
515
699
  input: openAIParams.input,
@@ -532,6 +716,7 @@ class WrappedResponses$1 extends Responses {
532
716
  client: this.phClient,
533
717
  distinctId: posthogDistinctId,
534
718
  traceId,
719
+ //@ts-expect-error
535
720
  model: openAIParams.model,
536
721
  provider: 'openai',
537
722
  input: openAIParams.input,
@@ -556,7 +741,7 @@ class WrappedResponses$1 extends Responses {
556
741
  originalSelf.create = tempCreate;
557
742
  }
558
743
  }
559
- }
744
+ };
560
745
 
561
746
  class PostHogAzureOpenAI extends AzureOpenAI {
562
747
  constructor(config) {
@@ -767,6 +952,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
767
952
  client: this.phClient,
768
953
  distinctId: posthogDistinctId,
769
954
  traceId,
955
+ //@ts-expect-error
770
956
  model: openAIParams.model,
771
957
  provider: 'azure',
772
958
  input: openAIParams.input,
@@ -783,6 +969,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
783
969
  client: this.phClient,
784
970
  distinctId: posthogDistinctId,
785
971
  traceId,
972
+ //@ts-expect-error
786
973
  model: openAIParams.model,
787
974
  provider: 'azure',
788
975
  input: openAIParams.input,
@@ -813,6 +1000,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
813
1000
  client: this.phClient,
814
1001
  distinctId: posthogDistinctId,
815
1002
  traceId,
1003
+ //@ts-expect-error
816
1004
  model: openAIParams.model,
817
1005
  provider: 'azure',
818
1006
  input: openAIParams.input,
@@ -836,6 +1024,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
836
1024
  client: this.phClient,
837
1025
  distinctId: posthogDistinctId,
838
1026
  traceId,
1027
+ //@ts-expect-error
839
1028
  model: openAIParams.model,
840
1029
  provider: 'azure',
841
1030
  input: openAIParams.input,
@@ -877,6 +1066,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
877
1066
  client: this.phClient,
878
1067
  distinctId: posthogDistinctId,
879
1068
  traceId,
1069
+ //@ts-expect-error
880
1070
  model: openAIParams.model,
881
1071
  provider: 'azure',
882
1072
  input: openAIParams.input,
@@ -899,6 +1089,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
899
1089
  client: this.phClient,
900
1090
  distinctId: posthogDistinctId,
901
1091
  traceId,
1092
+ //@ts-expect-error
902
1093
  model: openAIParams.model,
903
1094
  provider: 'azure',
904
1095
  input: openAIParams.input,
@@ -924,7 +1115,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
924
1115
  const mapVercelParams = params => {
925
1116
  return {
926
1117
  temperature: params.temperature,
927
- max_tokens: params.maxTokens,
1118
+ max_output_tokens: params.maxOutputTokens,
928
1119
  top_p: params.topP,
929
1120
  frequency_penalty: params.frequencyPenalty,
930
1121
  presence_penalty: params.presencePenalty,
@@ -932,78 +1123,67 @@ const mapVercelParams = params => {
932
1123
  stream: params.stream
933
1124
  };
934
1125
  };
935
- const mapVercelPrompt = prompt => {
936
- // normalize single inputs into an array of messages
937
- let promptsArray;
938
- if (typeof prompt === 'string') {
939
- promptsArray = [{
940
- role: 'user',
941
- content: prompt
942
- }];
943
- } else if (!Array.isArray(prompt)) {
944
- promptsArray = [prompt];
945
- } else {
946
- promptsArray = prompt;
947
- }
1126
+ const mapVercelPrompt = messages => {
948
1127
  // Map and truncate individual content
949
- const inputs = promptsArray.map(p => {
950
- let content = {};
951
- if (Array.isArray(p.content)) {
952
- content = p.content.map(c => {
953
- if (c.type === 'text') {
954
- return {
955
- type: 'text',
956
- content: truncate(c.text)
957
- };
958
- } else if (c.type === 'image') {
959
- return {
960
- type: 'image',
961
- content: {
962
- // if image is a url use it, or use "none supported"
963
- image: c.image instanceof URL ? c.image.toString() : 'raw images not supported',
964
- mimeType: c.mimeType
965
- }
966
- };
967
- } else if (c.type === 'file') {
968
- return {
969
- type: 'file',
970
- content: {
1128
+ const inputs = messages.map(message => {
1129
+ let content;
1130
+ // Handle system role which has string content
1131
+ if (message.role === 'system') {
1132
+ content = [{
1133
+ type: 'text',
1134
+ text: truncate(String(message.content))
1135
+ }];
1136
+ } else {
1137
+ // Handle other roles which have array content
1138
+ if (Array.isArray(message.content)) {
1139
+ content = message.content.map(c => {
1140
+ if (c.type === 'text') {
1141
+ return {
1142
+ type: 'text',
1143
+ text: truncate(c.text)
1144
+ };
1145
+ } else if (c.type === 'file') {
1146
+ return {
1147
+ type: 'file',
971
1148
  file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',
972
- mimeType: c.mimeType
973
- }
974
- };
975
- } else if (c.type === 'tool-call') {
976
- return {
977
- type: 'tool-call',
978
- content: {
1149
+ mediaType: c.mediaType
1150
+ };
1151
+ } else if (c.type === 'reasoning') {
1152
+ return {
1153
+ type: 'reasoning',
1154
+ text: truncate(c.reasoning)
1155
+ };
1156
+ } else if (c.type === 'tool-call') {
1157
+ return {
1158
+ type: 'tool-call',
979
1159
  toolCallId: c.toolCallId,
980
1160
  toolName: c.toolName,
981
- args: c.args
982
- }
983
- };
984
- } else if (c.type === 'tool-result') {
985
- return {
986
- type: 'tool-result',
987
- content: {
1161
+ input: c.input
1162
+ };
1163
+ } else if (c.type === 'tool-result') {
1164
+ return {
1165
+ type: 'tool-result',
988
1166
  toolCallId: c.toolCallId,
989
1167
  toolName: c.toolName,
990
- result: c.result,
1168
+ output: c.output,
991
1169
  isError: c.isError
992
- }
1170
+ };
1171
+ }
1172
+ return {
1173
+ type: 'text',
1174
+ text: ''
993
1175
  };
994
- }
995
- return {
996
- content: ''
997
- };
998
- });
999
- } else {
1000
- content = {
1001
- type: 'text',
1002
- text: truncate(p.content)
1003
- };
1176
+ });
1177
+ } else {
1178
+ // Fallback for non-array content
1179
+ content = [{
1180
+ type: 'text',
1181
+ text: truncate(String(message.content))
1182
+ }];
1183
+ }
1004
1184
  }
1005
1185
  return {
1006
- role: p.role,
1186
+ role: message.role,
1007
1187
  content
1008
1188
  };
1009
1189
  });
@@ -1035,7 +1215,32 @@ const mapVercelPrompt = prompt => {
1035
1215
  return inputs;
1036
1216
  };
1037
1217
  const mapVercelOutput = result => {
1038
- // normalize string results to object
1218
+ const content = [];
1219
+ if (result.text) {
1220
+ content.push({
1221
+ type: 'text',
1222
+ text: truncate(result.text)
1223
+ });
1224
+ }
1225
+ if (result.toolCalls && Array.isArray(result.toolCalls)) {
1226
+ for (const toolCall of result.toolCalls) {
1227
+ content.push({
1228
+ type: 'function',
1229
+ id: toolCall.toolCallId,
1230
+ function: {
1231
+ name: toolCall.toolName,
1232
+ arguments: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args)
1233
+ }
1234
+ });
1235
+ }
1236
+ }
1237
+ if (content.length > 0) {
1238
+ return [{
1239
+ role: 'assistant',
1240
+ content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
1241
+ }];
1242
+ }
1243
+ // Fallback to original behavior for other result types TODO: check if we can remove this
1039
1244
  const normalizedResult = typeof result === 'string' ? {
1040
1245
  text: result
1041
1246
  } : result;
@@ -1046,8 +1251,8 @@ const mapVercelOutput = result => {
1046
1251
  ...(normalizedResult.object ? {
1047
1252
  object: normalizedResult.object
1048
1253
  } : {}),
1049
- ...(normalizedResult.reasoning ? {
1050
- reasoning: normalizedResult.reasoning
1254
+ ...(normalizedResult.reasoningText ? {
1255
+ reasoning: normalizedResult.reasoningText
1051
1256
  } : {}),
1052
1257
  ...(normalizedResult.response ? {
1053
1258
  response: normalizedResult.response
@@ -1106,14 +1311,14 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1106
1311
  ...options,
1107
1312
  ...mapVercelParams(params)
1108
1313
  };
1314
+ const availableTools = extractAvailableToolCalls('vercel', params);
1109
1315
  try {
1110
1316
  const result = await doGenerate();
1111
- const latency = (Date.now() - startTime) / 1000;
1112
1317
  const modelId = options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
1113
1318
  const provider = options.posthogProviderOverride ?? extractProvider(model);
1114
1319
  const baseURL = ''; // cannot currently get baseURL from vercel
1115
1320
  const content = mapVercelOutput(result);
1116
- // let tools = result.toolCalls
1321
+ const latency = (Date.now() - startTime) / 1000;
1117
1322
  const providerMetadata = result.providerMetadata;
1118
1323
  const additionalTokenValues = {
1119
1324
  ...(providerMetadata?.openai?.reasoningTokens ? {
@@ -1134,19 +1339,17 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1134
1339
  model: modelId,
1135
1340
  provider: provider,
1136
1341
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
1137
- output: [{
1138
- content,
1139
- role: 'assistant'
1140
- }],
1342
+ output: content,
1141
1343
  latency,
1142
1344
  baseURL,
1143
1345
  params: mergedParams,
1144
1346
  httpStatus: 200,
1145
1347
  usage: {
1146
- inputTokens: result.usage.promptTokens,
1147
- outputTokens: result.usage.completionTokens,
1348
+ inputTokens: result.usage.inputTokens,
1349
+ outputTokens: result.usage.outputTokens,
1148
1350
  ...additionalTokenValues
1149
1351
  },
1352
+ tools: availableTools,
1150
1353
  captureImmediate: options.posthogCaptureImmediate
1151
1354
  });
1152
1355
  return result;
@@ -1170,6 +1373,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1170
1373
  },
1171
1374
  isError: true,
1172
1375
  error: truncate(JSON.stringify(error)),
1376
+ tools: availableTools,
1173
1377
  captureImmediate: options.posthogCaptureImmediate
1174
1378
  });
1175
1379
  throw error;
@@ -1181,6 +1385,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1181
1385
  }) => {
1182
1386
  const startTime = Date.now();
1183
1387
  let generatedText = '';
1388
+ let reasoningText = '';
1184
1389
  let usage = {};
1185
1390
  const mergedParams = {
1186
1391
  ...options,
@@ -1188,6 +1393,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1188
1393
  };
1189
1394
  const modelId = options.posthogModelOverride ?? model.modelId;
1190
1395
  const provider = options.posthogProviderOverride ?? extractProvider(model);
1396
+ const availableTools = extractAvailableToolCalls('vercel', params);
1191
1397
  const baseURL = ''; // cannot currently get baseURL from vercel
1192
1398
  try {
1193
1399
  const {
@@ -1196,13 +1402,17 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1196
1402
  } = await doStream();
1197
1403
  const transformStream = new TransformStream({
1198
1404
  transform(chunk, controller) {
1405
+ // Handle new v5 streaming patterns
1199
1406
  if (chunk.type === 'text-delta') {
1200
- generatedText += chunk.textDelta;
1407
+ generatedText += chunk.delta;
1408
+ }
1409
+ if (chunk.type === 'reasoning-delta') {
1410
+ reasoningText += chunk.delta; // New in v5
1201
1411
  }
1202
1412
  if (chunk.type === 'finish') {
1203
1413
  usage = {
1204
- inputTokens: chunk.usage?.promptTokens,
1205
- outputTokens: chunk.usage?.completionTokens
1414
+ inputTokens: chunk.usage?.inputTokens,
1415
+ outputTokens: chunk.usage?.outputTokens
1206
1416
  };
1207
1417
  if (chunk.providerMetadata?.openai?.reasoningTokens) {
1208
1418
  usage.reasoningTokens = chunk.providerMetadata.openai.reasoningTokens;
@@ -1221,6 +1431,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1221
1431
  },
1222
1432
  flush: async () => {
1223
1433
  const latency = (Date.now() - startTime) / 1000;
1434
+ const outputContent = reasoningText ? `${reasoningText}\n\n${generatedText}` : generatedText;
1224
1435
  await sendEventToPosthog({
1225
1436
  client: phClient,
1226
1437
  distinctId: options.posthogDistinctId,
@@ -1229,7 +1440,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1229
1440
  provider: provider,
1230
1441
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
1231
1442
  output: [{
1232
- content: generatedText,
1443
+ content: outputContent,
1233
1444
  role: 'assistant'
1234
1445
  }],
1235
1446
  latency,
@@ -1237,6 +1448,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1237
1448
  params: mergedParams,
1238
1449
  httpStatus: 200,
1239
1450
  usage,
1451
+ tools: availableTools,
1240
1452
  captureImmediate: options.posthogCaptureImmediate
1241
1453
  });
1242
1454
  }
@@ -1264,6 +1476,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
1264
1476
  },
1265
1477
  isError: true,
1266
1478
  error: truncate(JSON.stringify(error)),
1479
+ tools: availableTools,
1267
1480
  captureImmediate: options.posthogCaptureImmediate
1268
1481
  });
1269
1482
  throw error;
@@ -1279,7 +1492,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1279
1492
  posthogTraceId: traceId,
1280
1493
  posthogDistinctId: options.posthogDistinctId
1281
1494
  });
1282
- const wrappedModel = experimental_wrapLanguageModel({
1495
+ const wrappedModel = wrapLanguageModel({
1283
1496
  model,
1284
1497
  middleware
1285
1498
  });
@@ -1346,6 +1559,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1346
1559
  }
1347
1560
  }
1348
1561
  const latency = (Date.now() - startTime) / 1000;
1562
+ const availableTools = extractAvailableToolCalls('anthropic', anthropicParams);
1349
1563
  await sendEventToPosthog({
1350
1564
  client: this.phClient,
1351
1565
  distinctId: posthogDistinctId,
@@ -1362,6 +1576,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1362
1576
  params: body,
1363
1577
  httpStatus: 200,
1364
1578
  usage,
1579
+ tools: availableTools,
1365
1580
  captureImmediate: posthogCaptureImmediate
1366
1581
  });
1367
1582
  } catch (error) {
@@ -1372,7 +1587,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1372
1587
  traceId,
1373
1588
  model: anthropicParams.model,
1374
1589
  provider: 'anthropic',
1375
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1590
+ input: mergeSystemPrompt(anthropicParams),
1376
1591
  output: [],
1377
1592
  latency: 0,
1378
1593
  baseURL: this.baseURL ?? '',
@@ -1397,13 +1612,14 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1397
1612
  const wrappedPromise = parentPromise.then(async result => {
1398
1613
  if ('content' in result) {
1399
1614
  const latency = (Date.now() - startTime) / 1000;
1615
+ const availableTools = extractAvailableToolCalls('anthropic', anthropicParams);
1400
1616
  await sendEventToPosthog({
1401
1617
  client: this.phClient,
1402
1618
  distinctId: posthogDistinctId,
1403
1619
  traceId,
1404
1620
  model: anthropicParams.model,
1405
1621
  provider: 'anthropic',
1406
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1622
+ input: mergeSystemPrompt(anthropicParams),
1407
1623
  output: formatResponseAnthropic(result),
1408
1624
  latency,
1409
1625
  baseURL: this.baseURL ?? '',
@@ -1415,6 +1631,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1415
1631
  cacheCreationInputTokens: result.usage.cache_creation_input_tokens ?? 0,
1416
1632
  cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0
1417
1633
  },
1634
+ tools: availableTools,
1418
1635
  captureImmediate: posthogCaptureImmediate
1419
1636
  });
1420
1637
  }
@@ -1426,7 +1643,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
1426
1643
  traceId,
1427
1644
  model: anthropicParams.model,
1428
1645
  provider: 'anthropic',
1429
- input: mergeSystemPrompt(anthropicParams, 'anthropic'),
1646
+ input: mergeSystemPrompt(anthropicParams),
1430
1647
  output: [],
1431
1648
  latency: 0,
1432
1649
  baseURL: this.baseURL ?? '',
@@ -1477,6 +1694,7 @@ class WrappedModels {
1477
1694
  try {
1478
1695
  const response = await this.client.models.generateContent(geminiParams);
1479
1696
  const latency = (Date.now() - startTime) / 1000;
1697
+ const availableTools = extractAvailableToolCalls('gemini', geminiParams);
1480
1698
  await sendEventToPosthog({
1481
1699
  client: this.phClient,
1482
1700
  distinctId: posthogDistinctId,
@@ -1484,7 +1702,7 @@ class WrappedModels {
1484
1702
  model: geminiParams.model,
1485
1703
  provider: 'gemini',
1486
1704
  input: this.formatInput(geminiParams.contents),
1487
- output: this.formatOutput(response),
1705
+ output: formatResponseGemini(response),
1488
1706
  latency,
1489
1707
  baseURL: 'https://generativelanguage.googleapis.com',
1490
1708
  params: params,
@@ -1493,6 +1711,7 @@ class WrappedModels {
1493
1711
  inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
1494
1712
  outputTokens: response.usageMetadata?.candidatesTokenCount ?? 0
1495
1713
  },
1714
+ tools: availableTools,
1496
1715
  captureImmediate: posthogCaptureImmediate
1497
1716
  });
1498
1717
  return response;
@@ -1552,6 +1771,7 @@ class WrappedModels {
1552
1771
  yield chunk;
1553
1772
  }
1554
1773
  const latency = (Date.now() - startTime) / 1000;
1774
+ const availableTools = extractAvailableToolCalls('gemini', geminiParams);
1555
1775
  await sendEventToPosthog({
1556
1776
  client: this.phClient,
1557
1777
  distinctId: posthogDistinctId,
@@ -1568,6 +1788,7 @@ class WrappedModels {
1568
1788
  params: params,
1569
1789
  httpStatus: 200,
1570
1790
  usage,
1791
+ tools: availableTools,
1571
1792
  captureImmediate: posthogCaptureImmediate
1572
1793
  });
1573
1794
  } catch (error) {
@@ -1649,487 +1870,523 @@ class WrappedModels {
1649
1870
  content: String(contents)
1650
1871
  }];
1651
1872
  }
1652
- formatOutput(response) {
1653
- if (response.text) {
1654
- return [{
1655
- role: 'assistant',
1656
- content: response.text
1657
- }];
1658
- }
1659
- if (response.candidates && Array.isArray(response.candidates)) {
1660
- return response.candidates.map(candidate => {
1661
- if (candidate.content && candidate.content.parts) {
1662
- const text = candidate.content.parts.filter(part => part.text).map(part => part.text).join('');
1663
- return {
1664
- role: 'assistant',
1665
- content: text
1666
- };
1667
- }
1668
- return {
1669
- role: 'assistant',
1670
- content: String(candidate)
1671
- };
1672
- });
1673
- }
1674
- return [];
1675
- }
1676
1873
  }
1677
1874
 
1678
- var decamelize = function (str, sep) {
1679
- if (typeof str !== 'string') {
1680
- throw new TypeError('Expected a string');
1681
- }
1682
- sep = typeof sep === 'undefined' ? '_' : sep;
1683
- return str
1684
- .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2')
1685
- .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2')
1686
- .toLowerCase();
1687
- };
1875
+ function getDefaultExportFromCjs (x) {
1876
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1877
+ }
1878
+
1879
+ var decamelize;
1880
+ var hasRequiredDecamelize;
1881
+
1882
+ function requireDecamelize () {
1883
+ if (hasRequiredDecamelize) return decamelize;
1884
+ hasRequiredDecamelize = 1;
1885
+ decamelize = function (str, sep) {
1886
+ if (typeof str !== 'string') {
1887
+ throw new TypeError('Expected a string');
1888
+ }
1889
+
1890
+ sep = typeof sep === 'undefined' ? '_' : sep;
1891
+
1892
+ return str
1893
+ .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2')
1894
+ .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2')
1895
+ .toLowerCase();
1896
+ };
1897
+ return decamelize;
1898
+ }
1899
+
1900
+ var decamelizeExports = requireDecamelize();
1901
+ var snakeCase = /*@__PURE__*/getDefaultExportFromCjs(decamelizeExports);
1688
1902
 
1689
1903
  var camelcase = {exports: {}};
1690
1904
 
1691
- const UPPERCASE = /[\p{Lu}]/u;
1692
- const LOWERCASE = /[\p{Ll}]/u;
1693
- const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
1694
- const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
1695
- const SEPARATORS = /[_.\- ]+/;
1696
- const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
1697
- const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
1698
- const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
1699
- const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
1700
- let isLastCharLower = false;
1701
- let isLastCharUpper = false;
1702
- let isLastLastCharUpper = false;
1703
- for (let i = 0; i < string.length; i++) {
1704
- const character = string[i];
1705
- if (isLastCharLower && UPPERCASE.test(character)) {
1706
- string = string.slice(0, i) + '-' + string.slice(i);
1707
- isLastCharLower = false;
1708
- isLastLastCharUpper = isLastCharUpper;
1709
- isLastCharUpper = true;
1710
- i++;
1711
- }
1712
- else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
1713
- string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
1714
- isLastLastCharUpper = isLastCharUpper;
1715
- isLastCharUpper = false;
1716
- isLastCharLower = true;
1717
- }
1718
- else {
1719
- isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
1720
- isLastLastCharUpper = isLastCharUpper;
1721
- isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
1722
- }
1723
- }
1724
- return string;
1725
- };
1726
- const preserveConsecutiveUppercase = (input, toLowerCase) => {
1727
- LEADING_CAPITAL.lastIndex = 0;
1728
- return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
1729
- };
1730
- const postProcess = (input, toUpperCase) => {
1731
- SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
1732
- NUMBERS_AND_IDENTIFIER.lastIndex = 0;
1733
- return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
1734
- .replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
1735
- };
1736
- const camelCase = (input, options) => {
1737
- if (!(typeof input === 'string' || Array.isArray(input))) {
1738
- throw new TypeError('Expected the input to be `string | string[]`');
1739
- }
1740
- options = {
1741
- pascalCase: false,
1742
- preserveConsecutiveUppercase: false,
1743
- ...options
1744
- };
1745
- if (Array.isArray(input)) {
1746
- input = input.map(x => x.trim())
1747
- .filter(x => x.length)
1748
- .join('-');
1749
- }
1750
- else {
1751
- input = input.trim();
1752
- }
1753
- if (input.length === 0) {
1754
- return '';
1755
- }
1756
- const toLowerCase = options.locale === false ?
1757
- string => string.toLowerCase() :
1758
- string => string.toLocaleLowerCase(options.locale);
1759
- const toUpperCase = options.locale === false ?
1760
- string => string.toUpperCase() :
1761
- string => string.toLocaleUpperCase(options.locale);
1762
- if (input.length === 1) {
1763
- return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
1764
- }
1765
- const hasUpperCase = input !== toLowerCase(input);
1766
- if (hasUpperCase) {
1767
- input = preserveCamelCase(input, toLowerCase, toUpperCase);
1768
- }
1769
- input = input.replace(LEADING_SEPARATORS, '');
1770
- if (options.preserveConsecutiveUppercase) {
1771
- input = preserveConsecutiveUppercase(input, toLowerCase);
1772
- }
1773
- else {
1774
- input = toLowerCase(input);
1775
- }
1776
- if (options.pascalCase) {
1777
- input = toUpperCase(input.charAt(0)) + input.slice(1);
1778
- }
1779
- return postProcess(input, toUpperCase);
1780
- };
1781
- camelcase.exports = camelCase;
1782
- // TODO: Remove this for the next major release
1783
- camelcase.exports.default = camelCase;
1905
+ var hasRequiredCamelcase;
1906
+
1907
+ function requireCamelcase () {
1908
+ if (hasRequiredCamelcase) return camelcase.exports;
1909
+ hasRequiredCamelcase = 1;
1910
+
1911
+ const UPPERCASE = /[\p{Lu}]/u;
1912
+ const LOWERCASE = /[\p{Ll}]/u;
1913
+ const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
1914
+ const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
1915
+ const SEPARATORS = /[_.\- ]+/;
1916
+
1917
+ const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
1918
+ const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
1919
+ const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
1920
+
1921
+ const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
1922
+ let isLastCharLower = false;
1923
+ let isLastCharUpper = false;
1924
+ let isLastLastCharUpper = false;
1925
+
1926
+ for (let i = 0; i < string.length; i++) {
1927
+ const character = string[i];
1928
+
1929
+ if (isLastCharLower && UPPERCASE.test(character)) {
1930
+ string = string.slice(0, i) + '-' + string.slice(i);
1931
+ isLastCharLower = false;
1932
+ isLastLastCharUpper = isLastCharUpper;
1933
+ isLastCharUpper = true;
1934
+ i++;
1935
+ } else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
1936
+ string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
1937
+ isLastLastCharUpper = isLastCharUpper;
1938
+ isLastCharUpper = false;
1939
+ isLastCharLower = true;
1940
+ } else {
1941
+ isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
1942
+ isLastLastCharUpper = isLastCharUpper;
1943
+ isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
1944
+ }
1945
+ }
1946
+
1947
+ return string;
1948
+ };
1949
+
1950
+ const preserveConsecutiveUppercase = (input, toLowerCase) => {
1951
+ LEADING_CAPITAL.lastIndex = 0;
1952
+
1953
+ return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
1954
+ };
1955
+
1956
+ const postProcess = (input, toUpperCase) => {
1957
+ SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
1958
+ NUMBERS_AND_IDENTIFIER.lastIndex = 0;
1959
+
1960
+ return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
1961
+ .replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
1962
+ };
1963
+
1964
+ const camelCase = (input, options) => {
1965
+ if (!(typeof input === 'string' || Array.isArray(input))) {
1966
+ throw new TypeError('Expected the input to be `string | string[]`');
1967
+ }
1784
1968
 
1785
- function keyToJson(key, map) {
1786
- return map?.[key] || decamelize(key);
1787
- }
1788
- function mapKeys(fields, mapper, map) {
1789
- const mapped = {};
1790
- for (const key in fields) {
1791
- if (Object.hasOwn(fields, key)) {
1792
- mapped[mapper(key, map)] = fields[key];
1793
- }
1794
- }
1795
- return mapped;
1969
+ options = {
1970
+ pascalCase: false,
1971
+ preserveConsecutiveUppercase: false,
1972
+ ...options
1973
+ };
1974
+
1975
+ if (Array.isArray(input)) {
1976
+ input = input.map(x => x.trim())
1977
+ .filter(x => x.length)
1978
+ .join('-');
1979
+ } else {
1980
+ input = input.trim();
1981
+ }
1982
+
1983
+ if (input.length === 0) {
1984
+ return '';
1985
+ }
1986
+
1987
+ const toLowerCase = options.locale === false ?
1988
+ string => string.toLowerCase() :
1989
+ string => string.toLocaleLowerCase(options.locale);
1990
+ const toUpperCase = options.locale === false ?
1991
+ string => string.toUpperCase() :
1992
+ string => string.toLocaleUpperCase(options.locale);
1993
+
1994
+ if (input.length === 1) {
1995
+ return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
1996
+ }
1997
+
1998
+ const hasUpperCase = input !== toLowerCase(input);
1999
+
2000
+ if (hasUpperCase) {
2001
+ input = preserveCamelCase(input, toLowerCase, toUpperCase);
2002
+ }
2003
+
2004
+ input = input.replace(LEADING_SEPARATORS, '');
2005
+
2006
+ if (options.preserveConsecutiveUppercase) {
2007
+ input = preserveConsecutiveUppercase(input, toLowerCase);
2008
+ } else {
2009
+ input = toLowerCase(input);
2010
+ }
2011
+
2012
+ if (options.pascalCase) {
2013
+ input = toUpperCase(input.charAt(0)) + input.slice(1);
2014
+ }
2015
+
2016
+ return postProcess(input, toUpperCase);
2017
+ };
2018
+
2019
+ camelcase.exports = camelCase;
2020
+ // TODO: Remove this for the next major release
2021
+ camelcase.exports.default = camelCase;
2022
+ return camelcase.exports;
1796
2023
  }
1797
2024
 
1798
- function shallowCopy(obj) {
1799
- return Array.isArray(obj) ? [...obj] : { ...obj };
1800
- }
1801
- function replaceSecrets(root, secretsMap) {
1802
- const result = shallowCopy(root);
1803
- for (const [path, secretId] of Object.entries(secretsMap)) {
1804
- const [last, ...partsReverse] = path.split(".").reverse();
1805
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1806
- let current = result;
1807
- for (const part of partsReverse.reverse()) {
1808
- if (current[part] === undefined) {
1809
- break;
1810
- }
1811
- current[part] = shallowCopy(current[part]);
1812
- current = current[part];
1813
- }
1814
- if (current[last] !== undefined) {
1815
- current[last] = {
1816
- lc: 1,
1817
- type: "secret",
1818
- id: [secretId],
1819
- };
1820
- }
1821
- }
1822
- return result;
1823
- }
1824
- /**
1825
- * Get a unique name for the module, rather than parent class implementations.
1826
- * Should not be subclassed, subclass lc_name above instead.
1827
- */
1828
- function get_lc_unique_name(
1829
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
1830
- serializableClass) {
1831
- // "super" here would refer to the parent class of Serializable,
1832
- // when we want the parent class of the module actually calling this method.
1833
- const parentClass = Object.getPrototypeOf(serializableClass);
1834
- const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
1835
- (typeof parentClass.lc_name !== "function" ||
1836
- serializableClass.lc_name() !== parentClass.lc_name());
1837
- if (lcNameIsSubclassed) {
1838
- return serializableClass.lc_name();
1839
- }
1840
- else {
1841
- return serializableClass.name;
1842
- }
1843
- }
1844
- class Serializable {
1845
- /**
1846
- * The name of the serializable. Override to provide an alias or
1847
- * to preserve the serialized module name in minified environments.
1848
- *
1849
- * Implemented as a static method to support loading logic.
1850
- */
1851
- static lc_name() {
1852
- return this.name;
1853
- }
1854
- /**
1855
- * The final serialized identifier for the module.
1856
- */
1857
- get lc_id() {
1858
- return [
1859
- ...this.lc_namespace,
1860
- get_lc_unique_name(this.constructor),
1861
- ];
1862
- }
1863
- /**
1864
- * A map of secrets, which will be omitted from serialization.
1865
- * Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
1866
- * Values are the secret ids, which will be used when deserializing.
1867
- */
1868
- get lc_secrets() {
1869
- return undefined;
1870
- }
1871
- /**
1872
- * A map of additional attributes to merge with constructor args.
1873
- * Keys are the attribute names, e.g. "foo".
1874
- * Values are the attribute values, which will be serialized.
1875
- * These attributes need to be accepted by the constructor as arguments.
1876
- */
1877
- get lc_attributes() {
1878
- return undefined;
1879
- }
1880
- /**
1881
- * A map of aliases for constructor args.
1882
- * Keys are the attribute names, e.g. "foo".
1883
- * Values are the alias that will replace the key in serialization.
1884
- * This is used to eg. make argument names match Python.
1885
- */
1886
- get lc_aliases() {
1887
- return undefined;
1888
- }
1889
- constructor(kwargs, ..._args) {
1890
- Object.defineProperty(this, "lc_serializable", {
1891
- enumerable: true,
1892
- configurable: true,
1893
- writable: true,
1894
- value: false
1895
- });
1896
- Object.defineProperty(this, "lc_kwargs", {
1897
- enumerable: true,
1898
- configurable: true,
1899
- writable: true,
1900
- value: void 0
1901
- });
1902
- this.lc_kwargs = kwargs || {};
1903
- }
1904
- toJSON() {
1905
- if (!this.lc_serializable) {
1906
- return this.toJSONNotImplemented();
1907
- }
1908
- if (
1909
- // eslint-disable-next-line no-instanceof/no-instanceof
1910
- this.lc_kwargs instanceof Serializable ||
1911
- typeof this.lc_kwargs !== "object" ||
1912
- Array.isArray(this.lc_kwargs)) {
1913
- // We do not support serialization of classes with arg not a POJO
1914
- // I'm aware the check above isn't as strict as it could be
1915
- return this.toJSONNotImplemented();
1916
- }
1917
- const aliases = {};
1918
- const secrets = {};
1919
- const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
1920
- acc[key] = key in this ? this[key] : this.lc_kwargs[key];
1921
- return acc;
1922
- }, {});
1923
- // get secrets, attributes and aliases from all superclasses
1924
- for (
1925
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1926
- let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
1927
- Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
1928
- Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
1929
- Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
1930
- }
1931
- // include all secrets used, even if not in kwargs,
1932
- // will be replaced with sentinel value in replaceSecrets
1933
- Object.keys(secrets).forEach((keyPath) => {
1934
- // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
1935
- let read = this;
1936
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1937
- let write = kwargs;
1938
- const [last, ...partsReverse] = keyPath.split(".").reverse();
1939
- for (const key of partsReverse.reverse()) {
1940
- if (!(key in read) || read[key] === undefined)
1941
- return;
1942
- if (!(key in write) || write[key] === undefined) {
1943
- if (typeof read[key] === "object" && read[key] != null) {
1944
- write[key] = {};
1945
- }
1946
- else if (Array.isArray(read[key])) {
1947
- write[key] = [];
1948
- }
1949
- }
1950
- read = read[key];
1951
- write = write[key];
1952
- }
1953
- if (last in read && read[last] !== undefined) {
1954
- write[last] = write[last] || read[last];
1955
- }
1956
- });
1957
- return {
1958
- lc: 1,
1959
- type: "constructor",
1960
- id: this.lc_id,
1961
- kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
1962
- };
1963
- }
1964
- toJSONNotImplemented() {
1965
- return {
1966
- lc: 1,
1967
- type: "not_implemented",
1968
- id: this.lc_id,
1969
- };
1970
- }
2025
+ requireCamelcase();
2026
+
2027
+ function keyToJson(key, map) {
2028
+ return map?.[key] || snakeCase(key);
2029
+ }
2030
+ function mapKeys(fields, mapper, map) {
2031
+ const mapped = {};
2032
+ for (const key in fields) {
2033
+ if (Object.hasOwn(fields, key)) {
2034
+ mapped[mapper(key, map)] = fields[key];
2035
+ }
2036
+ }
2037
+ return mapped;
1971
2038
  }
1972
2039
 
1973
- // Supabase Edge Function provides a `Deno` global object
1974
- // without `version` property
1975
- const isDeno = () => typeof Deno !== "undefined";
1976
- function getEnvironmentVariable(name) {
1977
- // Certain Deno setups will throw an error if you try to access environment variables
1978
- // https://github.com/langchain-ai/langchainjs/issues/1412
1979
- try {
1980
- if (typeof process !== "undefined") {
1981
- // eslint-disable-next-line no-process-env
1982
- return process.env?.[name];
1983
- }
1984
- else if (isDeno()) {
1985
- return Deno?.env.get(name);
1986
- }
1987
- else {
1988
- return undefined;
1989
- }
1990
- }
1991
- catch (e) {
1992
- return undefined;
1993
- }
2040
+ function shallowCopy(obj) {
2041
+ return Array.isArray(obj) ? [...obj] : { ...obj };
2042
+ }
2043
+ function replaceSecrets(root, secretsMap) {
2044
+ const result = shallowCopy(root);
2045
+ for (const [path, secretId] of Object.entries(secretsMap)) {
2046
+ const [last, ...partsReverse] = path.split(".").reverse();
2047
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2048
+ let current = result;
2049
+ for (const part of partsReverse.reverse()) {
2050
+ if (current[part] === undefined) {
2051
+ break;
2052
+ }
2053
+ current[part] = shallowCopy(current[part]);
2054
+ current = current[part];
2055
+ }
2056
+ if (current[last] !== undefined) {
2057
+ current[last] = {
2058
+ lc: 1,
2059
+ type: "secret",
2060
+ id: [secretId],
2061
+ };
2062
+ }
2063
+ }
2064
+ return result;
2065
+ }
2066
+ /**
2067
+ * Get a unique name for the module, rather than parent class implementations.
2068
+ * Should not be subclassed, subclass lc_name above instead.
2069
+ */
2070
+ function get_lc_unique_name(
2071
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
2072
+ serializableClass) {
2073
+ // "super" here would refer to the parent class of Serializable,
2074
+ // when we want the parent class of the module actually calling this method.
2075
+ const parentClass = Object.getPrototypeOf(serializableClass);
2076
+ const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
2077
+ (typeof parentClass.lc_name !== "function" ||
2078
+ serializableClass.lc_name() !== parentClass.lc_name());
2079
+ if (lcNameIsSubclassed) {
2080
+ return serializableClass.lc_name();
2081
+ }
2082
+ else {
2083
+ return serializableClass.name;
2084
+ }
2085
+ }
2086
+ class Serializable {
2087
+ /**
2088
+ * The name of the serializable. Override to provide an alias or
2089
+ * to preserve the serialized module name in minified environments.
2090
+ *
2091
+ * Implemented as a static method to support loading logic.
2092
+ */
2093
+ static lc_name() {
2094
+ return this.name;
2095
+ }
2096
+ /**
2097
+ * The final serialized identifier for the module.
2098
+ */
2099
+ get lc_id() {
2100
+ return [
2101
+ ...this.lc_namespace,
2102
+ get_lc_unique_name(this.constructor),
2103
+ ];
2104
+ }
2105
+ /**
2106
+ * A map of secrets, which will be omitted from serialization.
2107
+ * Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
2108
+ * Values are the secret ids, which will be used when deserializing.
2109
+ */
2110
+ get lc_secrets() {
2111
+ return undefined;
2112
+ }
2113
+ /**
2114
+ * A map of additional attributes to merge with constructor args.
2115
+ * Keys are the attribute names, e.g. "foo".
2116
+ * Values are the attribute values, which will be serialized.
2117
+ * These attributes need to be accepted by the constructor as arguments.
2118
+ */
2119
+ get lc_attributes() {
2120
+ return undefined;
2121
+ }
2122
+ /**
2123
+ * A map of aliases for constructor args.
2124
+ * Keys are the attribute names, e.g. "foo".
2125
+ * Values are the alias that will replace the key in serialization.
2126
+ * This is used to eg. make argument names match Python.
2127
+ */
2128
+ get lc_aliases() {
2129
+ return undefined;
2130
+ }
2131
+ /**
2132
+ * A manual list of keys that should be serialized.
2133
+ * If not overridden, all fields passed into the constructor will be serialized.
2134
+ */
2135
+ get lc_serializable_keys() {
2136
+ return undefined;
2137
+ }
2138
+ constructor(kwargs, ..._args) {
2139
+ Object.defineProperty(this, "lc_serializable", {
2140
+ enumerable: true,
2141
+ configurable: true,
2142
+ writable: true,
2143
+ value: false
2144
+ });
2145
+ Object.defineProperty(this, "lc_kwargs", {
2146
+ enumerable: true,
2147
+ configurable: true,
2148
+ writable: true,
2149
+ value: void 0
2150
+ });
2151
+ if (this.lc_serializable_keys !== undefined) {
2152
+ this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
2153
+ }
2154
+ else {
2155
+ this.lc_kwargs = kwargs ?? {};
2156
+ }
2157
+ }
2158
+ toJSON() {
2159
+ if (!this.lc_serializable) {
2160
+ return this.toJSONNotImplemented();
2161
+ }
2162
+ if (
2163
+ // eslint-disable-next-line no-instanceof/no-instanceof
2164
+ this.lc_kwargs instanceof Serializable ||
2165
+ typeof this.lc_kwargs !== "object" ||
2166
+ Array.isArray(this.lc_kwargs)) {
2167
+ // We do not support serialization of classes with arg not a POJO
2168
+ // I'm aware the check above isn't as strict as it could be
2169
+ return this.toJSONNotImplemented();
2170
+ }
2171
+ const aliases = {};
2172
+ const secrets = {};
2173
+ const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
2174
+ acc[key] = key in this ? this[key] : this.lc_kwargs[key];
2175
+ return acc;
2176
+ }, {});
2177
+ // get secrets, attributes and aliases from all superclasses
2178
+ for (
2179
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
2180
+ let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
2181
+ Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
2182
+ Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
2183
+ Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
2184
+ }
2185
+ // include all secrets used, even if not in kwargs,
2186
+ // will be replaced with sentinel value in replaceSecrets
2187
+ Object.keys(secrets).forEach((keyPath) => {
2188
+ // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
2189
+ let read = this;
2190
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2191
+ let write = kwargs;
2192
+ const [last, ...partsReverse] = keyPath.split(".").reverse();
2193
+ for (const key of partsReverse.reverse()) {
2194
+ if (!(key in read) || read[key] === undefined)
2195
+ return;
2196
+ if (!(key in write) || write[key] === undefined) {
2197
+ if (typeof read[key] === "object" && read[key] != null) {
2198
+ write[key] = {};
2199
+ }
2200
+ else if (Array.isArray(read[key])) {
2201
+ write[key] = [];
2202
+ }
2203
+ }
2204
+ read = read[key];
2205
+ write = write[key];
2206
+ }
2207
+ if (last in read && read[last] !== undefined) {
2208
+ write[last] = write[last] || read[last];
2209
+ }
2210
+ });
2211
+ return {
2212
+ lc: 1,
2213
+ type: "constructor",
2214
+ id: this.lc_id,
2215
+ kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
2216
+ };
2217
+ }
2218
+ toJSONNotImplemented() {
2219
+ return {
2220
+ lc: 1,
2221
+ type: "not_implemented",
2222
+ id: this.lc_id,
2223
+ };
2224
+ }
1994
2225
  }
1995
2226
 
1996
- /**
1997
- * Abstract class that provides a set of optional methods that can be
1998
- * overridden in derived classes to handle various events during the
1999
- * execution of a LangChain application.
2000
- */
2001
- class BaseCallbackHandlerMethodsClass {
2002
- }
2003
- /**
2004
- * Abstract base class for creating callback handlers in the LangChain
2005
- * framework. It provides a set of optional methods that can be overridden
2006
- * in derived classes to handle various events during the execution of a
2007
- * LangChain application.
2008
- */
2009
- class BaseCallbackHandler extends BaseCallbackHandlerMethodsClass {
2010
- get lc_namespace() {
2011
- return ["langchain_core", "callbacks", this.name];
2012
- }
2013
- get lc_secrets() {
2014
- return undefined;
2015
- }
2016
- get lc_attributes() {
2017
- return undefined;
2018
- }
2019
- get lc_aliases() {
2020
- return undefined;
2021
- }
2022
- /**
2023
- * The name of the serializable. Override to provide an alias or
2024
- * to preserve the serialized module name in minified environments.
2025
- *
2026
- * Implemented as a static method to support loading logic.
2027
- */
2028
- static lc_name() {
2029
- return this.name;
2030
- }
2031
- /**
2032
- * The final serialized identifier for the module.
2033
- */
2034
- get lc_id() {
2035
- return [
2036
- ...this.lc_namespace,
2037
- get_lc_unique_name(this.constructor),
2038
- ];
2039
- }
2040
- constructor(input) {
2041
- super();
2042
- Object.defineProperty(this, "lc_serializable", {
2043
- enumerable: true,
2044
- configurable: true,
2045
- writable: true,
2046
- value: false
2047
- });
2048
- Object.defineProperty(this, "lc_kwargs", {
2049
- enumerable: true,
2050
- configurable: true,
2051
- writable: true,
2052
- value: void 0
2053
- });
2054
- Object.defineProperty(this, "ignoreLLM", {
2055
- enumerable: true,
2056
- configurable: true,
2057
- writable: true,
2058
- value: false
2059
- });
2060
- Object.defineProperty(this, "ignoreChain", {
2061
- enumerable: true,
2062
- configurable: true,
2063
- writable: true,
2064
- value: false
2065
- });
2066
- Object.defineProperty(this, "ignoreAgent", {
2067
- enumerable: true,
2068
- configurable: true,
2069
- writable: true,
2070
- value: false
2071
- });
2072
- Object.defineProperty(this, "ignoreRetriever", {
2073
- enumerable: true,
2074
- configurable: true,
2075
- writable: true,
2076
- value: false
2077
- });
2078
- Object.defineProperty(this, "ignoreCustomEvent", {
2079
- enumerable: true,
2080
- configurable: true,
2081
- writable: true,
2082
- value: false
2083
- });
2084
- Object.defineProperty(this, "raiseError", {
2085
- enumerable: true,
2086
- configurable: true,
2087
- writable: true,
2088
- value: false
2089
- });
2090
- Object.defineProperty(this, "awaitHandlers", {
2091
- enumerable: true,
2092
- configurable: true,
2093
- writable: true,
2094
- value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
2095
- });
2096
- this.lc_kwargs = input || {};
2097
- if (input) {
2098
- this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
2099
- this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
2100
- this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
2101
- this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
2102
- this.ignoreCustomEvent =
2103
- input.ignoreCustomEvent ?? this.ignoreCustomEvent;
2104
- this.raiseError = input.raiseError ?? this.raiseError;
2105
- this.awaitHandlers =
2106
- this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
2107
- }
2108
- }
2109
- copy() {
2110
- return new this.constructor(this);
2111
- }
2112
- toJSON() {
2113
- return Serializable.prototype.toJSON.call(this);
2114
- }
2115
- toJSONNotImplemented() {
2116
- return Serializable.prototype.toJSONNotImplemented.call(this);
2117
- }
2118
- static fromMethods(methods) {
2119
- class Handler extends BaseCallbackHandler {
2120
- constructor() {
2121
- super();
2122
- Object.defineProperty(this, "name", {
2123
- enumerable: true,
2124
- configurable: true,
2125
- writable: true,
2126
- value: uuid.v4()
2127
- });
2128
- Object.assign(this, methods);
2129
- }
2130
- }
2131
- return new Handler();
2132
- }
2227
+ // Supabase Edge Function provides a `Deno` global object
2228
+ // without `version` property
2229
+ const isDeno = () => typeof Deno !== "undefined";
2230
+ function getEnvironmentVariable(name) {
2231
+ // Certain Deno setups will throw an error if you try to access environment variables
2232
+ // https://github.com/langchain-ai/langchainjs/issues/1412
2233
+ try {
2234
+ if (typeof process !== "undefined") {
2235
+ // eslint-disable-next-line no-process-env
2236
+ return process.env?.[name];
2237
+ }
2238
+ else if (isDeno()) {
2239
+ return Deno?.env.get(name);
2240
+ }
2241
+ else {
2242
+ return undefined;
2243
+ }
2244
+ }
2245
+ catch (e) {
2246
+ return undefined;
2247
+ }
2248
+ }
2249
+
2250
+ /**
2251
+ * Abstract class that provides a set of optional methods that can be
2252
+ * overridden in derived classes to handle various events during the
2253
+ * execution of a LangChain application.
2254
+ */
2255
+ class BaseCallbackHandlerMethodsClass {
2256
+ }
2257
+ /**
2258
+ * Abstract base class for creating callback handlers in the LangChain
2259
+ * framework. It provides a set of optional methods that can be overridden
2260
+ * in derived classes to handle various events during the execution of a
2261
+ * LangChain application.
2262
+ */
2263
+ class BaseCallbackHandler extends BaseCallbackHandlerMethodsClass {
2264
+ get lc_namespace() {
2265
+ return ["langchain_core", "callbacks", this.name];
2266
+ }
2267
+ get lc_secrets() {
2268
+ return undefined;
2269
+ }
2270
+ get lc_attributes() {
2271
+ return undefined;
2272
+ }
2273
+ get lc_aliases() {
2274
+ return undefined;
2275
+ }
2276
+ get lc_serializable_keys() {
2277
+ return undefined;
2278
+ }
2279
+ /**
2280
+ * The name of the serializable. Override to provide an alias or
2281
+ * to preserve the serialized module name in minified environments.
2282
+ *
2283
+ * Implemented as a static method to support loading logic.
2284
+ */
2285
+ static lc_name() {
2286
+ return this.name;
2287
+ }
2288
+ /**
2289
+ * The final serialized identifier for the module.
2290
+ */
2291
+ get lc_id() {
2292
+ return [
2293
+ ...this.lc_namespace,
2294
+ get_lc_unique_name(this.constructor),
2295
+ ];
2296
+ }
2297
+ constructor(input) {
2298
+ super();
2299
+ Object.defineProperty(this, "lc_serializable", {
2300
+ enumerable: true,
2301
+ configurable: true,
2302
+ writable: true,
2303
+ value: false
2304
+ });
2305
+ Object.defineProperty(this, "lc_kwargs", {
2306
+ enumerable: true,
2307
+ configurable: true,
2308
+ writable: true,
2309
+ value: void 0
2310
+ });
2311
+ Object.defineProperty(this, "ignoreLLM", {
2312
+ enumerable: true,
2313
+ configurable: true,
2314
+ writable: true,
2315
+ value: false
2316
+ });
2317
+ Object.defineProperty(this, "ignoreChain", {
2318
+ enumerable: true,
2319
+ configurable: true,
2320
+ writable: true,
2321
+ value: false
2322
+ });
2323
+ Object.defineProperty(this, "ignoreAgent", {
2324
+ enumerable: true,
2325
+ configurable: true,
2326
+ writable: true,
2327
+ value: false
2328
+ });
2329
+ Object.defineProperty(this, "ignoreRetriever", {
2330
+ enumerable: true,
2331
+ configurable: true,
2332
+ writable: true,
2333
+ value: false
2334
+ });
2335
+ Object.defineProperty(this, "ignoreCustomEvent", {
2336
+ enumerable: true,
2337
+ configurable: true,
2338
+ writable: true,
2339
+ value: false
2340
+ });
2341
+ Object.defineProperty(this, "raiseError", {
2342
+ enumerable: true,
2343
+ configurable: true,
2344
+ writable: true,
2345
+ value: false
2346
+ });
2347
+ Object.defineProperty(this, "awaitHandlers", {
2348
+ enumerable: true,
2349
+ configurable: true,
2350
+ writable: true,
2351
+ value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
2352
+ });
2353
+ this.lc_kwargs = input || {};
2354
+ if (input) {
2355
+ this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
2356
+ this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
2357
+ this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
2358
+ this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
2359
+ this.ignoreCustomEvent =
2360
+ input.ignoreCustomEvent ?? this.ignoreCustomEvent;
2361
+ this.raiseError = input.raiseError ?? this.raiseError;
2362
+ this.awaitHandlers =
2363
+ this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
2364
+ }
2365
+ }
2366
+ copy() {
2367
+ return new this.constructor(this);
2368
+ }
2369
+ toJSON() {
2370
+ return Serializable.prototype.toJSON.call(this);
2371
+ }
2372
+ toJSONNotImplemented() {
2373
+ return Serializable.prototype.toJSONNotImplemented.call(this);
2374
+ }
2375
+ static fromMethods(methods) {
2376
+ class Handler extends BaseCallbackHandler {
2377
+ constructor() {
2378
+ super();
2379
+ Object.defineProperty(this, "name", {
2380
+ enumerable: true,
2381
+ configurable: true,
2382
+ writable: true,
2383
+ value: uuid.v4()
2384
+ });
2385
+ Object.assign(this, methods);
2386
+ }
2387
+ }
2388
+ return new Handler();
2389
+ }
2133
2390
  }
2134
2391
 
2135
2392
  class LangChainCallbackHandler extends BaseCallbackHandler {
@@ -2309,6 +2566,9 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2309
2566
  };
2310
2567
  if (extraParams) {
2311
2568
  generation.modelParams = getModelParams(extraParams.invocation_params);
2569
+ if (extraParams.invocation_params && extraParams.invocation_params.tools) {
2570
+ generation.tools = extraParams.invocation_params.tools;
2571
+ }
2312
2572
  }
2313
2573
  if (metadata) {
2314
2574
  if (metadata.ls_model_name) {
@@ -2415,7 +2675,7 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2415
2675
  $ai_base_url: run.baseUrl
2416
2676
  };
2417
2677
  if (run.tools) {
2418
- eventProperties['$ai_tools'] = withPrivacyMode(this.client, this.privacyMode, run.tools);
2678
+ eventProperties['$ai_tools'] = run.tools;
2419
2679
  }
2420
2680
  if (output instanceof Error) {
2421
2681
  eventProperties['$ai_http_status'] = output.status || 500;
@@ -2437,13 +2697,20 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2437
2697
  let completions;
2438
2698
  if (output.generations && Array.isArray(output.generations)) {
2439
2699
  const lastGeneration = output.generations[output.generations.length - 1];
2440
- if (Array.isArray(lastGeneration)) {
2441
- completions = lastGeneration.map(gen => {
2442
- return {
2443
- role: 'assistant',
2444
- content: gen.text
2445
- };
2446
- });
2700
+ if (Array.isArray(lastGeneration) && lastGeneration.length > 0) {
2701
+ // Check if this is a ChatGeneration by looking at the first item
2702
+ const isChatGeneration = 'message' in lastGeneration[0] && lastGeneration[0].message;
2703
+ if (isChatGeneration) {
2704
+ // For ChatGeneration, convert messages to dict format
2705
+ completions = lastGeneration.map(gen => {
2706
+ return this._convertMessageToDict(gen.message);
2707
+ });
2708
+ } else {
2709
+ // For non-ChatGeneration, extract raw response
2710
+ completions = lastGeneration.map(gen => {
2711
+ return this._extractRawResponse(gen);
2712
+ });
2713
+ }
2447
2714
  }
2448
2715
  }
2449
2716
  if (completions) {
@@ -2494,6 +2761,19 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
2494
2761
  }
2495
2762
  }));
2496
2763
  }
2764
+ _extractRawResponse(generation) {
2765
+ // Extract the response from the last response of the LLM call
2766
+ // We return the text of the response if not empty
2767
+ if (generation.text != null && generation.text.trim() !== '') {
2768
+ return generation.text.trim();
2769
+ } else if (generation.message) {
2770
+ // Additional kwargs contains the response in case of tool usage
2771
+ return generation.message.additional_kwargs || generation.message.additionalKwargs || {};
2772
+ } else {
2773
+ // Not tool usage, some LLM responses can be simply empty
2774
+ return '';
2775
+ }
2776
+ }
2497
2777
  _convertMessageToDict(message) {
2498
2778
  let messageDict = {};
2499
2779
  const messageType = message.getType();