@posthog/ai 7.3.2 → 7.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2,10 +2,11 @@ import { OpenAI, AzureOpenAI } from 'openai';
2
2
  import { Buffer } from 'buffer';
3
3
  import * as uuid from 'uuid';
4
4
  import { v4 } from 'uuid';
5
+ import { uuidv7 } from '@posthog/core';
5
6
  import AnthropicOriginal from '@anthropic-ai/sdk';
6
7
  import { GoogleGenAI } from '@google/genai';
7
8
 
8
- var version = "7.3.2";
9
+ var version = "7.4.1";
9
10
 
10
11
  // Type guards for safer type checking
11
12
  const isString = value => {
@@ -473,6 +474,33 @@ function addDefaults(params) {
473
474
  traceId: params.traceId ?? v4()
474
475
  };
475
476
  }
477
+ const sendEventWithErrorToPosthog = async ({
478
+ client,
479
+ traceId,
480
+ error,
481
+ ...args
482
+ }) => {
483
+ const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
484
+ const properties = {
485
+ client,
486
+ traceId,
487
+ httpStatus,
488
+ error: JSON.stringify(error),
489
+ ...args
490
+ };
491
+ const enrichedError = error;
492
+ if (client.options?.enableExceptionAutocapture) {
493
+ // assign a uuid that can be used to link the trace and exception events
494
+ const exceptionId = uuidv7();
495
+ client.captureException(error, undefined, {
496
+ $ai_trace_id: traceId
497
+ }, exceptionId);
498
+ enrichedError.__posthog_previously_captured_error = true;
499
+ properties.exceptionId = exceptionId;
500
+ }
501
+ await sendEventToPosthog(properties);
502
+ return enrichedError;
503
+ };
476
504
  const sendEventToPosthog = async ({
477
505
  client,
478
506
  eventType = AIEvent.Generation,
@@ -487,8 +515,8 @@ const sendEventToPosthog = async ({
487
515
  params,
488
516
  httpStatus = 200,
489
517
  usage = {},
490
- isError = false,
491
518
  error,
519
+ exceptionId,
492
520
  tools,
493
521
  captureImmediate = false
494
522
  }) => {
@@ -500,10 +528,11 @@ const sendEventToPosthog = async ({
500
528
  const safeOutput = sanitizeValues(output);
501
529
  const safeError = sanitizeValues(error);
502
530
  let errorData = {};
503
- if (isError) {
531
+ if (error) {
504
532
  errorData = {
505
533
  $ai_is_error: true,
506
- $ai_error: safeError
534
+ $ai_error: safeError,
535
+ $exception_event_id: exceptionId
507
536
  };
508
537
  }
509
538
  let costOverrideData = {};
@@ -569,6 +598,7 @@ const sendEventToPosthog = async ({
569
598
  } else {
570
599
  client.capture(event);
571
600
  }
601
+ return Promise.resolve();
572
602
  };
573
603
  function formatOpenAIResponsesInput(input, instructions) {
574
604
  const messages = [];
@@ -976,8 +1006,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
976
1006
  tools: availableTools
977
1007
  });
978
1008
  } catch (error) {
979
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
980
- await sendEventToPosthog({
1009
+ const enrichedError = await sendEventWithErrorToPosthog({
981
1010
  client: this.phClient,
982
1011
  ...posthogParams,
983
1012
  model: openAIParams.model,
@@ -987,14 +1016,13 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
987
1016
  latency: 0,
988
1017
  baseURL: this.baseURL,
989
1018
  params: body,
990
- httpStatus,
991
1019
  usage: {
992
1020
  inputTokens: 0,
993
1021
  outputTokens: 0
994
1022
  },
995
- isError: true,
996
- error: JSON.stringify(error)
1023
+ error
997
1024
  });
1025
+ throw enrichedError;
998
1026
  }
999
1027
  })();
1000
1028
  // Return the other stream to the user
@@ -1047,7 +1075,6 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1047
1075
  inputTokens: 0,
1048
1076
  outputTokens: 0
1049
1077
  },
1050
- isError: true,
1051
1078
  error: JSON.stringify(error)
1052
1079
  });
1053
1080
  throw error;
@@ -1130,8 +1157,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1130
1157
  tools: availableTools
1131
1158
  });
