@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/README.md CHANGED
@@ -226,7 +226,9 @@ trace.span({
226
226
 
227
227
  ```bash
228
228
  FALLOM_API_KEY=your-api-key
229
- FALLOM_BASE_URL=https://spans.fallom.com
229
+ FALLOM_TRACES_URL=https://traces.fallom.com
230
+ FALLOM_CONFIGS_URL=https://configs.fallom.com
231
+ FALLOM_PROMPTS_URL=https://prompts.fallom.com
230
232
  FALLOM_CAPTURE_CONTENT=true # set to "false" for privacy mode
231
233
  ```
232
234
 
@@ -0,0 +1,255 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/prompts.ts
8
+ var prompts_exports = {};
9
+ __export(prompts_exports, {
10
+ clearPromptContext: () => clearPromptContext,
11
+ get: () => get,
12
+ getAB: () => getAB,
13
+ getPromptContext: () => getPromptContext,
14
+ init: () => init
15
+ });
16
+ import { createHash } from "crypto";
17
+ var apiKey = null;
18
+ var baseUrl = "https://prompts.fallom.com";
19
+ var initialized = false;
20
+ var syncInterval = null;
21
+ var debugMode = false;
22
+ var promptCache = /* @__PURE__ */ new Map();
23
+ var promptABCache = /* @__PURE__ */ new Map();
24
+ var promptContext = null;
25
+ var SYNC_TIMEOUT = 2e3;
26
+ function log(msg) {
27
+ if (debugMode) {
28
+ console.log(`[Fallom Prompts] ${msg}`);
29
+ }
30
+ }
31
+ function init(options = {}) {
32
+ apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
33
+ baseUrl = options.baseUrl || process.env.FALLOM_PROMPTS_URL || process.env.FALLOM_BASE_URL || "https://prompts.fallom.com";
34
+ initialized = true;
35
+ if (!apiKey) {
36
+ return;
37
+ }
38
+ fetchAll().catch(() => {
39
+ });
40
+ if (!syncInterval) {
41
+ syncInterval = setInterval(() => {
42
+ fetchAll().catch(() => {
43
+ });
44
+ }, 3e4);
45
+ syncInterval.unref();
46
+ }
47
+ }
48
+ function ensureInit() {
49
+ if (!initialized) {
50
+ try {
51
+ init();
52
+ } catch {
53
+ }
54
+ }
55
+ }
56
+ async function fetchAll() {
57
+ await Promise.all([fetchPrompts(), fetchPromptABTests()]);
58
+ }
59
+ async function fetchPrompts(timeout = SYNC_TIMEOUT) {
60
+ if (!apiKey) return;
61
+ try {
62
+ const controller = new AbortController();
63
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
64
+ const resp = await fetch(`${baseUrl}/prompts`, {
65
+ headers: { Authorization: `Bearer ${apiKey}` },
66
+ signal: controller.signal
67
+ });
68
+ clearTimeout(timeoutId);
69
+ if (resp.ok) {
70
+ const data = await resp.json();
71
+ for (const p of data.prompts || []) {
72
+ if (!promptCache.has(p.key)) {
73
+ promptCache.set(p.key, { versions: /* @__PURE__ */ new Map(), current: null });
74
+ }
75
+ const cached = promptCache.get(p.key);
76
+ cached.versions.set(p.version, {
77
+ systemPrompt: p.system_prompt,
78
+ userTemplate: p.user_template
79
+ });
80
+ cached.current = p.version;
81
+ }
82
+ }
83
+ } catch {
84
+ }
85
+ }
86
+ async function fetchPromptABTests(timeout = SYNC_TIMEOUT) {
87
+ if (!apiKey) return;
88
+ try {
89
+ const controller = new AbortController();
90
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
91
+ const resp = await fetch(`${baseUrl}/prompt-ab-tests`, {
92
+ headers: { Authorization: `Bearer ${apiKey}` },
93
+ signal: controller.signal
94
+ });
95
+ clearTimeout(timeoutId);
96
+ if (resp.ok) {
97
+ const data = await resp.json();
98
+ for (const t of data.prompt_ab_tests || []) {
99
+ if (!promptABCache.has(t.key)) {
100
+ promptABCache.set(t.key, { versions: /* @__PURE__ */ new Map(), current: null });
101
+ }
102
+ const cached = promptABCache.get(t.key);
103
+ cached.versions.set(t.version, { variants: t.variants });
104
+ cached.current = t.version;
105
+ }
106
+ }
107
+ } catch {
108
+ }
109
+ }
110
+ function replaceVariables(template, variables) {
111
+ if (!variables) return template;
112
+ return template.replace(/\{\{(\s*\w+\s*)\}\}/g, (match, varName) => {
113
+ const key = varName.trim();
114
+ return key in variables ? String(variables[key]) : match;
115
+ });
116
+ }
117
+ function setPromptContext(ctx) {
118
+ promptContext = ctx;
119
+ }
120
+ function getPromptContext() {
121
+ const ctx = promptContext;
122
+ promptContext = null;
123
+ return ctx;
124
+ }
125
+ async function get(promptKey, options = {}) {
126
+ const { variables, version, debug = false } = options;
127
+ debugMode = debug;
128
+ ensureInit();
129
+ log(`get() called: promptKey=${promptKey}`);
130
+ let promptData = promptCache.get(promptKey);
131
+ if (!promptData) {
132
+ log("Not in cache, fetching...");
133
+ await fetchPrompts(SYNC_TIMEOUT);
134
+ promptData = promptCache.get(promptKey);
135
+ }
136
+ if (!promptData) {
137
+ throw new Error(
138
+ `Prompt '${promptKey}' not found. Check that it exists in your Fallom dashboard.`
139
+ );
140
+ }
141
+ const targetVersion = version ?? promptData.current;
142
+ const content = promptData.versions.get(targetVersion);
143
+ if (!content) {
144
+ throw new Error(
145
+ `Prompt '${promptKey}' version ${targetVersion} not found.`
146
+ );
147
+ }
148
+ const system = replaceVariables(content.systemPrompt, variables);
149
+ const user = replaceVariables(content.userTemplate, variables);
150
+ setPromptContext({
151
+ promptKey,
152
+ promptVersion: targetVersion
153
+ });
154
+ log(`\u2705 Got prompt: ${promptKey} v${targetVersion}`);
155
+ return {
156
+ key: promptKey,
157
+ version: targetVersion,
158
+ system,
159
+ user
160
+ };
161
+ }
162
+ async function getAB(abTestKey, sessionId, options = {}) {
163
+ const { variables, debug = false } = options;
164
+ debugMode = debug;
165
+ ensureInit();
166
+ log(`getAB() called: abTestKey=${abTestKey}, sessionId=${sessionId}`);
167
+ let abData = promptABCache.get(abTestKey);
168
+ if (!abData) {
169
+ log("Not in cache, fetching...");
170
+ await fetchPromptABTests(SYNC_TIMEOUT);
171
+ abData = promptABCache.get(abTestKey);
172
+ }
173
+ if (!abData) {
174
+ throw new Error(
175
+ `Prompt A/B test '${abTestKey}' not found. Check that it exists in your Fallom dashboard.`
176
+ );
177
+ }
178
+ const currentVersion = abData.current;
179
+ const versionData = abData.versions.get(currentVersion);
180
+ if (!versionData) {
181
+ throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
182
+ }
183
+ const { variants } = versionData;
184
+ log(`A/B test '${abTestKey}' has ${variants?.length ?? 0} variants`);
185
+ log(`Version data: ${JSON.stringify(versionData, null, 2)}`);
186
+ if (!variants || variants.length === 0) {
187
+ throw new Error(
188
+ `Prompt A/B test '${abTestKey}' has no variants configured.`
189
+ );
190
+ }
191
+ const hashBytes = createHash("md5").update(sessionId).digest();
192
+ const hashVal = hashBytes.readUInt32BE(0) % 1e6;
193
+ let cumulative = 0;
194
+ let selectedVariant = variants[variants.length - 1];
195
+ let selectedIndex = variants.length - 1;
196
+ for (let i = 0; i < variants.length; i++) {
197
+ cumulative += variants[i].weight * 1e4;
198
+ if (hashVal < cumulative) {
199
+ selectedVariant = variants[i];
200
+ selectedIndex = i;
201
+ break;
202
+ }
203
+ }
204
+ const promptKey = selectedVariant.prompt_key;
205
+ const promptVersion = selectedVariant.prompt_version;
206
+ let promptData = promptCache.get(promptKey);
207
+ if (!promptData) {
208
+ await fetchPrompts(SYNC_TIMEOUT);
209
+ promptData = promptCache.get(promptKey);
210
+ }
211
+ if (!promptData) {
212
+ throw new Error(
213
+ `Prompt '${promptKey}' (from A/B test '${abTestKey}') not found.`
214
+ );
215
+ }
216
+ const targetVersion = promptVersion ?? promptData.current;
217
+ const content = promptData.versions.get(targetVersion);
218
+ if (!content) {
219
+ throw new Error(
220
+ `Prompt '${promptKey}' version ${targetVersion} not found.`
221
+ );
222
+ }
223
+ const system = replaceVariables(content.systemPrompt, variables);
224
+ const user = replaceVariables(content.userTemplate, variables);
225
+ setPromptContext({
226
+ promptKey,
227
+ promptVersion: targetVersion,
228
+ abTestKey,
229
+ variantIndex: selectedIndex
230
+ });
231
+ log(
232
+ `\u2705 Got prompt from A/B: ${promptKey} v${targetVersion} (variant ${selectedIndex})`
233
+ );
234
+ return {
235
+ key: promptKey,
236
+ version: targetVersion,
237
+ system,
238
+ user,
239
+ abTestKey,
240
+ variantIndex: selectedIndex
241
+ };
242
+ }
243
+ function clearPromptContext() {
244
+ promptContext = null;
245
+ }
246
+
247
+ export {
248
+ __export,
249
+ init,
250
+ getPromptContext,
251
+ get,
252
+ getAB,
253
+ clearPromptContext,
254
+ prompts_exports
255
+ };
@@ -0,0 +1,255 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/prompts.ts
8
+ var prompts_exports = {};
9
+ __export(prompts_exports, {
10
+ clearPromptContext: () => clearPromptContext,
11
+ get: () => get,
12
+ getAB: () => getAB,
13
+ getPromptContext: () => getPromptContext,
14
+ init: () => init
15
+ });
16
+ import { createHash } from "crypto";
17
+ var apiKey = null;
18
+ var baseUrl = "https://prompts.fallom.com";
19
+ var initialized = false;
20
+ var syncInterval = null;
21
+ var debugMode = false;
22
+ var promptCache = /* @__PURE__ */ new Map();
23
+ var promptABCache = /* @__PURE__ */ new Map();
24
+ var promptContext = null;
25
+ var SYNC_TIMEOUT = 2e3;
26
+ function log(msg) {
27
+ if (debugMode) {
28
+ console.log(`[Fallom Prompts] ${msg}`);
29
+ }
30
+ }
31
+ function init(options = {}) {
32
+ apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
33
+ baseUrl = options.baseUrl || process.env.FALLOM_PROMPTS_URL || process.env.FALLOM_BASE_URL || "https://prompts.fallom.com";
34
+ initialized = true;
35
+ if (!apiKey) {
36
+ return;
37
+ }
38
+ fetchAll().catch(() => {
39
+ });
40
+ if (!syncInterval) {
41
+ syncInterval = setInterval(() => {
42
+ fetchAll().catch(() => {
43
+ });
44
+ }, 3e4);
45
+ syncInterval.unref();
46
+ }
47
+ }
48
+ function ensureInit() {
49
+ if (!initialized) {
50
+ try {
51
+ init();
52
+ } catch {
53
+ }
54
+ }
55
+ }
56
+ async function fetchAll() {
57
+ await Promise.all([fetchPrompts(), fetchPromptABTests()]);
58
+ }
59
+ async function fetchPrompts(timeout = SYNC_TIMEOUT) {
60
+ if (!apiKey) return;
61
+ try {
62
+ const controller = new AbortController();
63
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
64
+ const resp = await fetch(`${baseUrl}/prompts`, {
65
+ headers: { Authorization: `Bearer ${apiKey}` },
66
+ signal: controller.signal
67
+ });
68
+ clearTimeout(timeoutId);
69
+ if (resp.ok) {
70
+ const data = await resp.json();
71
+ for (const p of data.prompts || []) {
72
+ if (!promptCache.has(p.key)) {
73
+ promptCache.set(p.key, { versions: /* @__PURE__ */ new Map(), current: null });
74
+ }
75
+ const cached = promptCache.get(p.key);
76
+ cached.versions.set(p.version, {
77
+ systemPrompt: p.system_prompt,
78
+ userTemplate: p.user_template
79
+ });
80
+ cached.current = p.version;
81
+ }
82
+ }
83
+ } catch {
84
+ }
85
+ }
86
+ async function fetchPromptABTests(timeout = SYNC_TIMEOUT) {
87
+ if (!apiKey) return;
88
+ try {
89
+ const controller = new AbortController();
90
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
91
+ const resp = await fetch(`${baseUrl}/prompt-ab-tests`, {
92
+ headers: { Authorization: `Bearer ${apiKey}` },
93
+ signal: controller.signal
94
+ });
95
+ clearTimeout(timeoutId);
96
+ if (resp.ok) {
97
+ const data = await resp.json();
98
+ for (const t of data.prompt_ab_tests || []) {
99
+ if (!promptABCache.has(t.key)) {
100
+ promptABCache.set(t.key, { versions: /* @__PURE__ */ new Map(), current: null });
101
+ }
102
+ const cached = promptABCache.get(t.key);
103
+ cached.versions.set(t.version, { variants: t.variants });
104
+ cached.current = t.version;
105
+ }
106
+ }
107
+ } catch {
108
+ }
109
+ }
110
+ function replaceVariables(template, variables) {
111
+ if (!variables) return template;
112
+ return template.replace(/\{\{(\s*\w+\s*)\}\}/g, (match, varName) => {
113
+ const key = varName.trim();
114
+ return key in variables ? String(variables[key]) : match;
115
+ });
116
+ }
117
+ function setPromptContext(ctx) {
118
+ promptContext = ctx;
119
+ }
120
+ function getPromptContext() {
121
+ const ctx = promptContext;
122
+ promptContext = null;
123
+ return ctx;
124
+ }
125
+ async function get(promptKey, options = {}) {
126
+ const { variables, version, debug = false } = options;
127
+ debugMode = debug;
128
+ ensureInit();
129
+ log(`get() called: promptKey=${promptKey}`);
130
+ let promptData = promptCache.get(promptKey);
131
+ if (!promptData) {
132
+ log("Not in cache, fetching...");
133
+ await fetchPrompts(SYNC_TIMEOUT);
134
+ promptData = promptCache.get(promptKey);
135
+ }
136
+ if (!promptData) {
137
+ throw new Error(
138
+ `Prompt '${promptKey}' not found. Check that it exists in your Fallom dashboard.`
139
+ );
140
+ }
141
+ const targetVersion = version ?? promptData.current;
142
+ const content = promptData.versions.get(targetVersion);
143
+ if (!content) {
144
+ throw new Error(
145
+ `Prompt '${promptKey}' version ${targetVersion} not found.`
146
+ );
147
+ }
148
+ const system = replaceVariables(content.systemPrompt, variables);
149
+ const user = replaceVariables(content.userTemplate, variables);
150
+ setPromptContext({
151
+ promptKey,
152
+ promptVersion: targetVersion
153
+ });
154
+ log(`\u2705 Got prompt: ${promptKey} v${targetVersion}`);
155
+ return {
156
+ key: promptKey,
157
+ version: targetVersion,
158
+ system,
159
+ user
160
+ };
161
+ }
162
+ async function getAB(abTestKey, sessionId, options = {}) {
163
+ const { variables, debug = false } = options;
164
+ debugMode = debug;
165
+ ensureInit();
166
+ log(`getAB() called: abTestKey=${abTestKey}, sessionId=${sessionId}`);
167
+ let abData = promptABCache.get(abTestKey);
168
+ if (!abData) {
169
+ log("Not in cache, fetching...");
170
+ await fetchPromptABTests(SYNC_TIMEOUT);
171
+ abData = promptABCache.get(abTestKey);
172
+ }
173
+ if (!abData) {
174
+ throw new Error(
175
+ `Prompt A/B test '${abTestKey}' not found. Check that it exists in your Fallom dashboard.`
176
+ );
177
+ }
178
+ const currentVersion = abData.current;
179
+ const versionData = abData.versions.get(currentVersion);
180
+ if (!versionData) {
181
+ throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
182
+ }
183
+ const { variants } = versionData;
184
+ log(`A/B test '${abTestKey}' has ${variants?.length ?? 0} variants`);
185
+ log(`Version data:`, JSON.stringify(versionData, null, 2));
186
+ if (!variants || variants.length === 0) {
187
+ throw new Error(
188
+ `Prompt A/B test '${abTestKey}' has no variants configured.`
189
+ );
190
+ }
191
+ const hashBytes = createHash("md5").update(sessionId).digest();
192
+ const hashVal = hashBytes.readUInt32BE(0) % 1e6;
193
+ let cumulative = 0;
194
+ let selectedVariant = variants[variants.length - 1];
195
+ let selectedIndex = variants.length - 1;
196
+ for (let i = 0; i < variants.length; i++) {
197
+ cumulative += variants[i].weight * 1e4;
198
+ if (hashVal < cumulative) {
199
+ selectedVariant = variants[i];
200
+ selectedIndex = i;
201
+ break;
202
+ }
203
+ }
204
+ const promptKey = selectedVariant.prompt_key;
205
+ const promptVersion = selectedVariant.prompt_version;
206
+ let promptData = promptCache.get(promptKey);
207
+ if (!promptData) {
208
+ await fetchPrompts(SYNC_TIMEOUT);
209
+ promptData = promptCache.get(promptKey);
210
+ }
211
+ if (!promptData) {
212
+ throw new Error(
213
+ `Prompt '${promptKey}' (from A/B test '${abTestKey}') not found.`
214
+ );
215
+ }
216
+ const targetVersion = promptVersion ?? promptData.current;
217
+ const content = promptData.versions.get(targetVersion);
218
+ if (!content) {
219
+ throw new Error(
220
+ `Prompt '${promptKey}' version ${targetVersion} not found.`
221
+ );
222
+ }
223
+ const system = replaceVariables(content.systemPrompt, variables);
224
+ const user = replaceVariables(content.userTemplate, variables);
225
+ setPromptContext({
226
+ promptKey,
227
+ promptVersion: targetVersion,
228
+ abTestKey,
229
+ variantIndex: selectedIndex
230
+ });
231
+ log(
232
+ `\u2705 Got prompt from A/B: ${promptKey} v${targetVersion} (variant ${selectedIndex})`
233
+ );
234
+ return {
235
+ key: promptKey,
236
+ version: targetVersion,
237
+ system,
238
+ user,
239
+ abTestKey,
240
+ variantIndex: selectedIndex
241
+ };
242
+ }
243
+ function clearPromptContext() {
244
+ promptContext = null;
245
+ }
246
+
247
+ export {
248
+ __export,
249
+ init,
250
+ getPromptContext,
251
+ get,
252
+ getAB,
253
+ clearPromptContext,
254
+ prompts_exports
255
+ };
package/dist/index.d.mts CHANGED
@@ -183,6 +183,45 @@ declare function wrapAnthropic<T extends {
183
183
  declare function wrapGoogleAI<T extends {
184
184
  generateContent: (...args: any[]) => Promise<any>;
185
185
  }>(model: T): T;
186
+ /**
187
+ * Wrap the Vercel AI SDK to automatically trace all LLM calls.
188
+ * Works with generateText, streamText, generateObject, streamObject.
189
+ *
190
+ * @param ai - The ai module (import * as ai from "ai")
191
+ * @returns Object with wrapped generateText, streamText, generateObject, streamObject
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * import * as ai from "ai";
196
+ * import { createOpenAI } from "@ai-sdk/openai";
197
+ * import { trace } from "@fallom/trace";
198
+ *
199
+ * await trace.init({ apiKey: process.env.FALLOM_API_KEY });
200
+ * const { generateText, streamText } = trace.wrapAISDK(ai);
201
+ *
202
+ * const openrouter = createOpenAI({
203
+ * apiKey: process.env.OPENROUTER_API_KEY,
204
+ * baseURL: "https://openrouter.ai/api/v1",
205
+ * });
206
+ *
207
+ * trace.setSession("my-config", sessionId);
208
+ * const { text } = await generateText({
209
+ * model: openrouter("openai/gpt-4o-mini"),
210
+ * prompt: "Hello!",
211
+ * }); // Automatically traced!
212
+ * ```
213
+ */
214
+ declare function wrapAISDK<T extends {
215
+ generateText: (...args: any[]) => Promise<any>;
216
+ streamText: (...args: any[]) => any;
217
+ generateObject?: (...args: any[]) => Promise<any>;
218
+ streamObject?: (...args: any[]) => any;
219
+ }>(ai: T): {
220
+ generateText: T["generateText"];
221
+ streamText: T["streamText"];
222
+ generateObject: T["generateObject"];
223
+ streamObject: T["streamObject"];
224
+ };
186
225
 
187
226
  declare const trace_clearSession: typeof clearSession;
188
227
  declare const trace_getSession: typeof getSession;
@@ -190,11 +229,12 @@ declare const trace_runWithSession: typeof runWithSession;
190
229
  declare const trace_setSession: typeof setSession;
191
230
  declare const trace_shutdown: typeof shutdown;
192
231
  declare const trace_span: typeof span;
232
+ declare const trace_wrapAISDK: typeof wrapAISDK;
193
233
  declare const trace_wrapAnthropic: typeof wrapAnthropic;
194
234
  declare const trace_wrapGoogleAI: typeof wrapGoogleAI;
195
235
  declare const trace_wrapOpenAI: typeof wrapOpenAI;
196
236
  declare namespace trace {
197
- export { trace_clearSession as clearSession, trace_getSession as getSession, init$3 as init, trace_runWithSession as runWithSession, trace_setSession as setSession, trace_shutdown as shutdown, trace_span as span, trace_wrapAnthropic as wrapAnthropic, trace_wrapGoogleAI as wrapGoogleAI, trace_wrapOpenAI as wrapOpenAI };
237
+ export { trace_clearSession as clearSession, trace_getSession as getSession, init$3 as init, trace_runWithSession as runWithSession, trace_setSession as setSession, trace_shutdown as shutdown, trace_span as span, trace_wrapAISDK as wrapAISDK, trace_wrapAnthropic as wrapAnthropic, trace_wrapGoogleAI as wrapGoogleAI, trace_wrapOpenAI as wrapOpenAI };
198
238
  }
199
239
 
200
240
  /**
@@ -368,16 +408,20 @@ declare namespace prompts {
368
408
  */
369
409
  interface InitOptions {
370
410
  apiKey?: string;
371
- baseUrl?: string;
411
+ tracesUrl?: string;
412
+ configsUrl?: string;
413
+ promptsUrl?: string;
372
414
  captureContent?: boolean;
373
415
  debug?: boolean;
374
416
  }
375
417
  /**
376
- * Initialize both trace and models at once.
418
+ * Initialize trace, models, and prompts at once.
377
419
  *
378
420
  * @param options - Configuration options
379
421
  * @param options.apiKey - Your Fallom API key. Defaults to FALLOM_API_KEY env var.
380
- * @param options.baseUrl - API base URL. Defaults to FALLOM_BASE_URL or https://spans.fallom.com
422
+ * @param options.tracesUrl - Traces API URL. Defaults to FALLOM_TRACES_URL or https://traces.fallom.com
423
+ * @param options.configsUrl - Configs API URL. Defaults to FALLOM_CONFIGS_URL or https://configs.fallom.com
424
+ * @param options.promptsUrl - Prompts API URL. Defaults to FALLOM_PROMPTS_URL or https://prompts.fallom.com
381
425
  * @param options.captureContent - Whether to capture prompt/completion content (default: true)
382
426
  *
383
427
  * @example
@@ -388,7 +432,11 @@ interface InitOptions {
388
432
  * fallom.init({ apiKey: "your-api-key" });
389
433
  *
390
434
  * // Local development
391
- * fallom.init({ baseUrl: "http://localhost:8001" });
435
+ * fallom.init({
436
+ * tracesUrl: "http://localhost:3002",
437
+ * configsUrl: "http://localhost:3003",
438
+ * promptsUrl: "http://localhost:3004"
439
+ * });
392
440
  *
393
441
  * // Privacy mode
394
442
  * fallom.init({ captureContent: false });