@fallom/trace 0.1.6 → 0.1.10

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.js CHANGED
@@ -36,7 +36,7 @@ function log(msg) {
36
36
  }
37
37
  function init(options = {}) {
38
38
  apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
39
- baseUrl = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
39
+ baseUrl = options.baseUrl || process.env.FALLOM_PROMPTS_URL || process.env.FALLOM_BASE_URL || "https://prompts.fallom.com";
40
40
  initialized = true;
41
41
  if (!apiKey) {
42
42
  return;
@@ -187,6 +187,13 @@ async function getAB(abTestKey, sessionId, options = {}) {
187
187
  throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
188
188
  }
189
189
  const { variants } = versionData;
190
+ log(`A/B test '${abTestKey}' has ${variants?.length ?? 0} variants`);
191
+ log(`Version data: ${JSON.stringify(versionData, null, 2)}`);
192
+ if (!variants || variants.length === 0) {
193
+ throw new Error(
194
+ `Prompt A/B test '${abTestKey}' has no variants configured.`
195
+ );
196
+ }
190
197
  const hashBytes = (0, import_crypto.createHash)("md5").update(sessionId).digest();
191
198
  const hashVal = hashBytes.readUInt32BE(0) % 1e6;
192
199
  let cumulative = 0;
@@ -248,7 +255,7 @@ var init_prompts = __esm({
248
255
  "use strict";
249
256
  import_crypto = require("crypto");
250
257
  apiKey = null;
251
- baseUrl = "https://spans.fallom.com";
258
+ baseUrl = "https://prompts.fallom.com";
252
259
  initialized = false;
253
260
  syncInterval = null;
254
261
  debugMode = false;
@@ -280,6 +287,7 @@ __export(trace_exports, {
280
287
  setSession: () => setSession,
281
288
  shutdown: () => shutdown,
282
289
  span: () => span,
290
+ wrapAISDK: () => wrapAISDK,
283
291
  wrapAnthropic: () => wrapAnthropic,
284
292
  wrapGoogleAI: () => wrapGoogleAI,
285
293
  wrapOpenAI: () => wrapOpenAI
@@ -915,7 +923,7 @@ var Resource = (
915
923
  var sessionStorage = new import_async_hooks.AsyncLocalStorage();
916
924
  var fallbackSession = null;
917
925
  var apiKey2 = null;
918
- var baseUrl2 = "https://spans.fallom.com";
926
+ var baseUrl2 = "https://traces.fallom.com";
919
927
  var initialized2 = false;
920
928
  var captureContent = true;
921
929
  var debugMode2 = false;
@@ -958,7 +966,7 @@ async function init2(options = {}) {
958
966
  debugMode2 = options.debug ?? false;
959
967
  log2("\u{1F680} Initializing Fallom tracing...");
960
968
  apiKey2 = options.apiKey || process.env.FALLOM_API_KEY || null;
961
- baseUrl2 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
969
+ baseUrl2 = options.baseUrl || process.env.FALLOM_TRACES_URL || process.env.FALLOM_BASE_URL || "https://traces.fallom.com";
962
970
  const envCapture = process.env.FALLOM_CAPTURE_CONTENT?.toLowerCase();
963
971
  if (envCapture === "false" || envCapture === "0" || envCapture === "no") {
964
972
  captureContent = false;
@@ -1130,12 +1138,12 @@ function messagesToOtelAttributes(messages, completion, model, responseId) {
1130
1138
  if (messages) {
1131
1139
  messages.forEach((msg, i) => {
1132
1140
  attrs[`gen_ai.prompt.${i}.role`] = msg.role;
1133
- attrs[`gen_ai.prompt.${i}.content`] = msg.content;
1141
+ attrs[`gen_ai.prompt.${i}.content`] = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
1134
1142
  });
1135
1143
  }
1136
1144
  if (completion) {
1137
1145
  attrs["gen_ai.completion.0.role"] = completion.role;
1138
- attrs["gen_ai.completion.0.content"] = completion.content;
1146
+ attrs["gen_ai.completion.0.content"] = typeof completion.content === "string" ? completion.content : JSON.stringify(completion.content);
1139
1147
  if (completion.tool_calls) {
1140
1148
  attrs["gen_ai.completion.0.tool_calls"] = JSON.stringify(
1141
1149
  completion.tool_calls
@@ -1152,10 +1160,13 @@ function generateHexId(length) {
1152
1160
  var traceContextStorage = new import_async_hooks.AsyncLocalStorage();
1153
1161
  var fallbackTraceContext = null;
1154
1162
  async function sendTrace(trace) {
1163
+ const url = `${baseUrl2}/v1/traces`;
1164
+ log2("\u{1F4E4} Sending trace to:", url);
1165
+ log2(" Session:", trace.session_id, "Config:", trace.config_key);
1155
1166
  try {
1156
1167
  const controller = new AbortController();
1157
1168
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
1158
- await fetch(`${baseUrl2}/v1/traces`, {
1169
+ const response = await fetch(url, {
1159
1170
  method: "POST",
1160
1171
  headers: {
1161
1172
  Authorization: `Bearer ${apiKey2}`,
@@ -1165,8 +1176,14 @@ async function sendTrace(trace) {
1165
1176
  signal: controller.signal
1166
1177
  });
1167
1178
  clearTimeout(timeoutId);
1168
- log2("\u{1F4E4} Trace sent:", trace.name, trace.model);
1169
- } catch {
1179
+ if (!response.ok) {
1180
+ const text = await response.text();
1181
+ log2("\u274C Trace send failed:", response.status, text);
1182
+ } else {
1183
+ log2("\u2705 Trace sent:", trace.name, trace.model);
1184
+ }
1185
+ } catch (err) {
1186
+ log2("\u274C Trace send error:", err instanceof Error ? err.message : err);
1170
1187
  }
1171
1188
  }
1172
1189
  function wrapOpenAI(client) {
@@ -1468,6 +1485,414 @@ function wrapGoogleAI(model) {
1468
1485
  };
1469
1486
  return model;
1470
1487
  }
1488
+ function wrapAISDK(ai) {
1489
+ const aiModule = ai;
1490
+ return {
1491
+ generateText: createGenerateTextWrapper(aiModule),
1492
+ streamText: createStreamTextWrapper(aiModule),
1493
+ generateObject: aiModule.generateObject ? createGenerateObjectWrapper(aiModule) : void 0,
1494
+ streamObject: aiModule.streamObject ? createStreamObjectWrapper(aiModule) : void 0
1495
+ };
1496
+ }
1497
+ function createGenerateTextWrapper(aiModule) {
1498
+ return async (...args) => {
1499
+ const ctx = sessionStorage.getStore() || fallbackSession;
1500
+ if (!ctx || !initialized2) {
1501
+ return aiModule.generateText(...args);
1502
+ }
1503
+ let promptCtx = null;
1504
+ try {
1505
+ const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
1506
+ promptCtx = getPromptContext2();
1507
+ } catch {
1508
+ }
1509
+ const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
1510
+ const traceId = traceCtx?.traceId || generateHexId(32);
1511
+ const spanId = generateHexId(16);
1512
+ const parentSpanId = traceCtx?.parentSpanId;
1513
+ const params = args[0] || {};
1514
+ const startTime = Date.now();
1515
+ try {
1516
+ const result = await aiModule.generateText(...args);
1517
+ const endTime = Date.now();
1518
+ const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
1519
+ const attributes = {};
1520
+ if (captureContent) {
1521
+ attributes["gen_ai.request.model"] = modelId;
1522
+ attributes["gen_ai.response.model"] = modelId;
1523
+ if (params?.prompt) {
1524
+ attributes["gen_ai.prompt.0.role"] = "user";
1525
+ attributes["gen_ai.prompt.0.content"] = params.prompt;
1526
+ }
1527
+ if (params?.messages) {
1528
+ params.messages.forEach((msg, i) => {
1529
+ attributes[`gen_ai.prompt.${i}.role`] = msg.role;
1530
+ attributes[`gen_ai.prompt.${i}.content`] = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
1531
+ });
1532
+ }
1533
+ if (result?.text) {
1534
+ attributes["gen_ai.completion.0.role"] = "assistant";
1535
+ attributes["gen_ai.completion.0.content"] = result.text;
1536
+ }
1537
+ if (result?.response?.id) {
1538
+ attributes["gen_ai.response.id"] = result.response.id;
1539
+ }
1540
+ }
1541
+ sendTrace({
1542
+ config_key: ctx.configKey,
1543
+ session_id: ctx.sessionId,
1544
+ customer_id: ctx.customerId,
1545
+ trace_id: traceId,
1546
+ span_id: spanId,
1547
+ parent_span_id: parentSpanId,
1548
+ name: "generateText",
1549
+ kind: "llm",
1550
+ model: modelId,
1551
+ start_time: new Date(startTime).toISOString(),
1552
+ end_time: new Date(endTime).toISOString(),
1553
+ duration_ms: endTime - startTime,
1554
+ status: "OK",
1555
+ prompt_tokens: result?.usage?.promptTokens,
1556
+ completion_tokens: result?.usage?.completionTokens,
1557
+ total_tokens: result?.usage?.totalTokens,
1558
+ attributes: captureContent ? attributes : void 0,
1559
+ prompt_key: promptCtx?.promptKey,
1560
+ prompt_version: promptCtx?.promptVersion,
1561
+ prompt_ab_test_key: promptCtx?.abTestKey,
1562
+ prompt_variant_index: promptCtx?.variantIndex
1563
+ }).catch(() => {
1564
+ });
1565
+ return result;
1566
+ } catch (error) {
1567
+ const endTime = Date.now();
1568
+ const modelId = params?.model?.modelId || String(params?.model || "unknown");
1569
+ sendTrace({
1570
+ config_key: ctx.configKey,
1571
+ session_id: ctx.sessionId,
1572
+ customer_id: ctx.customerId,
1573
+ trace_id: traceId,
1574
+ span_id: spanId,
1575
+ parent_span_id: parentSpanId,
1576
+ name: "generateText",
1577
+ kind: "llm",
1578
+ model: modelId,
1579
+ start_time: new Date(startTime).toISOString(),
1580
+ end_time: new Date(endTime).toISOString(),
1581
+ duration_ms: endTime - startTime,
1582
+ status: "ERROR",
1583
+ error_message: error?.message,
1584
+ prompt_key: promptCtx?.promptKey,
1585
+ prompt_version: promptCtx?.promptVersion,
1586
+ prompt_ab_test_key: promptCtx?.abTestKey,
1587
+ prompt_variant_index: promptCtx?.variantIndex
1588
+ }).catch(() => {
1589
+ });
1590
+ throw error;
1591
+ }
1592
+ };
1593
+ }
1594
+ function createStreamTextWrapper(aiModule) {
1595
+ return async (...args) => {
1596
+ const ctx = sessionStorage.getStore() || fallbackSession;
1597
+ const params = args[0] || {};
1598
+ const startTime = Date.now();
1599
+ const result = await aiModule.streamText(...args);
1600
+ if (!ctx || !initialized2) {
1601
+ return result;
1602
+ }
1603
+ const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
1604
+ const traceId = traceCtx?.traceId || generateHexId(32);
1605
+ const spanId = generateHexId(16);
1606
+ const parentSpanId = traceCtx?.parentSpanId;
1607
+ let firstTokenTime = null;
1608
+ const modelId = params?.model?.modelId || String(params?.model || "unknown");
1609
+ let promptCtx = null;
1610
+ try {
1611
+ const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
1612
+ promptCtx = getPromptContext2();
1613
+ } catch {
1614
+ }
1615
+ if (result?.usage) {
1616
+ result.usage.then((usage) => {
1617
+ const endTime = Date.now();
1618
+ log2("\u{1F4CA} streamText usage:", JSON.stringify(usage, null, 2));
1619
+ const attributes = {};
1620
+ if (captureContent) {
1621
+ attributes["gen_ai.request.model"] = modelId;
1622
+ if (params?.prompt) {
1623
+ attributes["gen_ai.prompt.0.role"] = "user";
1624
+ attributes["gen_ai.prompt.0.content"] = params.prompt;
1625
+ }
1626
+ }
1627
+ if (firstTokenTime) {
1628
+ attributes["gen_ai.time_to_first_token_ms"] = firstTokenTime - startTime;
1629
+ }
1630
+ const tracePayload = {
1631
+ config_key: ctx.configKey,
1632
+ session_id: ctx.sessionId,
1633
+ customer_id: ctx.customerId,
1634
+ trace_id: traceId,
1635
+ span_id: spanId,
1636
+ parent_span_id: parentSpanId,
1637
+ name: "streamText",
1638
+ kind: "llm",
1639
+ model: modelId,
1640
+ start_time: new Date(startTime).toISOString(),
1641
+ end_time: new Date(endTime).toISOString(),
1642
+ duration_ms: endTime - startTime,
1643
+ status: "OK",
1644
+ prompt_tokens: usage?.promptTokens,
1645
+ completion_tokens: usage?.completionTokens,
1646
+ total_tokens: usage?.totalTokens,
1647
+ time_to_first_token_ms: firstTokenTime ? firstTokenTime - startTime : void 0,
1648
+ attributes: captureContent ? attributes : void 0,
1649
+ prompt_key: promptCtx?.promptKey,
1650
+ prompt_version: promptCtx?.promptVersion,
1651
+ prompt_ab_test_key: promptCtx?.abTestKey,
1652
+ prompt_variant_index: promptCtx?.variantIndex
1653
+ };
1654
+ sendTrace(tracePayload).catch(() => {
1655
+ });
1656
+ }).catch((error) => {
1657
+ const endTime = Date.now();
1658
+ log2("\u274C streamText error:", error?.message);
1659
+ sendTrace({
1660
+ config_key: ctx.configKey,
1661
+ session_id: ctx.sessionId,
1662
+ customer_id: ctx.customerId,
1663
+ trace_id: traceId,
1664
+ span_id: spanId,
1665
+ parent_span_id: parentSpanId,
1666
+ name: "streamText",
1667
+ kind: "llm",
1668
+ model: modelId,
1669
+ start_time: new Date(startTime).toISOString(),
1670
+ end_time: new Date(endTime).toISOString(),
1671
+ duration_ms: endTime - startTime,
1672
+ status: "ERROR",
1673
+ error_message: error?.message,
1674
+ prompt_key: promptCtx?.promptKey,
1675
+ prompt_version: promptCtx?.promptVersion,
1676
+ prompt_ab_test_key: promptCtx?.abTestKey,
1677
+ prompt_variant_index: promptCtx?.variantIndex
1678
+ }).catch(() => {
1679
+ });
1680
+ });
1681
+ }
1682
+ if (result?.textStream) {
1683
+ const originalTextStream = result.textStream;
1684
+ const wrappedTextStream = (async function* () {
1685
+ for await (const chunk of originalTextStream) {
1686
+ if (!firstTokenTime) {
1687
+ firstTokenTime = Date.now();
1688
+ log2("\u23F1\uFE0F Time to first token:", firstTokenTime - startTime, "ms");
1689
+ }
1690
+ yield chunk;
1691
+ }
1692
+ })();
1693
+ return new Proxy(result, {
1694
+ get(target, prop) {
1695
+ if (prop === "textStream") {
1696
+ return wrappedTextStream;
1697
+ }
1698
+ return target[prop];
1699
+ }
1700
+ });
1701
+ }
1702
+ return result;
1703
+ };
1704
+ }
1705
+ function createGenerateObjectWrapper(aiModule) {
1706
+ return async (...args) => {
1707
+ const ctx = sessionStorage.getStore() || fallbackSession;
1708
+ if (!ctx || !initialized2) {
1709
+ return aiModule.generateObject(...args);
1710
+ }
1711
+ let promptCtx = null;
1712
+ try {
1713
+ const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
1714
+ promptCtx = getPromptContext2();
1715
+ } catch {
1716
+ }
1717
+ const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
1718
+ const traceId = traceCtx?.traceId || generateHexId(32);
1719
+ const spanId = generateHexId(16);
1720
+ const parentSpanId = traceCtx?.parentSpanId;
1721
+ const params = args[0] || {};
1722
+ const startTime = Date.now();
1723
+ try {
1724
+ const result = await aiModule.generateObject(...args);
1725
+ const endTime = Date.now();
1726
+ const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
1727
+ const attributes = {};
1728
+ if (captureContent) {
1729
+ attributes["gen_ai.request.model"] = modelId;
1730
+ attributes["gen_ai.response.model"] = modelId;
1731
+ if (result?.object) {
1732
+ attributes["gen_ai.completion.0.role"] = "assistant";
1733
+ attributes["gen_ai.completion.0.content"] = JSON.stringify(
1734
+ result.object
1735
+ );
1736
+ }
1737
+ }
1738
+ sendTrace({
1739
+ config_key: ctx.configKey,
1740
+ session_id: ctx.sessionId,
1741
+ customer_id: ctx.customerId,
1742
+ trace_id: traceId,
1743
+ span_id: spanId,
1744
+ parent_span_id: parentSpanId,
1745
+ name: "generateObject",
1746
+ kind: "llm",
1747
+ model: modelId,
1748
+ start_time: new Date(startTime).toISOString(),
1749
+ end_time: new Date(endTime).toISOString(),
1750
+ duration_ms: endTime - startTime,
1751
+ status: "OK",
1752
+ prompt_tokens: result?.usage?.promptTokens,
1753
+ completion_tokens: result?.usage?.completionTokens,
1754
+ total_tokens: result?.usage?.totalTokens,
1755
+ attributes: captureContent ? attributes : void 0,
1756
+ prompt_key: promptCtx?.promptKey,
1757
+ prompt_version: promptCtx?.promptVersion,
1758
+ prompt_ab_test_key: promptCtx?.abTestKey,
1759
+ prompt_variant_index: promptCtx?.variantIndex
1760
+ }).catch(() => {
1761
+ });
1762
+ return result;
1763
+ } catch (error) {
1764
+ const endTime = Date.now();
1765
+ const modelId = params?.model?.modelId || String(params?.model || "unknown");
1766
+ sendTrace({
1767
+ config_key: ctx.configKey,
1768
+ session_id: ctx.sessionId,
1769
+ customer_id: ctx.customerId,
1770
+ trace_id: traceId,
1771
+ span_id: spanId,
1772
+ parent_span_id: parentSpanId,
1773
+ name: "generateObject",
1774
+ kind: "llm",
1775
+ model: modelId,
1776
+ start_time: new Date(startTime).toISOString(),
1777
+ end_time: new Date(endTime).toISOString(),
1778
+ duration_ms: endTime - startTime,
1779
+ status: "ERROR",
1780
+ error_message: error?.message,
1781
+ prompt_key: promptCtx?.promptKey,
1782
+ prompt_version: promptCtx?.promptVersion,
1783
+ prompt_ab_test_key: promptCtx?.abTestKey,
1784
+ prompt_variant_index: promptCtx?.variantIndex
1785
+ }).catch(() => {
1786
+ });
1787
+ throw error;
1788
+ }
1789
+ };
1790
+ }
1791
+ function createStreamObjectWrapper(aiModule) {
1792
+ return async (...args) => {
1793
+ const ctx = sessionStorage.getStore() || fallbackSession;
1794
+ const params = args[0] || {};
1795
+ const startTime = Date.now();
1796
+ const result = await aiModule.streamObject(...args);
1797
+ log2("\u{1F50D} streamObject result keys:", Object.keys(result || {}));
1798
+ if (!ctx || !initialized2) {
1799
+ return result;
1800
+ }
1801
+ const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
1802
+ const traceId = traceCtx?.traceId || generateHexId(32);
1803
+ const spanId = generateHexId(16);
1804
+ const parentSpanId = traceCtx?.parentSpanId;
1805
+ let firstTokenTime = null;
1806
+ const modelId = params?.model?.modelId || String(params?.model || "unknown");
1807
+ let promptCtx = null;
1808
+ try {
1809
+ const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
1810
+ promptCtx = getPromptContext2();
1811
+ } catch {
1812
+ }
1813
+ if (result?.usage) {
1814
+ result.usage.then((usage) => {
1815
+ const endTime = Date.now();
1816
+ log2("\u{1F4CA} streamObject usage:", JSON.stringify(usage, null, 2));
1817
+ const attributes = {};
1818
+ if (captureContent) {
1819
+ attributes["gen_ai.request.model"] = modelId;
1820
+ }
1821
+ if (firstTokenTime) {
1822
+ attributes["gen_ai.time_to_first_token_ms"] = firstTokenTime - startTime;
1823
+ }
1824
+ sendTrace({
1825
+ config_key: ctx.configKey,
1826
+ session_id: ctx.sessionId,
1827
+ customer_id: ctx.customerId,
1828
+ trace_id: traceId,
1829
+ span_id: spanId,
1830
+ parent_span_id: parentSpanId,
1831
+ name: "streamObject",
1832
+ kind: "llm",
1833
+ model: modelId,
1834
+ start_time: new Date(startTime).toISOString(),
1835
+ end_time: new Date(endTime).toISOString(),
1836
+ duration_ms: endTime - startTime,
1837
+ status: "OK",
1838
+ prompt_tokens: usage?.promptTokens,
1839
+ completion_tokens: usage?.completionTokens,
1840
+ total_tokens: usage?.totalTokens,
1841
+ attributes: captureContent ? attributes : void 0,
1842
+ prompt_key: promptCtx?.promptKey,
1843
+ prompt_version: promptCtx?.promptVersion,
1844
+ prompt_ab_test_key: promptCtx?.abTestKey,
1845
+ prompt_variant_index: promptCtx?.variantIndex
1846
+ }).catch(() => {
1847
+ });
1848
+ }).catch((error) => {
1849
+ const endTime = Date.now();
1850
+ sendTrace({
1851
+ config_key: ctx.configKey,
1852
+ session_id: ctx.sessionId,
1853
+ customer_id: ctx.customerId,
1854
+ trace_id: traceId,
1855
+ span_id: spanId,
1856
+ parent_span_id: parentSpanId,
1857
+ name: "streamObject",
1858
+ kind: "llm",
1859
+ model: modelId,
1860
+ start_time: new Date(startTime).toISOString(),
1861
+ end_time: new Date(endTime).toISOString(),
1862
+ duration_ms: endTime - startTime,
1863
+ status: "ERROR",
1864
+ error_message: error?.message,
1865
+ prompt_key: promptCtx?.promptKey,
1866
+ prompt_version: promptCtx?.promptVersion,
1867
+ prompt_ab_test_key: promptCtx?.abTestKey,
1868
+ prompt_variant_index: promptCtx?.variantIndex
1869
+ }).catch(() => {
1870
+ });
1871
+ });
1872
+ }
1873
+ if (result?.partialObjectStream) {
1874
+ const originalStream = result.partialObjectStream;
1875
+ const wrappedStream = (async function* () {
1876
+ for await (const chunk of originalStream) {
1877
+ if (!firstTokenTime) {
1878
+ firstTokenTime = Date.now();
1879
+ log2("\u23F1\uFE0F Time to first token:", firstTokenTime - startTime, "ms");
1880
+ }
1881
+ yield chunk;
1882
+ }
1883
+ })();
1884
+ return new Proxy(result, {
1885
+ get(target, prop) {
1886
+ if (prop === "partialObjectStream") {
1887
+ return wrappedStream;
1888
+ }
1889
+ return target[prop];
1890
+ }
1891
+ });
1892
+ }
1893
+ return result;
1894
+ };
1895
+ }
1471
1896
 
1472
1897
  // src/models.ts
1473
1898
  var models_exports = {};
@@ -1477,7 +1902,7 @@ __export(models_exports, {
1477
1902
  });
1478
1903
  var import_crypto2 = require("crypto");
1479
1904
  var apiKey3 = null;
1480
- var baseUrl3 = "https://spans.fallom.com";
1905
+ var baseUrl3 = "https://configs.fallom.com";
1481
1906
  var initialized3 = false;
1482
1907
  var syncInterval2 = null;
1483
1908
  var debugMode3 = false;
@@ -1491,7 +1916,7 @@ function log3(msg) {
1491
1916
  }
1492
1917
  function init3(options = {}) {
1493
1918
  apiKey3 = options.apiKey || process.env.FALLOM_API_KEY || null;
1494
- baseUrl3 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
1919
+ baseUrl3 = options.baseUrl || process.env.FALLOM_CONFIGS_URL || process.env.FALLOM_BASE_URL || "https://configs.fallom.com";
1495
1920
  initialized3 = true;
1496
1921
  if (!apiKey3) {
1497
1922
  return;
@@ -1580,20 +2005,28 @@ async function get2(configKey, sessionId, options = {}) {
1580
2005
  const { version, fallback, debug = false } = options;
1581
2006
  debugMode3 = debug;
1582
2007
  ensureInit2();
1583
- log3(`get() called: configKey=${configKey}, sessionId=${sessionId}, fallback=${fallback}`);
2008
+ log3(
2009
+ `get() called: configKey=${configKey}, sessionId=${sessionId}, fallback=${fallback}`
2010
+ );
1584
2011
  try {
1585
2012
  let configData = configCache.get(configKey);
1586
- log3(`Cache lookup for '${configKey}': ${configData ? "found" : "not found"}`);
2013
+ log3(
2014
+ `Cache lookup for '${configKey}': ${configData ? "found" : "not found"}`
2015
+ );
1587
2016
  if (!configData) {
1588
2017
  log3("Not in cache, fetching...");
1589
2018
  await fetchConfigs(SYNC_TIMEOUT2);
1590
2019
  configData = configCache.get(configKey);
1591
- log3(`After fetch, cache lookup: ${configData ? "found" : "still not found"}`);
2020
+ log3(
2021
+ `After fetch, cache lookup: ${configData ? "found" : "still not found"}`
2022
+ );
1592
2023
  }
1593
2024
  if (!configData) {
1594
2025
  log3(`Config not found, using fallback: ${fallback}`);
1595
2026
  if (fallback) {
1596
- console.warn(`[Fallom WARNING] Config '${configKey}' not found, using fallback model: ${fallback}`);
2027
+ console.warn(
2028
+ `[Fallom WARNING] Config '${configKey}' not found, using fallback model: ${fallback}`
2029
+ );
1597
2030
  return returnWithTrace(configKey, sessionId, fallback, 0);
1598
2031
  }
1599
2032
  throw new Error(
@@ -1609,7 +2042,9 @@ async function get2(configKey, sessionId, options = {}) {
1609
2042
  }
1610
2043
  if (!config) {
1611
2044
  if (fallback) {
1612
- console.warn(`[Fallom WARNING] Config '${configKey}' version ${version} not found, using fallback: ${fallback}`);
2045
+ console.warn(
2046
+ `[Fallom WARNING] Config '${configKey}' version ${version} not found, using fallback: ${fallback}`
2047
+ );
1613
2048
  return returnWithTrace(configKey, sessionId, fallback, 0);
1614
2049
  }
1615
2050
  throw new Error(`Config '${configKey}' version ${version} not found.`);
@@ -1620,7 +2055,9 @@ async function get2(configKey, sessionId, options = {}) {
1620
2055
  config = configData.versions.get(targetVersion);
1621
2056
  if (!config) {
1622
2057
  if (fallback) {
1623
- console.warn(`[Fallom WARNING] Config '${configKey}' has no cached version, using fallback: ${fallback}`);
2058
+ console.warn(
2059
+ `[Fallom WARNING] Config '${configKey}' has no cached version, using fallback: ${fallback}`
2060
+ );
1624
2061
  return returnWithTrace(configKey, sessionId, fallback, 0);
1625
2062
  }
1626
2063
  throw new Error(`Config '${configKey}' has no cached version.`);
@@ -1629,7 +2066,11 @@ async function get2(configKey, sessionId, options = {}) {
1629
2066
  const variantsRaw = config.variants;
1630
2067
  const configVersion = config.version || targetVersion;
1631
2068
  const variants = Array.isArray(variantsRaw) ? variantsRaw : Object.values(variantsRaw);
1632
- log3(`Config found! Version: ${configVersion}, Variants: ${JSON.stringify(variants)}`);
2069
+ log3(
2070
+ `Config found! Version: ${configVersion}, Variants: ${JSON.stringify(
2071
+ variants
2072
+ )}`
2073
+ );
1633
2074
  const hashBytes = (0, import_crypto2.createHash)("md5").update(sessionId).digest();
1634
2075
  const hashVal = hashBytes.readUInt32BE(0) % 1e6;
1635
2076
  log3(`Session hash: ${hashVal} (out of 1,000,000)`);
@@ -1638,7 +2079,9 @@ async function get2(configKey, sessionId, options = {}) {
1638
2079
  for (const v of variants) {
1639
2080
  const oldCumulative = cumulative;
1640
2081
  cumulative += v.weight * 1e4;
1641
- log3(`Variant ${v.model}: weight=${v.weight}%, range=${oldCumulative}-${cumulative}, hash=${hashVal}, match=${hashVal < cumulative}`);
2082
+ log3(
2083
+ `Variant ${v.model}: weight=${v.weight}%, range=${oldCumulative}-${cumulative}, hash=${hashVal}, match=${hashVal < cumulative}`
2084
+ );
1642
2085
  if (hashVal < cumulative) {
1643
2086
  assignedModel = v.model;
1644
2087
  break;
@@ -1651,7 +2094,9 @@ async function get2(configKey, sessionId, options = {}) {
1651
2094
  throw e;
1652
2095
  }
1653
2096
  if (fallback) {
1654
- console.warn(`[Fallom WARNING] Error getting model for '${configKey}': ${e}. Using fallback: ${fallback}`);
2097
+ console.warn(
2098
+ `[Fallom WARNING] Error getting model for '${configKey}': ${e}. Using fallback: ${fallback}`
2099
+ );
1655
2100
  return returnWithTrace(configKey, sessionId, fallback, 0);
1656
2101
  }
1657
2102
  throw e;
@@ -1698,20 +2143,22 @@ init_prompts();
1698
2143
  // src/init.ts
1699
2144
  init_prompts();
1700
2145
  async function init4(options = {}) {
1701
- const baseUrl4 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
2146
+ const tracesUrl = options.tracesUrl || process.env.FALLOM_TRACES_URL || "https://traces.fallom.com";
2147
+ const configsUrl = options.configsUrl || process.env.FALLOM_CONFIGS_URL || "https://configs.fallom.com";
2148
+ const promptsUrl = options.promptsUrl || process.env.FALLOM_PROMPTS_URL || "https://prompts.fallom.com";
1702
2149
  await init2({
1703
2150
  apiKey: options.apiKey,
1704
- baseUrl: baseUrl4,
2151
+ baseUrl: tracesUrl,
1705
2152
  captureContent: options.captureContent,
1706
2153
  debug: options.debug
1707
2154
  });
1708
2155
  init3({
1709
2156
  apiKey: options.apiKey,
1710
- baseUrl: baseUrl4
2157
+ baseUrl: configsUrl
1711
2158
  });
1712
2159
  init({
1713
2160
  apiKey: options.apiKey,
1714
- baseUrl: baseUrl4
2161
+ baseUrl: promptsUrl
1715
2162
  });
1716
2163
  }
1717
2164