1132
1159
  } catch (error) {
1133
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1134
- await sendEventToPosthog({
1160
+ const enrichedError = await sendEventWithErrorToPosthog({
1135
1161
  client: this.phClient,
1136
1162
  ...posthogParams,
1137
1163
  model: openAIParams.model,
@@ -1141,14 +1167,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1141
1167
  latency: 0,
1142
1168
  baseURL: this.baseURL,
1143
1169
  params: body,
1144
- httpStatus,
1145
1170
  usage: {
1146
1171
  inputTokens: 0,
1147
1172
  outputTokens: 0
1148
1173
  },
1149
- isError: true,
1150
- error: JSON.stringify(error)
1174
+ error: error
1151
1175
  });
1176
+ throw enrichedError;
1152
1177
  }
1153
1178
  })();
1154
1179
  return stream2;
@@ -1202,7 +1227,6 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1202
1227
  inputTokens: 0,
1203
1228
  outputTokens: 0
1204
1229
  },
1205
- isError: true,
1206
1230
  error: JSON.stringify(error)
1207
1231
  });
1208
1232
  throw error;
@@ -1244,8 +1268,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1244
1268
  });
1245
1269
  return result;
1246
1270
  }, async error => {
1247
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1248
- await sendEventToPosthog({
1271
+ const enrichedError = await sendEventWithErrorToPosthog({
1249
1272
  client: this.phClient,
1250
1273
  ...posthogParams,
1251
1274
  model: openAIParams.model,
@@ -1255,15 +1278,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1255
1278
  latency: 0,
1256
1279
  baseURL: this.baseURL,
1257
1280
  params: body,
1258
- httpStatus,
1259
1281
  usage: {
1260
1282
  inputTokens: 0,
1261
1283
  outputTokens: 0
1262
1284
  },
1263
- isError: true,
1264
1285
  error: JSON.stringify(error)
1265
1286
  });
1266
- throw error;
1287
+ throw enrichedError;
1267
1288
  });
1268
1289
  return wrappedPromise;
1269
1290
  } finally {
@@ -1323,7 +1344,6 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends Embeddings {
1323
1344
  usage: {
1324
1345
  inputTokens: 0
1325
1346
  },
1326
- isError: true,
1327
1347
  error: JSON.stringify(error)
1328
1348
  });
1329
1349
  throw error;
@@ -1391,8 +1411,7 @@ class WrappedTranscriptions extends Transcriptions {
1391
1411
  tools: availableTools
1392
1412
  });
1393
1413
  } catch (error) {
1394
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1395
- await sendEventToPosthog({
1414
+ const enrichedError = await sendEventWithErrorToPosthog({
1396
1415
  client: this.phClient,
1397
1416
  ...posthogParams,
1398
1417
  model: openAIParams.model,
@@ -1402,14 +1421,13 @@ class WrappedTranscriptions extends Transcriptions {
1402
1421
  latency: 0,
1403
1422
  baseURL: this.baseURL,
1404
1423
  params: body,
1405
- httpStatus,
1406
1424
  usage: {
1407
1425
  inputTokens: 0,
1408
1426
  outputTokens: 0
1409
1427
  },
1410
- isError: true,
1411
- error: JSON.stringify(error)
1428
+ error: error
1412
1429
  });
1430
+ throw enrichedError;
1413
1431
  }
1414
1432
  })();
1415
1433
  return stream2;
@@ -1439,8 +1457,7 @@ class WrappedTranscriptions extends Transcriptions {
1439
1457
  return result;
1440
1458
  }
1441
1459
  }, async error => {
1442
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1443
- await sendEventToPosthog({
1460
+ const enrichedError = await sendEventWithErrorToPosthog({
1444
1461
  client: this.phClient,
1445
1462
  ...posthogParams,
1446
1463
  model: openAIParams.model,
@@ -1450,15 +1467,13 @@ class WrappedTranscriptions extends Transcriptions {
1450
1467
  latency: 0,
1451
1468
  baseURL: this.baseURL,
1452
1469
  params: body,
1453
- httpStatus,
1454
1470
  usage: {
1455
1471
  inputTokens: 0,
1456
1472
  outputTokens: 0
1457
1473
  },
1458
- isError: true,
1459
- error: JSON.stringify(error)
1474
+ error: error
1460
1475
  });
1461
- throw error;
1476
+ throw enrichedError;
1462
1477
  });
1463
1478
  return wrappedPromise;
1464
1479
  }
@@ -1609,8 +1624,7 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
1609
1624
  usage
1610
1625
  });
