@fallom/trace 0.1.1 → 0.1.4

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
@@ -1,167 +1,223 @@
1
1
  # @fallom/trace
2
2
 
3
- Model A/B testing and tracing for LLM applications. Zero latency, production-ready.
3
+ Model A/B testing, prompt management, and tracing for LLM applications. Zero latency, production-ready.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @fallom/trace
9
-
10
- # With auto-instrumentation for your LLM provider:
11
- npm install @fallom/trace @traceloop/node-server-sdk
12
9
  ```
13
10
 
14
11
  ## Quick Start
15
12
 
16
13
  ```typescript
17
- // ⚠️ IMPORTANT: Import and initialize Fallom BEFORE importing OpenAI!
18
- import fallom from '@fallom/trace';
14
+ import fallom from "@fallom/trace";
15
+ import OpenAI from "openai";
19
16
 
20
- fallom.init({ apiKey: 'your-api-key' });
17
+ // Initialize Fallom
18
+ await fallom.init({ apiKey: "your-api-key" });
21
19
 
22
- // NOW import OpenAI (after instrumentation is set up)
23
- const { default: OpenAI } = await import('openai');
20
+ // Wrap your LLM client for automatic tracing
21
+ const openai = fallom.trace.wrapOpenAI(new OpenAI());
24
22
 
25
- // Set default session context for tracing
26
- fallom.trace.setSession('my-agent', sessionId);
23
+ // Set session context
24
+ fallom.trace.setSession("my-agent", sessionId);
27
25
 
28
26
  // All LLM calls are now automatically traced!
29
- const openai = new OpenAI();
30
27
  const response = await openai.chat.completions.create({
31
- model: 'gpt-4o',
32
- messages: [{ role: 'user', content: 'Hello!' }],
28
+ model: "gpt-4o",
29
+ messages: [{ role: "user", content: "Hello!" }],
33
30
  });
34
31
  ```
35
32
 
36
- > ⚠️ **Import Order Matters!** Auto-instrumentation hooks into libraries when they're imported. You must call `fallom.init()` BEFORE importing `openai`, `@anthropic-ai/sdk`, etc. Use dynamic imports (`await import('openai')`) to ensure correct order.
37
-
38
33
  ## Model A/B Testing
39
34
 
40
35
  Run A/B tests on models with zero latency. Same session always gets same model (sticky assignment).
41
36
 
42
37
  ```typescript
43
- import { models } from '@fallom/trace';
38
+ import { models } from "@fallom/trace";
44
39
 
45
40
  // Get assigned model for this session
46
- const model = await models.get('summarizer-config', sessionId);
41
+ const model = await models.get("summarizer-config", sessionId);
47
42
  // Returns: "gpt-4o" or "claude-3-5-sonnet" based on your config weights
48
43
 
49
- const agent = new Agent({ model });
50
- await agent.run(message);
44
+ const response = await openai.chat.completions.create({ model, ... });
51
45
  ```
52
46
 
53
- ### Version Pinning
47
+ ### Fallback for Resilience
48
+
49
+ ```typescript
50
+ const model = await models.get("my-config", sessionId, {
51
+ fallback: "gpt-4o-mini", // Used if config not found or Fallom unreachable
52
+ });
53
+ ```
54
+
55
+ ## Prompt Management
56
+
57
+ Manage prompts centrally and A/B test them with zero latency.
58
+
59
+ ### Basic Prompt Retrieval
60
+
61
+ ```typescript
62
+ import { prompts } from "@fallom/trace";
63
+
64
+ // Get a managed prompt (with template variables)
65
+ const prompt = await prompts.get("onboarding", {
66
+ variables: { userName: "John", company: "Acme" },
67
+ });
68
+
69
+ // Use the prompt with any LLM
70
+ const response = await openai.chat.completions.create({
71
+ model: "gpt-4o",
72
+ messages: [
73
+ { role: "system", content: prompt.system },
74
+ { role: "user", content: prompt.user },
75
+ ],
76
+ });
77
+ ```
78
+
79
+ The `prompt` object contains:
80
+ - `key`: The prompt key
81
+ - `version`: The prompt version
82
+ - `system`: The system prompt (with variables replaced)
83
+ - `user`: The user template (with variables replaced)
84
+
85
+ ### Prompt A/B Testing
86
+
87
+ Run experiments on different prompt versions:
88
+
89
+ ```typescript
90
+ import { prompts } from "@fallom/trace";
91
+
92
+ // Get prompt from A/B test (sticky assignment based on sessionId)
93
+ const prompt = await prompts.getAB("onboarding-test", sessionId, {
94
+ variables: { userName: "John" },
95
+ });
96
+
97
+ // prompt.abTestKey and prompt.variantIndex are set
98
+ // for analytics in your dashboard
99
+ ```
54
100
 
55
- Pin to a specific config version, or use latest (default):
101
+ ### Version Pinning
56
102
 
57
103
  ```typescript
