@fallom/trace 0.2.24 → 0.2.26

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
@@ -23,7 +23,7 @@ import {
23
23
  isCustomMetric,
24
24
  runGEval,
25
25
  uploadResultsPublic
26
- } from "./chunk-3VWF2OJX.mjs";
26
+ } from "./chunk-FTZVXPQN.mjs";
27
27
  import {
28
28
  __export
29
29
  } from "./chunk-7P6ASYW6.mjs";
@@ -45,7 +45,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
45
45
  // node_modules/@opentelemetry/resources/build/esm/Resource.js
46
46
  import { diag } from "@opentelemetry/api";
47
47
 
48
- // node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions/build/esm/resource/SemanticResourceAttributes.js
48
+ // node_modules/@opentelemetry/semantic-conventions/build/esm/resource/SemanticResourceAttributes.js
49
49
  var SemanticResourceAttributes = {
50
50
  /**
51
51
  * Name of the cloud provider.
@@ -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.26",
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",