1611
1626
  } catch (error) {
1612
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1613
- await sendEventToPosthog({
1627
+ const enrichedError = await sendEventWithErrorToPosthog({
1614
1628
  client: this.phClient,
1615
1629
  ...posthogParams,
1616
1630
  model: openAIParams.model,
@@ -1620,14 +1634,13 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
1620
1634
  latency: 0,
1621
1635
  baseURL: this.baseURL,
1622
1636
  params: body,
1623
- httpStatus,
1624
1637
  usage: {
1625
1638
  inputTokens: 0,
1626
1639
  outputTokens: 0
1627
1640
  },
1628
- isError: true,
1629
- error: JSON.stringify(error)
1641
+ error: error
1630
1642
  });
1643
+ throw enrichedError;
1631
1644
  }
1632
1645
  })();
1633
1646
  // Return the other stream to the user
@@ -1676,7 +1689,6 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
1676
1689
  inputTokens: 0,
1677
1690
  outputTokens: 0
1678
1691
  },
1679
- isError: true,
1680
1692
  error: JSON.stringify(error)
1681
1693
  });
1682
1694
  throw error;
@@ -1745,8 +1757,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
1745
1757
  usage
1746
1758
  });
1747
1759
  } catch (error) {
1748
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1749
- await sendEventToPosthog({
1760
+ const enrichedError = await sendEventWithErrorToPosthog({
1750
1761
  client: this.phClient,
1751
1762
  ...posthogParams,
1752
1763
  model: openAIParams.model,
@@ -1756,14 +1767,13 @@ class WrappedResponses extends AzureOpenAI.Responses {
1756
1767
  latency: 0,
1757
1768
  baseURL: this.baseURL,
1758
1769
  params: body,
1759
- httpStatus,
1760
1770
  usage: {
1761
1771
  inputTokens: 0,
1762
1772
  outputTokens: 0
1763
1773
  },
1764
- isError: true,
1765
- error: JSON.stringify(error)
1774
+ error: error
1766
1775
  });
1776
+ throw enrichedError;
1767
1777
  }
1768
1778
  })();
1769
1779
  return stream2;
@@ -1811,7 +1821,6 @@ class WrappedResponses extends AzureOpenAI.Responses {
1811
1821
  inputTokens: 0,
1812
1822
  outputTokens: 0
1813
1823
  },
1814
- isError: true,
1815
1824
  error: JSON.stringify(error)
1816
1825
  });
1817
1826
  throw error;
@@ -1863,7 +1872,6 @@ class WrappedResponses extends AzureOpenAI.Responses {
1863
1872
  inputTokens: 0,
1864
1873
  outputTokens: 0
1865
1874
  },
1866
- isError: true,
1867
1875
  error: JSON.stringify(error)
1868
1876
  });
1869
1877
  throw error;
@@ -1921,7 +1929,6 @@ class WrappedEmbeddings extends AzureOpenAI.Embeddings {
1921
1929
  usage: {
1922
1930
  inputTokens: 0
1923
1931
  },
1924
- isError: true,
1925
1932
  error: JSON.stringify(error)
1926
1933
  });
1927
1934
  throw error;
@@ -1930,6 +1937,10 @@ class WrappedEmbeddings extends AzureOpenAI.Embeddings {
1930
1937
  }
1931
1938
  }
1932
1939
 
