@fallom/trace 0.2.24 → 0.2.25

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 (3) hide show
  1. package/dist/index.js +193 -56
  2. package/dist/index.mjs +193 -56
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2842,6 +2842,101 @@ function wrapGoogleAI(model, sessionCtx) {
2842
2842
  return model;
2843
2843
  }
2844
2844
 
2845
+ // src/trace/wrappers/vercel-ai/utils.ts
2846
+ function extractProviderInfo(model, aiModule, result) {
2847
+ const info = {};
2848
+ try {
2849
+ if (aiModule) {
2850
+ info.aiSdkVersion = aiModule.version ?? aiModule.VERSION ?? void 0;
2851
+ }
2852
+ if (!model) return info;
2853
+ info.modelId = model.modelId ?? model.id ?? String(model);
2854
+ if (model.provider) {
2855
+ if (typeof model.provider === "string") {
2856
+ info.provider = model.provider;
2857
+ } else if (typeof model.provider === "object") {
2858
+ info.provider = model.provider.id ?? model.provider.name;
2859
+ info.providerId = model.provider.id;
2860
+ }
2861
+ }
2862
+ if (model.providerId) {
2863
+ info.providerId = model.providerId;
2864
+ }
2865
+ const baseUrl4 = model.config?.baseURL ?? model.config?.baseUrl ?? model.settings?.baseURL ?? model.settings?.baseUrl ?? model.baseURL ?? model.baseUrl;
2866
+ if (baseUrl4 && typeof baseUrl4 === "string") {
2867
+ info.baseUrl = baseUrl4;
2868
+ if (!info.provider) {
2869
+ if (baseUrl4.includes("openrouter.ai")) {
2870
+ info.provider = "openrouter";
2871
+ } else if (baseUrl4.includes("api.openai.com")) {
2872
+ info.provider = "openai";
2873
+ } else if (baseUrl4.includes("api.anthropic.com")) {
2874
+ info.provider = "anthropic";
2875
+ } else if (baseUrl4.includes("generativelanguage.googleapis.com")) {
2876
+ info.provider = "google";
2877
+ } else if (baseUrl4.includes("api.mistral.ai")) {
2878
+ info.provider = "mistral";
2879
+ } else if (baseUrl4.includes("api.together.xyz")) {
2880
+ info.provider = "together";
2881
+ } else if (baseUrl4.includes("api.groq.com")) {
2882
+ info.provider = "groq";
2883
+ } else if (baseUrl4.includes("localhost") || baseUrl4.includes("127.0.0.1")) {
2884
+ info.provider = "local";
2885
+ }
2886
+ }
2887
+ }
2888
+ if (!info.provider && info.modelId) {
2889
+ const modelStr = String(info.modelId).toLowerCase();
2890
+ if (modelStr.includes("gpt-") || modelStr.includes("o1-") || modelStr.includes("text-embedding")) {
2891
+ info.provider = info.provider ?? "openai";
2892
+ } else if (modelStr.includes("claude-")) {
2893
+ info.provider = info.provider ?? "anthropic";
2894
+ } else if (modelStr.includes("gemini-") || modelStr.includes("gemma-")) {
2895
+ info.provider = info.provider ?? "google";
2896
+ } else if (modelStr.includes("mistral-") || modelStr.includes("mixtral-")) {
2897
+ info.provider = info.provider ?? "mistral";
2898
+ } else if (modelStr.includes("llama-") || modelStr.includes("meta-llama")) {
2899
+ info.provider = info.provider ?? "meta";
2900
+ } else if (modelStr.includes("/")) {
2901
+ info.provider = info.provider ?? "openrouter";
2902
+ }
2903
+ }
2904
+ if (result?.response) {
2905
+ if (!info.modelId && result.response.modelId) {
2906
+ info.modelId = result.response.modelId;
2907
+ }
2908
+ }
2909
+ info.raw = {};
2910
+ if (model.modelId) info.raw.modelId = model.modelId;
2911
+ if (model.provider) {
2912
+ info.raw.provider = typeof model.provider === "object" ? { id: model.provider.id, name: model.provider.name } : model.provider;
2913
+ }
2914
+ if (model.providerId) info.raw.providerId = model.providerId;
2915
+ if (model.specificationVersion) info.raw.specificationVersion = model.specificationVersion;
2916
+ } catch {
2917
+ }
2918
+ return info;
2919
+ }
2920
+ function providerInfoToAttributes(info) {
2921
+ const attrs = {};
2922
+ if (info.provider) {
2923
+ attrs["fallom.provider"] = info.provider;
2924
+ }
2925
+ if (info.providerId) {
2926
+ attrs["fallom.provider_id"] = info.providerId;
2927
+ }
2928
+ if (info.baseUrl) {
2929
+ attrs["fallom.base_url"] = info.baseUrl;
2930
+ }
2931
+ if (info.aiSdkVersion) {
2932
+ attrs["fallom.ai_sdk_version"] = info.aiSdkVersion;
2933
+ }
2934
+ if (info.raw && Object.keys(info.raw).length > 0) {
2935
+ attrs["fallom.provider_raw"] = JSON.stringify(info.raw);
2936
+ }
2937
+ return attrs;
2938
+ }
2939
+
2845
2940
  // src/trace/wrappers/vercel-ai/generate-text.ts