58
104
  // Use latest version (default)
59
- const model = await models.get('my-config', sessionId);
105
+ const prompt = await prompts.get("my-prompt");
60
106
 
61
107
  // Pin to specific version
62
- const model = await models.get('my-config', sessionId, { version: 2 });
108
+ const prompt = await prompts.get("my-prompt", { version: 2 });
63
109
  ```
64
110
 
65
- ### Fallback for Resilience
111
+ ### Automatic Trace Tagging
66
112
 
67
- Always provide a fallback so your app works even if Fallom is down:
113
+ When you call `prompts.get()` or `prompts.getAB()`, the next LLM call is automatically tagged with the prompt information. This allows you to see which prompts are used in your traces without any extra code.
68
114
 
69
115
  ```typescript
70
- const model = await models.get('my-config', sessionId, {
71
- fallback: 'gpt-4o-mini', // Used if config not found or Fallom unreachable
116
+ // Get prompt - sets up auto-tagging for next LLM call
117
+ const prompt = await prompts.get("onboarding", {
118
+ variables: { userName: "John" },
72
119
  });
73
- ```
74
120
 
75
- **Resilience guarantees:**
76
- - Short timeouts (1-2 seconds max)
77
- - Background config sync (never blocks your requests)
78
- - Graceful degradation (returns fallback on any error)
79
- - Your app is never impacted by Fallom being down
121
+ // This call is automatically tagged with promptKey, promptVersion, etc.
122
+ const response = await openai.chat.completions.create({
123
+ model: "gpt-4o",
124
+ messages: [
125
+ { role: "system", content: prompt.system },
126
+ { role: "user", content: prompt.user },
127
+ ],
128
+ });
129
+ ```
80
130
 
81
131
  ## Tracing
82
132
 
83
- Auto-capture all LLM calls with OpenTelemetry instrumentation.
84
-
85
- > ⚠️ **Important:** Auto-tracing only works with supported LLM SDKs (OpenAI, Anthropic, etc.) - not raw HTTP requests. If you're using an OpenAI-compatible API like OpenRouter, LiteLLM, or a self-hosted model, use the OpenAI SDK with a custom `baseURL`:
86
- >
87
- > ```typescript
88
- > import OpenAI from 'openai';
89
- >
90
- > // OpenRouter, LiteLLM, vLLM, etc.
91
- > const client = new OpenAI({
92
- > baseURL: 'https://openrouter.ai/api/v1', // or your provider's URL
93
- > apiKey: 'your-provider-key',
94
- > });
95
- >
96
- > // Now this call will be auto-traced!
97
- > const response = await client.chat.completions.create({
98
- > model: 'gpt-4o',
99
- > messages: [...],
100
- > });
101
- > ```
102
-
103
- ### Automatic Tracing
133
+ Wrap your LLM client once, all calls are automatically traced.
134
+
135
+ ### OpenAI (+ OpenRouter, Azure, LiteLLM, etc.)
104
136
 
105
137
  ```typescript
106
- // Step 1: Import and init Fallom FIRST
107
- import fallom from '@fallom/trace';
108
- fallom.init();
138
+ import OpenAI from "openai";
139
+ import fallom from "@fallom/trace";
109
140
 
110
- // Step 2: Dynamic import OpenAI AFTER init
111
- const { default: OpenAI } = await import('openai');
112
- const openai = new OpenAI();
141
+ await fallom.init({ apiKey: "your-api-key" });
113
142
 
114
- // Step 3: Set session context
115
- fallom.trace.setSession('my-agent', sessionId);
143
+ // Works with any OpenAI-compatible API
144
+ const openai = fallom.trace.wrapOpenAI(
145
+ new OpenAI({
146
+ baseURL: "https://openrouter.ai/api/v1", // or Azure, LiteLLM, etc.
147
+ apiKey: "your-provider-key",
148
+ })
149
+ );
116
150
 
117
- // Step 4: Make LLM calls - automatically traced with:
118
- // - Model, tokens, latency
119
- // - Prompts and completions
120
- // - Your config_key and session_id
151
+ fallom.trace.setSession("my-config", sessionId);
152
+
153
+ // Automatically traced!
121
154
  const response = await openai.chat.completions.create({
122
- model: 'gpt-4o',
123
- messages: [...],
155
+ model: "gpt-4o",
156
+ messages: [{ role: "user", content: "Hello!" }],
124
157
  });
125
158
  ```
126
159
 
127
- > **Required dependency:** Install `@traceloop/node-server-sdk` for auto-instrumentation:
128
- > ```bash
129
- > npm install @traceloop/node-server-sdk
130
- > ```
160
+ ### Anthropic (Claude)
131
161
 
132
- ### Async Context Propagation
162
+ ```typescript
163
+ import Anthropic from "@anthropic-ai/sdk";
164
+ import fallom from "@fallom/trace";
133
165
 
134
- For proper session context across async boundaries, use `runWithSession`:
166
+ await fallom.init({ apiKey: "your-api-key" });
135
167
 
136
- ```typescript
137
- import { trace } from '@fallom/trace';
168
+ const anthropic = fallom.trace.wrapAnthropic(new Anthropic());
138
169
 
139
- await trace.runWithSession('my-agent', sessionId, async () => {
140
- // All LLM calls in here have session context
141
- await agent.run(message);
142
- await anotherAsyncOperation();
170
+ fallom.trace.setSession("my-config", sessionId);
171
+
172
+ // Automatically traced!
173
+ const response = await anthropic.messages.create({
174
+ model: "claude-3-5-sonnet-20241022",
175
+ messages: [{ role: "user", content: "Hello!" }],
143
176
  });
144
177
  ```
145
178
 
146
- ### Custom Metrics
179
+ ### Google AI (Gemini)
180
+
181
+ ```typescript
182
+ import { GoogleGenerativeAI } from "@google/generative-ai";
183
+ import fallom from "@fallom/trace";
184
+
185
+ await fallom.init({ apiKey: "your-api-key" });
186
+
187
+ const genAI = new GoogleGenerativeAI(apiKey);
188
+ const model = fallom.trace.wrapGoogleAI(
189
+ genAI.getGenerativeModel({ model: "gemini-pro" })
190
+ );
191
+
192
+ fallom.trace.setSession("my-config", sessionId);
193
+
194
+ // Automatically traced!
195
+ const response = await model.generateContent("Hello!");
196
+ ```
197
+
198
+ ## What Gets Traced
199
+
200
+ For each LLM call, Fallom automatically captures:
201
+ - ✅ Model name
202
+ - ✅ Duration (latency)
203
+ - ✅ Token counts (prompt, completion, total)
204
+ - ✅ Input/output content (can be disabled)
205
+ - ✅ Errors
206
+ - ✅ Config key + session ID (for A/B analysis)
207
+ - ✅ Prompt key + version (when using prompt management)
147
208
 
148
- Record business metrics that OTEL can't capture automatically:
209
+ ## Custom Metrics
210
+
211
+ Record business metrics for your A/B tests:
149
212
 
150
213
  ```typescript
151
- import { trace } from '@fallom/trace';
214
+ import { trace } from "@fallom/trace";
152
215
 
153
- // Record custom metrics for this session
154
216
  trace.span({
155
217
  outlier_score: 0.8,
156
218
  user_satisfaction: 4,
157
219
  conversion: true,
158
220
  });
159
-
160
- // Or explicitly specify session (for batch jobs)
161
- trace.span(
162
- { outlier_score: 0.8 },
163
- { configKey: 'my-agent', sessionId: 'user123-convo456' }
164
- );
165
221
  ```
166
222
 
167
223
  ## Configuration
@@ -170,120 +226,96 @@ trace.span(
170
226
 
171
227
  ```bash
172
228
  FALLOM_API_KEY=your-api-key
173
- FALLOM_BASE_URL=https://spans.fallom.com # or http://localhost:8001 for local dev
229
+ FALLOM_BASE_URL=https://spans.fallom.com
174
230
  FALLOM_CAPTURE_CONTENT=true # set to "false" for privacy mode
175
231
  ```
176
232
 
177
- ### Initialization Options
178
-
179
- ```typescript
180
- fallom.init({
181
- apiKey: 'your-api-key', // Or use FALLOM_API_KEY env var
182
- baseUrl: 'https://spans.fallom.com', // Or use FALLOM_BASE_URL env var
183
- captureContent: true, // Set false for privacy mode
184
- });
185
- ```
186
-
187
233
  ### Privacy Mode
188
234
 
189
- For companies with strict data policies, disable prompt/completion capture:
235
+ Disable prompt/completion capture:
190
236
 
191
237
  ```typescript
192
- // Via parameter
193
238
  fallom.init({ captureContent: false });
194
-
195
- // Or via environment variable
196
- // FALLOM_CAPTURE_CONTENT=false
197
239
  ```
198
240
 
199
- In privacy mode, Fallom still tracks:
200
- - ✅ Model used
201
- - ✅ Token counts
202
- - ✅ Latency
203
- - ✅ Session/config context
204
- - ❌ Prompt content (not captured)
205
- - ❌ Completion content (not captured)
206
-
207
241
  ## API Reference
208
242
 
209
243
  ### `fallom.init(options?)`
210
244
 
211
- Initialize the SDK. Call this before making LLM calls for auto-instrumentation.
245
+ Initialize the SDK.
212
246
 
213
- | Option | Type | Default | Description |
214
- |--------|------|---------|-------------|
215
- | `apiKey` | `string` | `FALLOM_API_KEY` env | Your Fallom API key |
216
- | `baseUrl` | `string` | `https://spans.fallom.com` | API base URL |
217
- | `captureContent` | `boolean` | `true` | Capture prompt/completion text |
247
+ ### `fallom.trace.wrapOpenAI(client)`
218
248
 
219
- ### `fallom.models.get(configKey, sessionId, options?)`
249
+ Wrap OpenAI client for automatic tracing. Works with any OpenAI-compatible API.
220
250
 
221
- Get model assignment for a session.
251
+ ### `fallom.trace.wrapAnthropic(client)`
222
252
 
223
- | Parameter | Type | Description |
224
- |-----------|------|-------------|
225
- | `configKey` | `string` | Your config name from the dashboard |
226
- | `sessionId` | `string` | Unique session/conversation ID (sticky assignment) |
227
- | `options.version` | `number` | Pin to specific version (default: latest) |
228
- | `options.fallback` | `string` | Model to return if anything fails |
229
- | `options.debug` | `boolean` | Enable debug logging |
253
+ Wrap Anthropic client for automatic tracing.
230
254
 
231
- Returns: `Promise<string>` - The assigned model name
255
+ ### `fallom.trace.wrapGoogleAI(model)`
256
+
257
+ Wrap Google AI model for automatic tracing.
232
258
 
233
259
  ### `fallom.trace.setSession(configKey, sessionId)`
234
260
 
235
- Set trace context. All subsequent LLM calls will be tagged with this session.
261
+ Set session context for tracing.
236
262
 
237
- ### `fallom.trace.runWithSession(configKey, sessionId, fn)`
263
+ ### `fallom.models.get(configKey, sessionId, options?)`
238
264
 
239
- Run a function with session context that propagates across async boundaries.
265
+ Get model assignment for A/B testing. Returns `Promise<string>`.
240
266
 
241
- ### `fallom.trace.clearSession()`
267
+ ### `fallom.prompts.get(promptKey, options?)`
242
268
 
243
- Clear trace context.
269
+ Get a managed prompt. Returns `Promise<PromptResult>`.
270
+ - `promptKey`: Your prompt key from the dashboard
271
+ - `options.variables`: Template variables (e.g., `{ userName: "John" }`)
272
+ - `options.version`: Pin to specific version (default: latest)
244
273
 
245
- ### `fallom.trace.span(data, options?)`
274
+ ### `fallom.prompts.getAB(abTestKey, sessionId, options?)`
246
275
 
247
- Record custom business metrics.
276
+ Get a prompt from an A/B test. Returns `Promise<PromptResult>`.
277
+ - `abTestKey`: Your A/B test key from the dashboard
278
+ - `sessionId`: Session ID for sticky assignment
279
+ - `options.variables`: Template variables
280
+
281
+ ### `fallom.trace.span(data)`
248
282
 
249
- | Parameter | Type | Description |
250
- |-----------|------|-------------|
251
- | `data` | `Record<string, unknown>` | Metrics to record |
252
- | `options.configKey` | `string` | Optional if `setSession()` was called |
253
- | `options.sessionId` | `string` | Optional if `setSession()` was called |
283
+ Record custom business metrics.
254
284
 
255
- ### `fallom.trace.shutdown()`
285
+ ## Testing
256
286
 
257
- Gracefully shutdown the tracing SDK. Call this on process exit.
287
+ Run the test suite:
258
288
 
259
- ## Supported LLM Providers
289
+ ```bash
290
+ cd sdk/typescript-sdk
291
+ npm install
292
+ npm test
293
+ ```
260
294
 
261
- Auto-instrumentation available for:
262
- - OpenAI (+ OpenAI-compatible APIs: OpenRouter, LiteLLM, vLLM, Ollama, etc.)
263
- - Anthropic
264
- - Cohere
265
- - AWS Bedrock
266
- - Google Generative AI
267
- - Azure OpenAI
268
- - LangChain
269
- - And more via Traceloop
295
+ ## Deploying
270
296
 
271
- Install `@traceloop/node-server-sdk` for comprehensive LLM instrumentation.
297
+ To publish a new version to npm:
272
298
 
273
- **Note:** You must use the official SDK for your provider. Raw HTTP requests (e.g., `fetch()`) will not be traced. For OpenAI-compatible APIs, use the OpenAI SDK with a custom `baseURL`.
299
+ ```bash
300
+ cd sdk/typescript-sdk
274
301
 
275
- ## Examples
302
+ # Update version in package.json
303
+ # Then:
304
+ npm run build
305
+ npm publish --access public
276
306
 
277
- See the `../examples/` folder for complete examples:
278
- - `random-fact/` - Simple A/B testing with Hono server
307
+ # Or use convenience scripts:
308
+ npm run publish:patch # 0.1.0 -> 0.1.1
309
+ npm run publish:minor # 0.1.0 -> 0.2.0
310
+ npm run publish:major # 0.1.0 -> 1.0.0
311
+ ```
279
312
 
280
313
  ## Requirements
281
314
 
282
315
  - Node.js >= 18.0.0
283
316
 
284
- > ⚠️ **Bun Compatibility:** Auto-tracing uses OpenTelemetry instrumentation which relies on Node.js module hooks. **Bun has limited support** for this. For full tracing functionality, use Node.js. A/B testing (`models.get()`) works fine in Bun.
317
+ Works with ESM and CommonJS. Works with tsx, ts-node, Bun, and compiled JavaScript.
285
318
 
286
319
  ## License
287
320
 
288
321
  MIT
289
-