1940
+ // Type guards
1941
+ function isV3Model(model) {
1942
+ return model.specificationVersion === 'v3';
1943
+ }
1933
1944
  const mapVercelParams = params => {
1934
1945
  return {
1935
1946
  temperature: params.temperature,
@@ -2150,6 +2161,19 @@ const extractAdditionalTokenValues = providerMetadata => {
2150
2161
  }
2151
2162
  return {};
2152
2163
  };
2164
+ // For Anthropic providers in V3, inputTokens.total is the sum of all tokens (uncached + cache read + cache write).
2165
+ // Our cost calculation expects inputTokens to be only the uncached portion for Anthropic.
2166
+ // This helper subtracts cache tokens from inputTokens for Anthropic V3 models.
2167
+ const adjustAnthropicV3CacheTokens = (model, provider, usage) => {
2168
+ if (isV3Model(model) && provider.toLowerCase().includes('anthropic')) {
2169
+ const cacheReadTokens = usage.cacheReadInputTokens || 0;
2170
+ const cacheWriteTokens = usage.cacheCreationInputTokens || 0;
2171
+ const cacheTokens = cacheReadTokens + cacheWriteTokens;
2172
+ if (usage.inputTokens && cacheTokens > 0) {
2173
+ usage.inputTokens = Math.max(usage.inputTokens - cacheTokens, 0);
2174
+ }
2175
+ }
2176
+ };
2153
2177
  // Helper to extract numeric token value from V2 (number) or V3 (object with .total) usage formats
2154
2178
  const extractTokenCount = value => {
2155
2179
  if (typeof value === 'number') {
@@ -2230,6 +2254,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2230
2254
  webSearchCount,
2231
2255
  ...additionalTokenValues
2232
2256
  };
2257
+ adjustAnthropicV3CacheTokens(model, provider, usage);
2233
2258
  await sendEventToPosthog({
2234
2259
  client: phClient,
2235
2260
  distinctId: mergedOptions.posthogDistinctId,
@@ -2249,7 +2274,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2249
2274
  return result;
2250
2275
  } catch (error) {
2251
2276
  const modelId = model.modelId;
2252
- await sendEventToPosthog({
2277
+ const enrichedError = await sendEventWithErrorToPosthog({
2253
2278
  client: phClient,
2254
2279
  distinctId: mergedOptions.posthogDistinctId,
2255
2280
  traceId: mergedOptions.posthogTraceId ?? v4(),
@@ -2260,17 +2285,15 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2260
2285
  latency: 0,
2261
2286
  baseURL: '',
2262
2287
  params: mergedParams,
2263
- httpStatus: error?.status ? error.status : 500,
2264
2288
  usage: {
2265
2289
  inputTokens: 0,
2266
2290
  outputTokens: 0
2267
2291
  },
2268
- isError: true,
2269
- error: truncate(JSON.stringify(error)),
2292
+ error: error,
2270
2293
  tools: availableTools,
2271
2294
  captureImmediate: mergedOptions.posthogCaptureImmediate
2272
2295
  });
2273
- throw error;
2296
+ throw enrichedError;
2274
2297
  }
2275
2298
  },
2276
2299
  doStream: async params => {
@@ -2384,6 +2407,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2384
2407
  ...usage,
2385
2408
  webSearchCount
2386
2409
  };
2410
+ adjustAnthropicV3CacheTokens(model, provider, finalUsage);
2387
2411
  await sendEventToPosthog({
2388
2412
  client: phClient,
2389
2413
  distinctId: mergedOptions.posthogDistinctId,
@@ -2407,7 +2431,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2407
2431
  ...rest
2408
2432
  };
2409
2433
  } catch (error) {
2410
- await sendEventToPosthog({
2434
+ const enrichedError = await sendEventWithErrorToPosthog({
2411
2435
  client: phClient,
2412
2436
  distinctId: mergedOptions.posthogDistinctId,
2413
2437
  traceId: mergedOptions.posthogTraceId ?? v4(),
@@ -2418,17 +2442,15 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2418
2442
  latency: 0,
2419
2443
  baseURL: '',
2420
2444
  params: mergedParams,
2421
- httpStatus: error?.status ? error.status : 500,
2422
2445
  usage: {
2423
2446
  inputTokens: 0,
2424
2447
  outputTokens: 0
2425
2448
  },
2426
- isError: true,
2427
- error: truncate(JSON.stringify(error)),
2449
+ error: error,
2428
2450
  tools: availableTools,
2429
2451
  captureImmediate: mergedOptions.posthogCaptureImmediate
2430
2452
  });
2431
- throw error;
2453
+ throw enrichedError;
2432
2454
  }
2433
2455
  }
2434
2456
  };
@@ -2585,8 +2607,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
2585
2607
  tools: availableTools
2586
2608
  });
2587
2609
  } catch (error) {
2588
- // error handling
2589
- await sendEventToPosthog({
2610
+ const enrichedError = await sendEventWithErrorToPosthog({
2590
2611
  client: this.phClient,
2591
2612
  ...posthogParams,
2592
2613
  model: anthropicParams.model,
@@ -2596,14 +2617,13 @@ class WrappedMessages extends AnthropicOriginal.Messages {
2596
2617
  latency: 0,
2597
2618
  baseURL: this.baseURL,
2598
2619
  params: body,
2599
- httpStatus: error?.status ? error.status : 500,
2600
2620
  usage: {
2601
2621
  inputTokens: 0,
2602
2622
  outputTokens: 0
2603
2623
  },
2604
- isError: true,
2605
- error: JSON.stringify(error)
2624
+ error: error
2606
2625
  });
2626
+ throw enrichedError;
2607
2627
  }
2608
2628
  })();
2609
2629
  // Return the other stream to the user
@@ -2654,7 +2674,6 @@ class WrappedMessages extends AnthropicOriginal.Messages {
2654
2674
  inputTokens: 0,
2655
2675
  outputTokens: 0
2656
2676
  },
2657
- isError: true,
2658
2677
  error: JSON.stringify(error)
2659
2678
  });