2846
2941
  function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2847
2942
  const ctx = sessionCtx;
@@ -2865,34 +2960,44 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2865
2960
  )) {
2866
2961
  if (tool && typeof tool.execute === "function") {
2867
2962
  const originalExecute = tool.execute;
2868
- wrappedTools[toolName] = {
2869
- ...tool,
2870
- execute: async (...executeArgs) => {
2871
- const toolStartTime = Date.now();
2872
- const toolCallId = `${toolName}-${toolStartTime}`;
2873
- try {
2874
- const result = await originalExecute(...executeArgs);
2875
- const toolEndTime = Date.now();
2876
- toolTimings.set(toolCallId, {
2877
- name: toolName,
2878
- startTime: toolStartTime - startTime,
2879
- // Relative to request start
2880
- endTime: toolEndTime - startTime,
2881
- duration: toolEndTime - toolStartTime
2882
- });
2883
- return result;
2884
- } catch (error) {
2885
- const toolEndTime = Date.now();
2886
- toolTimings.set(toolCallId, {
2887
- name: toolName,
2888
- startTime: toolStartTime - startTime,
2889
- endTime: toolEndTime - startTime,
2890
- duration: toolEndTime - toolStartTime
2891
- });
2892
- throw error;
2893
- }
2963
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
2964
+ const allKeys = [
2965
+ ...Object.getOwnPropertyNames(tool),
2966
+ ...Object.getOwnPropertySymbols(tool)
2967
+ ];
2968
+ for (const key of allKeys) {
2969
+ if (key === "execute") continue;
2970
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
2971
+ if (descriptor) {
2972
+ Object.defineProperty(wrappedTool, key, descriptor);
2973
+ }
2974
+ }
2975
+ wrappedTool.execute = async (...executeArgs) => {
2976
+ const toolStartTime = Date.now();
2977
+ const toolCallId = `${toolName}-${toolStartTime}`;
2978
+ try {
2979
+ const result = await originalExecute(...executeArgs);
2980
+ const toolEndTime = Date.now();
2981
+ toolTimings.set(toolCallId, {
2982
+ name: toolName,
2983
+ startTime: toolStartTime - startTime,
2984
+ // Relative to request start
2985
+ endTime: toolEndTime - startTime,
2986
+ duration: toolEndTime - toolStartTime
2987
+ });
2988
+ return result;
2989
+ } catch (error) {
2990
+ const toolEndTime = Date.now();
2991
+ toolTimings.set(toolCallId, {
2992
+ name: toolName,
2993
+ startTime: toolStartTime - startTime,
2994
+ endTime: toolEndTime - startTime,
2995
+ duration: toolEndTime - toolStartTime
2996
+ });
2997
+ throw error;
2894
2998
  }
2895
2999
  };
3000
+ wrappedTools[toolName] = wrappedTool;
2896
3001
  } else {
2897
3002
  wrappedTools[toolName] = tool;
2898
3003
  }
@@ -2908,9 +3013,12 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2908
3013
  console.log(" steps:", result?.steps?.length || 0);
2909
3014
  }
2910
3015
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
3016
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
2911
3017
  const attributes = {
2912
3018
  "fallom.sdk_version": "2",
2913
- "fallom.method": "generateText"
3019
+ "fallom.method": "generateText",
3020
+ // Provider info for debugging
3021
+ ...providerInfoToAttributes(providerInfo)
2914
3022
  };
2915
3023
  if (captureContent2) {
2916
3024
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -2924,7 +3032,17 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2924
3032
  const mapToolCall = (tc) => {
2925
3033
  let args2 = tc?.args ?? tc?.input;
2926
3034
  if (args2 === void 0 && tc) {
2927
- const { type, toolCallId, toolName, providerExecuted, dynamic, invalid, error, providerMetadata, ...rest } = tc;
3035
+ const {
3036
+ type,
3037
+ toolCallId,
3038
+ toolName,
3039
+ providerExecuted,
3040
+ dynamic,
3041
+ invalid,
3042
+ error,
3043
+ providerMetadata,
3044
+ ...rest
3045
+ } = tc;
2928
3046
  if (Object.keys(rest).length > 0) {
2929
3047
  args2 = rest;
2930
3048
  }
@@ -3168,33 +3286,43 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
3168
3286
  )) {
3169
3287
  if (tool && typeof tool.execute === "function") {
3170
3288
  const originalExecute = tool.execute;
3171
- wrappedTools[toolName] = {
3172
- ...tool,
3173
- execute: async (...executeArgs) => {
3174
- const toolStartTime = Date.now();
3175
- const toolCallId = `${toolName}-${toolStartTime}`;
3176
- try {
3177
- const result2 = await originalExecute(...executeArgs);
3178
- const toolEndTime = Date.now();
3179
- toolTimings.set(toolCallId, {
3180
- name: toolName,
3181
- startTime: toolStartTime - startTime,
3182
- endTime: toolEndTime - startTime,
3183
- duration: toolEndTime - toolStartTime
3184
- });
3185
- return result2;
3186
- } catch (error) {
3187
- const toolEndTime = Date.now();
3188
- toolTimings.set(toolCallId, {
3189
- name: toolName,
3190
- startTime: toolStartTime - startTime,
3191
- endTime: toolEndTime - startTime,
3192
- duration: toolEndTime - toolStartTime
3193
- });
3194
- throw error;
3195
- }
3289
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
3290
+ const allKeys = [
3291
+ ...Object.getOwnPropertyNames(tool),
3292
+ ...Object.getOwnPropertySymbols(tool)
3293
+ ];
3294
+ for (const key of allKeys) {
3295
+ if (key === "execute") continue;
3296
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
3297
+ if (descriptor) {
3298
+ Object.defineProperty(wrappedTool, key, descriptor);
3299
+ }
3300
+ }
3301
+ wrappedTool.execute = async (...executeArgs) => {
3302
+ const toolStartTime = Date.now();
3303
+ const toolCallId = `${toolName}-${toolStartTime}`;
3304
+ try {
3305
+ const result2 = await originalExecute(...executeArgs);
3306
+ const toolEndTime = Date.now();
3307
+ toolTimings.set(toolCallId, {
3308
+ name: toolName,
3309
+ startTime: toolStartTime - startTime,
3310
+ endTime: toolEndTime - startTime,
3311
+ duration: toolEndTime - toolStartTime
3312
+ });
3313
+ return result2;
3314
+ } catch (error) {
3315
+ const toolEndTime = Date.now();
3316
+ toolTimings.set(toolCallId, {
3317
+ name: toolName,
3318
+ startTime: toolStartTime - startTime,
3319
+ endTime: toolEndTime - startTime,
3320
+ duration: toolEndTime - toolStartTime
3321
+ });
3322
+ throw error;
3196
3323
  }
3197
3324
  };
3325
+ wrappedTools[toolName] = wrappedTool;
3198
3326
  } else {
3199
3327
  wrappedTools[toolName] = tool;
3200
3328
  }
@@ -3305,10 +3433,13 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
3305
3433
  providerMetadata = void 0;
3306
3434
  }
3307
3435
  }
3436
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3308
3437
  const attributes = {
3309
3438
  "fallom.sdk_version": "2",
3310
3439
  "fallom.method": "streamText",
3311
- "fallom.is_streaming": true
3440
+ "fallom.is_streaming": true,
3441
+ // Provider info for debugging
3442
+ ...providerInfoToAttributes(providerInfo)
3312
3443
  };
3313
3444
  if (captureContent2) {
3314
3445
  const mapToolCall = (tc) => {
@@ -3579,9 +3710,12 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
3579
3710
  );
3580
3711
  }
3581
3712
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
3713
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3582
3714
  const attributes = {
3583
3715
  "fallom.sdk_version": "2",
3584
- "fallom.method": "generateObject"
3716
+ "fallom.method": "generateObject",
3717
+ // Provider info for debugging
3718
+ ...providerInfoToAttributes(providerInfo)
3585
3719
  };
3586
3720
  if (captureContent2) {
3587
3721
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -3704,10 +3838,13 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
3704
3838
  providerMetadata = void 0;
3705
3839
  }
3706
3840
  }
3841
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3707
3842
  const attributes = {
3708
3843
  "fallom.sdk_version": "2",
3709
3844
  "fallom.method": "streamObject",
3710
- "fallom.is_streaming": true
3845
+ "fallom.is_streaming": true,
3846
+ // Provider info for debugging
3847
+ ...providerInfoToAttributes(providerInfo)
3711
3848
  };
3712
3849
  if (captureContent2) {
3713
3850
  attributes["fallom.raw.request"] = JSON.stringify({
package/dist/index.mjs CHANGED
@@ -1492,6 +1492,101 @@ function wrapGoogleAI(model, sessionCtx) {
1492
1492
  return model;
1493
1493
  }
1494
1494
 
1495
+ // src/trace/wrappers/vercel-ai/utils.ts
1496
+ function extractProviderInfo(model, aiModule, result) {
1497
+ const info = {};
1498
+ try {
1499
+ if (aiModule) {
1500
+ info.aiSdkVersion = aiModule.version ?? aiModule.VERSION ?? void 0;
1501
+ }
1502
+ if (!model) return info;
1503
+ info.modelId = model.modelId ?? model.id ?? String(model);
1504
+ if (model.provider) {
1505
+ if (typeof model.provider === "string") {
1506
+ info.provider = model.provider;
1507
+ } else if (typeof model.provider === "object") {
1508
+ info.provider = model.provider.id ?? model.provider.name;
1509
+ info.providerId = model.provider.id;
1510
+ }
1511
+ }
1512
+ if (model.providerId) {
1513
+ info.providerId = model.providerId;
1514
+ }
1515
+ const baseUrl3 = model.config?.baseURL ?? model.config?.baseUrl ?? model.settings?.baseURL ?? model.settings?.baseUrl ?? model.baseURL ?? model.baseUrl;
1516
+ if (baseUrl3 && typeof baseUrl3 === "string") {
1517
+ info.baseUrl = baseUrl3;
1518
+ if (!info.provider) {
1519
+ if (baseUrl3.includes("openrouter.ai")) {
1520
+ info.provider = "openrouter";
1521
+ } else if (baseUrl3.includes("api.openai.com")) {
1522
+ info.provider = "openai";
1523
+ } else if (baseUrl3.includes("api.anthropic.com")) {
1524
+ info.provider = "anthropic";
1525
+ } else if (baseUrl3.includes("generativelanguage.googleapis.com")) {
1526
+ info.provider = "google";
1527
+ } else if (baseUrl3.includes("api.mistral.ai")) {
1528
+ info.provider = "mistral";
1529
+ } else if (baseUrl3.includes("api.together.xyz")) {
1530
+ info.provider = "together";
1531
+ } else if (baseUrl3.includes("api.groq.com")) {
1532
+ info.provider = "groq";
1533
+ } else if (baseUrl3.includes("localhost") || baseUrl3.includes("127.0.0.1")) {
1534
+ info.provider = "local";
1535
+ }
1536
+ }
1537
+ }
1538
+ if (!info.provider && info.modelId) {
1539
+ const modelStr = String(info.modelId).toLowerCase();
1540
+ if (modelStr.includes("gpt-") || modelStr.includes("o1-") || modelStr.includes("text-embedding")) {
1541
+ info.provider = info.provider ?? "openai";
1542
+ } else if (modelStr.includes("claude-")) {
1543
+ info.provider = info.provider ?? "anthropic";
1544
+ } else if (modelStr.includes("gemini-") || modelStr.includes("gemma-")) {
1545
+ info.provider = info.provider ?? "google";
1546
+ } else if (modelStr.includes("mistral-") || modelStr.includes("mixtral-")) {
1547
+ info.provider = info.provider ?? "mistral";
1548
+ } else if (modelStr.includes("llama-") || modelStr.includes("meta-llama")) {
1549
+ info.provider = info.provider ?? "meta";
1550
+ } else if (modelStr.includes("/")) {
1551
+ info.provider = info.provider ?? "openrouter";
1552
+ }
1553
+ }
1554
+ if (result?.response) {
1555
+ if (!info.modelId && result.response.modelId) {
1556
+ info.modelId = result.response.modelId;
1557
+ }
1558
+ }
1559
+ info.raw = {};
1560
+ if (model.modelId) info.raw.modelId = model.modelId;
1561
+ if (model.provider) {
1562
+ info.raw.provider = typeof model.provider === "object" ? { id: model.provider.id, name: model.provider.name } : model.provider;
1563
+ }
1564
+ if (model.providerId) info.raw.providerId = model.providerId;
1565
+ if (model.specificationVersion) info.raw.specificationVersion = model.specificationVersion;
1566
+ } catch {
1567
+ }
1568
+ return info;
1569
+ }
1570
+ function providerInfoToAttributes(info) {
1571
+ const attrs = {};
1572
+ if (info.provider) {
1573
+ attrs["fallom.provider"] = info.provider;
1574
+ }
1575
+ if (info.providerId) {
1576
+ attrs["fallom.provider_id"] = info.providerId;
1577
+ }
1578
+ if (info.baseUrl) {
1579
+ attrs["fallom.base_url"] = info.baseUrl;
1580
+ }
1581
+ if (info.aiSdkVersion) {
1582
+ attrs["fallom.ai_sdk_version"] = info.aiSdkVersion;
1583
+ }
1584
+ if (info.raw && Object.keys(info.raw).length > 0) {
1585
+ attrs["fallom.provider_raw"] = JSON.stringify(info.raw);
1586
+ }
1587
+ return attrs;
1588
+ }
1589
+
1495
1590
  // src/trace/wrappers/vercel-ai/generate-text.ts
1496
1591
  function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
1497
1592
  const ctx = sessionCtx;
@@ -1515,34 +1610,44 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
1515
1610
  )) {
1516
1611
  if (tool && typeof tool.execute === "function") {
1517
1612
  const originalExecute = tool.execute;
1518
- wrappedTools[toolName] = {
1519
- ...tool,
1520
- execute: async (...executeArgs) => {
1521
- const toolStartTime = Date.now();
1522
- const toolCallId = `${toolName}-${toolStartTime}`;
1523
- try {
1524
- const result = await originalExecute(...executeArgs);
1525
- const toolEndTime = Date.now();
1526
- toolTimings.set(toolCallId, {
1527
- name: toolName,
1528
- startTime: toolStartTime - startTime,
1529
- // Relative to request start
1530
- endTime: toolEndTime - startTime,
1531
- duration: toolEndTime - toolStartTime
1532
- });
1533
- return result;
1534
- } catch (error) {
1535
- const toolEndTime = Date.now();
1536
- toolTimings.set(toolCallId, {
1537
- name: toolName,
1538
- startTime: toolStartTime - startTime,
1539
- endTime: toolEndTime - startTime,
1540
- duration: toolEndTime - toolStartTime
1541
- });
1542
- throw error;
1543
- }
1613
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
1614
+ const allKeys = [
1615
+ ...Object.getOwnPropertyNames(tool),
1616
+ ...Object.getOwnPropertySymbols(tool)
1617
+ ];
1618
+ for (const key of allKeys) {
1619
+ if (key === "execute") continue;
1620
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
1621
+ if (descriptor) {
1622
+ Object.defineProperty(wrappedTool, key, descriptor);
1623
+ }
1624
+ }
1625
+ wrappedTool.execute = async (...executeArgs) => {
1626
+ const toolStartTime = Date.now();
1627
+ const toolCallId = `${toolName}-${toolStartTime}`;
1628
+ try {
1629
+ const result = await originalExecute(...executeArgs);
1630
+ const toolEndTime = Date.now();
1631
+ toolTimings.set(toolCallId, {
1632
+ name: toolName,
1633
+ startTime: toolStartTime - startTime,
1634
+ // Relative to request start
1635
+ endTime: toolEndTime - startTime,
1636
+ duration: toolEndTime - toolStartTime
1637
+ });
1638
+ return result;
1639
+ } catch (error) {
1640
+ const toolEndTime = Date.now();
1641
+ toolTimings.set(toolCallId, {
1642
+ name: toolName,
1643
+ startTime: toolStartTime - startTime,
1644
+ endTime: toolEndTime - startTime,
1645
+ duration: toolEndTime - toolStartTime
1646
+ });
1647
+ throw error;
1544
1648
  }
1545
1649
  };
1650
+ wrappedTools[toolName] = wrappedTool;
1546
1651
  } else {
1547
1652
  wrappedTools[toolName] = tool;
1548
1653
  }
@@ -1558,9 +1663,12 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
1558
1663
  console.log(" steps:", result?.steps?.length || 0);
1559
1664
  }
1560
1665
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
1666
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
1561
1667
  const attributes = {
1562
1668
  "fallom.sdk_version": "2",
1563
- "fallom.method": "generateText"
1669
+ "fallom.method": "generateText",
1670
+ // Provider info for debugging
1671
+ ...providerInfoToAttributes(providerInfo)
1564
1672
  };
1565
1673
  if (captureContent2) {
1566
1674
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -1574,7 +1682,17 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
1574
1682
  const mapToolCall = (tc) => {
1575
1683
  let args2 = tc?.args ?? tc?.input;
1576
1684
  if (args2 === void 0 && tc) {
1577
- const { type, toolCallId, toolName, providerExecuted, dynamic, invalid, error, providerMetadata, ...rest } = tc;
1685
+ const {
1686
+ type,
1687
+ toolCallId,
1688
+ toolName,
1689
+ providerExecuted,
1690
+ dynamic,
1691
+ invalid,
1692
+ error,
1693
+ providerMetadata,
1694
+ ...rest
1695
+ } = tc;
1578
1696
  if (Object.keys(rest).length > 0) {
1579
1697
  args2 = rest;
1580
1698
  }
@@ -1818,33 +1936,43 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
1818
1936
  )) {
1819
1937
  if (tool && typeof tool.execute === "function") {
1820
1938
  const originalExecute = tool.execute;
1821
- wrappedTools[toolName] = {
1822
- ...tool,
1823
- execute: async (...executeArgs) => {
1824
- const toolStartTime = Date.now();
1825
- const toolCallId = `${toolName}-${toolStartTime}`;
1826
- try {
1827
- const result2 = await originalExecute(...executeArgs);
1828
- const toolEndTime = Date.now();
1829
- toolTimings.set(toolCallId, {
1830
- name: toolName,
1831
- startTime: toolStartTime - startTime,
1832
- endTime: toolEndTime - startTime,
1833
- duration: toolEndTime - toolStartTime
1834
- });
1835
- return result2;
1836
- } catch (error) {
1837
- const toolEndTime = Date.now();
1838
- toolTimings.set(toolCallId, {
1839
- name: toolName,
1840
- startTime: toolStartTime - startTime,
1841
- endTime: toolEndTime - startTime,
1842
- duration: toolEndTime - toolStartTime
1843
- });
1844
- throw error;
1845
- }
1939
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
1940
+ const allKeys = [
1941
+ ...Object.getOwnPropertyNames(tool),
1942
+ ...Object.getOwnPropertySymbols(tool)
1943
+ ];
1944
+ for (const key of allKeys) {
1945
+ if (key === "execute") continue;
1946
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
1947
+ if (descriptor) {
1948
+ Object.defineProperty(wrappedTool, key, descriptor);
1949
+ }
1950
+ }
1951
+ wrappedTool.execute = async (...executeArgs) => {
1952
+ const toolStartTime = Date.now();
1953
+ const toolCallId = `${toolName}-${toolStartTime}`;
1954
+ try {
1955
+ const result2 = await originalExecute(...executeArgs);
1956
+ const toolEndTime = Date.now();
1957
+ toolTimings.set(toolCallId, {
1958
+ name: toolName,
1959
+ startTime: toolStartTime - startTime,
1960
+ endTime: toolEndTime - startTime,
1961
+ duration: toolEndTime - toolStartTime
1962
+ });
1963
+ return result2;
1964
+ } catch (error) {
1965
+ const toolEndTime = Date.now();
1966
+ toolTimings.set(toolCallId, {
1967
+ name: toolName,
1968
+ startTime: toolStartTime - startTime,
1969
+ endTime: toolEndTime - startTime,
1970
+ duration: toolEndTime - toolStartTime
1971
+ });
1972
+ throw error;
1846
1973
  }
1847
1974
  };
1975
+ wrappedTools[toolName] = wrappedTool;
1848
1976
  } else {
1849
1977
  wrappedTools[toolName] = tool;
1850
1978
  }
@@ -1955,10 +2083,13 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
1955
2083
  providerMetadata = void 0;
1956
2084
  }
1957
2085
  }
2086
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
1958
2087
  const attributes = {
1959
2088
  "fallom.sdk_version": "2",
1960
2089
  "fallom.method": "streamText",
1961
- "fallom.is_streaming": true
2090
+ "fallom.is_streaming": true,
2091
+ // Provider info for debugging
2092
+ ...providerInfoToAttributes(providerInfo)
1962
2093
  };
1963
2094
  if (captureContent2) {
1964
2095
  const mapToolCall = (tc) => {
@@ -2229,9 +2360,12 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
2229
2360
  );
2230
2361
  }
2231
2362
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
2363
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
2232
2364
  const attributes = {
2233
2365
  "fallom.sdk_version": "2",
2234
- "fallom.method": "generateObject"
2366
+ "fallom.method": "generateObject",
2367
+ // Provider info for debugging
2368
+ ...providerInfoToAttributes(providerInfo)
2235
2369
  };
2236
2370
  if (captureContent2) {
2237
2371
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -2354,10 +2488,13 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
2354
2488
  providerMetadata = void 0;
2355
2489
  }
2356
2490
  }
2491
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
2357
2492
  const attributes = {
2358
2493
  "fallom.sdk_version": "2",
2359
2494
  "fallom.method": "streamObject",
2360
- "fallom.is_streaming": true
2495
+ "fallom.is_streaming": true,
2496
+ // Provider info for debugging
2497
+ ...providerInfoToAttributes(providerInfo)
2361
2498
  };
2362
2499
  if (captureContent2) {
2363
2500
  attributes["fallom.raw.request"] = JSON.stringify({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fallom/trace",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
4
4
  "description": "Model A/B testing and tracing for LLM applications. Zero latency, production-ready.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",