2660
2679
  throw error;
@@ -2714,7 +2733,7 @@ class WrappedModels {
2714
2733
  return response;
2715
2734
  } catch (error) {
2716
2735
  const latency = (Date.now() - startTime) / 1000;
2717
- await sendEventToPosthog({
2736
+ const enrichedError = await sendEventWithErrorToPosthog({
2718
2737
  client: this.phClient,
2719
2738
  ...posthogParams,
2720
2739
  model: geminiParams.model,
@@ -2724,15 +2743,13 @@ class WrappedModels {
2724
2743
  latency,
2725
2744
  baseURL: 'https://generativelanguage.googleapis.com',
2726
2745
  params: params,
2727
- httpStatus: error?.status ?? 500,
2728
2746
  usage: {
2729
2747
  inputTokens: 0,
2730
2748
  outputTokens: 0
2731
2749
  },
2732
- isError: true,
2733
- error: JSON.stringify(error)
2750
+ error: error
2734
2751
  });
2735
- throw error;
2752
+ throw enrichedError;
2736
2753
  }
2737
2754
  }
2738
2755
  async *generateContentStream(params) {
@@ -2834,7 +2851,7 @@ class WrappedModels {
2834
2851
  });
2835
2852
  } catch (error) {
2836
2853
  const latency = (Date.now() - startTime) / 1000;
2837
- await sendEventToPosthog({
2854
+ const enrichedError = await sendEventWithErrorToPosthog({
2838
2855
  client: this.phClient,
2839
2856
  ...posthogParams,
2840
2857
  model: geminiParams.model,
@@ -2844,15 +2861,13 @@ class WrappedModels {
2844
2861
  latency,
2845
2862
  baseURL: 'https://generativelanguage.googleapis.com',
2846
2863
  params: params,
2847
- httpStatus: error?.status ?? 500,
2848
2864
  usage: {
2849
2865
  inputTokens: 0,
2850
2866
  outputTokens: 0
2851
2867
  },
2852
- isError: true,
2853
- error: JSON.stringify(error)
2868
+ error: error
2854
2869
  });
2855
- throw error;
2870
+ throw enrichedError;
2856
2871
  }
2857
2872
  }
2858
2873
  formatPartsAsContentBlocks(parts) {
@@ -3232,6 +3247,64 @@ function mapKeys(fields, mapper, map) {
3232
3247
  return mapped;
3233
3248
  }
3234
3249
 
3250
+ //#region src/load/validation.ts
3251
+ /**
3252
+ * Sentinel key used to mark escaped user objects during serialization.
3253
+ *
3254
+ * When a plain object contains 'lc' key (which could be confused with LC objects),
3255
+ * we wrap it as `{"__lc_escaped__": {...original...}}`.
3256
+ */
3257
+ const LC_ESCAPED_KEY = "__lc_escaped__";
3258
+ /**
3259
+ * Check if an object needs escaping to prevent confusion with LC objects.
3260
+ *
3261
+ * An object needs escaping if:
3262
+ * 1. It has an `'lc'` key (could be confused with LC serialization format)
3263
+ * 2. It has only the escape key (would be mistaken for an escaped object)
3264
+ */
3265
+ function needsEscaping(obj) {
3266
+ return "lc" in obj || Object.keys(obj).length === 1 && LC_ESCAPED_KEY in obj;
3267
+ }
3268
+ /**
3269
+ * Wrap an object in the escape marker.
3270
+ *
3271
+ * @example
3272
+ * ```typescript
3273
+ * {"key": "value"} // becomes {"__lc_escaped__": {"key": "value"}}
3274
+ * ```
3275
+ */
3276
+ function escapeObject(obj) {
3277
+ return { [LC_ESCAPED_KEY]: obj };
3278
+ }
3279
+ /**
3280
+ * Check if an object looks like a Serializable instance (duck typing).
3281
+ */
3282
+ function isSerializableLike(obj) {
3283
+ return obj !== null && typeof obj === "object" && "lc_serializable" in obj && typeof obj.toJSON === "function";
3284
+ }
3285
+ /**
3286
+ * Escape a value if it needs escaping (contains `lc` key).
3287
+ *
3288
+ * This is a simpler version of `serializeValue` that doesn't handle Serializable
3289
+ * objects - it's meant to be called on kwargs values that have already been
3290
+ * processed by `toJSON()`.
3291
+ *
3292
+ * @param value - The value to potentially escape.
3293
+ * @returns The value with any `lc`-containing objects wrapped in escape markers.
3294
+ */
3295
+ function escapeIfNeeded(value) {
3296
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
3297
+ if (isSerializableLike(value)) return value;
3298
+ const record = value;
3299
+ if (needsEscaping(record)) return escapeObject(record);
3300
+ const result = {};
3301
+ for (const [key, val] of Object.entries(record)) result[key] = escapeIfNeeded(val);
3302
+ return result;
3303
+ }
3304
+ if (Array.isArray(value)) return value.map((item) => escapeIfNeeded(item));
3305
+ return value;
3306
+ }
3307
+
3235
3308
  //#region src/load/serializable.ts
3236
3309
  var serializable_exports = {};
3237
3310
  __export(serializable_exports, {
@@ -3353,11 +3426,15 @@ var Serializable = class Serializable {
3353
3426
  }
3354
3427
  if (last in read && read[last] !== void 0) write[last] = write[last] || read[last];
3355
3428
  });
3429
+ const escapedKwargs = {};
3430
+ for (const [key, value] of Object.entries(kwargs)) escapedKwargs[key] = escapeIfNeeded(value);
3431
+ const kwargsWithSecrets = Object.keys(secrets).length ? replaceSecrets(escapedKwargs, secrets) : escapedKwargs;
3432
+ const processedKwargs = mapKeys(kwargsWithSecrets, keyToJson, aliases);
3356
3433
  return {
3357
3434
  lc: 1,
3358
3435
  type: "constructor",
3359
3436
  id: this.lc_id,
3360
- kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases)
3437
+ kwargs: processedKwargs
3361
3438
  };
3362
3439
  }
3363
3440
  toJSONNotImplemented() {