@lelemondev/sdk 0.2.1 → 0.3.0
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 +124 -73
- package/dist/index.d.mts +50 -278
- package/dist/index.d.ts +50 -278
- package/dist/index.js +724 -524
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +723 -520
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
[](https://github.com/lelemondev/lelemondev-sdk/actions/workflows/ci.yml)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Automatic LLM observability for Node.js. Track your AI agents with zero code changes.
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
11
|
+
- **Automatic Tracing** - Wrap your client, everything is traced
|
|
12
|
+
- **Fire-and-forget** - Never blocks your code
|
|
13
|
+
- **Auto-batching** - Efficient network usage
|
|
14
|
+
- **Streaming Support** - Full support for streaming responses
|
|
15
|
+
- **Type-safe** - Preserves your client's TypeScript types
|
|
16
|
+
- **Serverless-ready** - Built-in flush for Lambda/Vercel
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
|
|
@@ -23,26 +24,34 @@ npm install @lelemondev/sdk
|
|
|
23
24
|
## Quick Start
|
|
24
25
|
|
|
25
26
|
```typescript
|
|
26
|
-
import { init,
|
|
27
|
+
import { init, observe, flush } from '@lelemondev/sdk';
|
|
28
|
+
import OpenAI from 'openai';
|
|
27
29
|
|
|
28
|
-
// Initialize once at app startup
|
|
30
|
+
// 1. Initialize once at app startup
|
|
29
31
|
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
30
32
|
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
+
// 2. Wrap your client
|
|
34
|
+
const openai = observe(new OpenAI());
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
36
|
+
// 3. Use normally - all calls are traced automatically
|
|
37
|
+
const response = await openai.chat.completions.create({
|
|
38
|
+
model: 'gpt-4',
|
|
39
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
40
|
+
});
|
|
41
41
|
|
|
42
|
-
// For serverless: flush before response
|
|
42
|
+
// 4. For serverless: flush before response
|
|
43
43
|
await flush();
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
That's it! No manual tracing code needed.
|
|
47
|
+
|
|
48
|
+
## Supported Providers
|
|
49
|
+
|
|
50
|
+
| Provider | Status | Methods |
|
|
51
|
+
|----------|--------|---------|
|
|
52
|
+
| OpenAI | Supported | `chat.completions.create()`, `completions.create()`, `embeddings.create()` |
|
|
53
|
+
| Anthropic | Supported | `messages.create()`, `messages.stream()` |
|
|
54
|
+
|
|
46
55
|
## API Reference
|
|
47
56
|
|
|
48
57
|
### `init(config)`
|
|
@@ -54,58 +63,88 @@ init({
|
|
|
54
63
|
apiKey: 'le_xxx', // Required (or set LELEMON_API_KEY env var)
|
|
55
64
|
endpoint: 'https://...', // Optional, custom endpoint
|
|
56
65
|
debug: false, // Optional, enable debug logs
|
|
66
|
+
disabled: false, // Optional, disable all tracing
|
|
57
67
|
batchSize: 10, // Optional, items per batch
|
|
58
68
|
flushIntervalMs: 1000, // Optional, auto-flush interval
|
|
69
|
+
requestTimeoutMs: 10000, // Optional, HTTP request timeout
|
|
59
70
|
});
|
|
60
71
|
```
|
|
61
72
|
|
|
62
|
-
### `
|
|
73
|
+
### `observe(client, options?)`
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
Wrap an LLM client with automatic tracing. Returns the same client type.
|
|
65
76
|
|
|
66
77
|
```typescript
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
79
|
+
|
|
80
|
+
const anthropic = observe(new Anthropic(), {
|
|
69
81
|
sessionId: 'session-123', // Optional, group related traces
|
|
70
82
|
userId: 'user-456', // Optional, identify the user
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
tags: ['prod', 'v2'], // Optional, tags for filtering
|
|
83
|
+
metadata: { source: 'api' }, // Optional, custom metadata
|
|
84
|
+
tags: ['production'], // Optional, tags for filtering
|
|
74
85
|
});
|
|
75
86
|
```
|
|
76
87
|
|
|
77
|
-
### `
|
|
88
|
+
### `createObserve(defaultOptions)`
|
|
78
89
|
|
|
79
|
-
|
|
90
|
+
Create a scoped observe function with preset options.
|
|
80
91
|
|
|
81
92
|
```typescript
|
|
82
|
-
|
|
93
|
+
const observeWithSession = createObserve({
|
|
94
|
+
sessionId: 'session-123',
|
|
95
|
+
userId: 'user-456',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const openai = observeWithSession(new OpenAI());
|
|
99
|
+
const anthropic = observeWithSession(new Anthropic());
|
|
83
100
|
```
|
|
84
101
|
|
|
85
|
-
### `
|
|
102
|
+
### `flush()`
|
|
86
103
|
|
|
87
|
-
|
|
104
|
+
Wait for all pending traces to be sent. Use in serverless environments.
|
|
88
105
|
|
|
89
106
|
```typescript
|
|
90
|
-
|
|
91
|
-
t.error(error, partialMessages); // Include messages up to failure
|
|
107
|
+
await flush();
|
|
92
108
|
```
|
|
93
109
|
|
|
94
|
-
### `
|
|
110
|
+
### `isEnabled()`
|
|
95
111
|
|
|
96
|
-
|
|
112
|
+
Check if tracing is enabled.
|
|
97
113
|
|
|
98
114
|
```typescript
|
|
99
|
-
|
|
100
|
-
|
|
115
|
+
if (isEnabled()) {
|
|
116
|
+
console.log('Tracing is active');
|
|
117
|
+
}
|
|
101
118
|
```
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
## Streaming Support
|
|
104
121
|
|
|
105
|
-
|
|
122
|
+
Both OpenAI and Anthropic streaming are fully supported:
|
|
106
123
|
|
|
107
124
|
```typescript
|
|
108
|
-
|
|
125
|
+
// OpenAI streaming
|
|
126
|
+
const stream = await openai.chat.completions.create({
|
|
127
|
+
model: 'gpt-4',
|
|
128
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
129
|
+
stream: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
for await (const chunk of stream) {
|
|
133
|
+
process.stdout.write(chunk.choices[0]?.delta?.content || '');
|
|
134
|
+
}
|
|
135
|
+
// Trace is captured automatically when stream completes
|
|
136
|
+
|
|
137
|
+
// Anthropic streaming
|
|
138
|
+
const stream = anthropic.messages.stream({
|
|
139
|
+
model: 'claude-3-opus-20240229',
|
|
140
|
+
max_tokens: 1024,
|
|
141
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
for await (const event of stream) {
|
|
145
|
+
// Process events
|
|
146
|
+
}
|
|
147
|
+
// Trace is captured automatically
|
|
109
148
|
```
|
|
110
149
|
|
|
111
150
|
## Serverless Usage
|
|
@@ -114,53 +153,65 @@ await flush();
|
|
|
114
153
|
|
|
115
154
|
```typescript
|
|
116
155
|
import { waitUntil } from '@vercel/functions';
|
|
117
|
-
import {
|
|
156
|
+
import { init, observe, flush } from '@lelemondev/sdk';
|
|
157
|
+
import OpenAI from 'openai';
|
|
158
|
+
|
|
159
|
+
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
160
|
+
const openai = observe(new OpenAI());
|
|
118
161
|
|
|
119
162
|
export async function POST(req: Request) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
} finally {
|
|
130
|
-
waitUntil(flush()); // Flush after response
|
|
131
|
-
}
|
|
163
|
+
const { message } = await req.json();
|
|
164
|
+
|
|
165
|
+
const response = await openai.chat.completions.create({
|
|
166
|
+
model: 'gpt-4',
|
|
167
|
+
messages: [{ role: 'user', content: message }],
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
waitUntil(flush()); // Flush after response
|
|
171
|
+
return Response.json(response.choices[0].message);
|
|
132
172
|
}
|
|
133
173
|
```
|
|
134
174
|
|
|
135
175
|
### AWS Lambda
|
|
136
176
|
|
|
137
177
|
```typescript
|
|
138
|
-
import {
|
|
178
|
+
import { init, observe, flush } from '@lelemondev/sdk';
|
|
179
|
+
import OpenAI from 'openai';
|
|
180
|
+
|
|
181
|
+
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
182
|
+
const openai = observe(new OpenAI());
|
|
139
183
|
|
|
140
184
|
export const handler = async (event) => {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
t.error(error);
|
|
149
|
-
throw error;
|
|
150
|
-
} finally {
|
|
151
|
-
await flush(); // Always flush before Lambda ends
|
|
152
|
-
}
|
|
185
|
+
const response = await openai.chat.completions.create({
|
|
186
|
+
model: 'gpt-4',
|
|
187
|
+
messages: [{ role: 'user', content: event.body }],
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
await flush(); // Always flush before Lambda ends
|
|
191
|
+
return { statusCode: 200, body: JSON.stringify(response) };
|
|
153
192
|
};
|
|
154
193
|
```
|
|
155
194
|
|
|
156
|
-
##
|
|
195
|
+
## What Gets Traced
|
|
196
|
+
|
|
197
|
+
Each LLM call automatically captures:
|
|
198
|
+
|
|
199
|
+
- **Provider** - openai, anthropic
|
|
200
|
+
- **Model** - gpt-4, claude-3-opus, etc.
|
|
201
|
+
- **Input** - Messages/prompt (sanitized)
|
|
202
|
+
- **Output** - Response content
|
|
203
|
+
- **Tokens** - Input and output token counts
|
|
204
|
+
- **Duration** - Request latency in ms
|
|
205
|
+
- **Status** - success or error
|
|
206
|
+
- **Streaming** - Whether streaming was used
|
|
207
|
+
|
|
208
|
+
## Security
|
|
209
|
+
|
|
210
|
+
The SDK automatically sanitizes sensitive data:
|
|
157
211
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
| Anthropic | ✅ |
|
|
162
|
-
| Google Gemini | ✅ |
|
|
163
|
-
| AWS Bedrock | ✅ |
|
|
212
|
+
- API keys and tokens are redacted
|
|
213
|
+
- Large payloads are truncated
|
|
214
|
+
- Errors are captured without stack traces
|
|
164
215
|
|
|
165
216
|
## Environment Variables
|
|
166
217
|
|
|
@@ -170,4 +221,4 @@ export const handler = async (event) => {
|
|
|
170
221
|
|
|
171
222
|
## License
|
|
172
223
|
|
|
173
|
-
MIT
|
|
224
|
+
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -1,316 +1,88 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lelemon SDK
|
|
3
|
-
* Minimal, low-friction API for LLM observability
|
|
2
|
+
* Core types for Lelemon SDK
|
|
4
3
|
*/
|
|
5
4
|
interface LelemonConfig {
|
|
6
|
-
/**
|
|
7
|
-
* API key for authentication (starts with 'le_')
|
|
8
|
-
* Can also be set via LELEMON_API_KEY env var
|
|
9
|
-
*/
|
|
5
|
+
/** API key (or set LELEMON_API_KEY env var) */
|
|
10
6
|
apiKey?: string;
|
|
11
|
-
/**
|
|
12
|
-
* API endpoint (default: https://api.lelemon.dev)
|
|
13
|
-
*/
|
|
7
|
+
/** API endpoint (default: https://api.lelemon.dev) */
|
|
14
8
|
endpoint?: string;
|
|
15
|
-
/**
|
|
16
|
-
* Enable debug logging
|
|
17
|
-
*/
|
|
9
|
+
/** Enable debug logging */
|
|
18
10
|
debug?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Disable tracing (useful for testing)
|
|
21
|
-
*/
|
|
11
|
+
/** Disable tracing */
|
|
22
12
|
disabled?: boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Number of items to batch before sending (default: 10)
|
|
25
|
-
*/
|
|
13
|
+
/** Batch size before flush (default: 10) */
|
|
26
14
|
batchSize?: number;
|
|
27
|
-
/**
|
|
28
|
-
* Interval in ms to flush pending items (default: 1000)
|
|
29
|
-
*/
|
|
15
|
+
/** Auto-flush interval in ms (default: 1000) */
|
|
30
16
|
flushIntervalMs?: number;
|
|
31
|
-
/**
|
|
32
|
-
* Request timeout in ms (default: 10000)
|
|
33
|
-
*/
|
|
17
|
+
/** Request timeout in ms (default: 10000) */
|
|
34
18
|
requestTimeoutMs?: number;
|
|
35
19
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*/
|
|
40
|
-
input: unknown;
|
|
41
|
-
/**
|
|
42
|
-
* Session ID to group related traces
|
|
43
|
-
*/
|
|
20
|
+
type ProviderName = 'openai' | 'anthropic' | 'google' | 'bedrock' | 'unknown';
|
|
21
|
+
interface ObserveOptions {
|
|
22
|
+
/** Session ID to group related calls */
|
|
44
23
|
sessionId?: string;
|
|
45
|
-
/**
|
|
46
|
-
* User ID for the end user
|
|
47
|
-
*/
|
|
24
|
+
/** User ID for the end user */
|
|
48
25
|
userId?: string;
|
|
49
|
-
/**
|
|
50
|
-
* Custom metadata
|
|
51
|
-
*/
|
|
26
|
+
/** Custom metadata added to all traces */
|
|
52
27
|
metadata?: Record<string, unknown>;
|
|
53
|
-
/**
|
|
54
|
-
* Tags for filtering
|
|
55
|
-
*/
|
|
28
|
+
/** Tags for filtering */
|
|
56
29
|
tags?: string[];
|
|
57
|
-
/**
|
|
58
|
-
* Name for this trace (e.g., 'chat-agent', 'summarizer')
|
|
59
|
-
*/
|
|
60
|
-
name?: string;
|
|
61
|
-
}
|
|
62
|
-
interface OpenAIMessage {
|
|
63
|
-
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
64
|
-
content: string | null;
|
|
65
|
-
tool_calls?: OpenAIToolCall[];
|
|
66
|
-
tool_call_id?: string;
|
|
67
|
-
}
|
|
68
|
-
interface OpenAIToolCall {
|
|
69
|
-
id: string;
|
|
70
|
-
type: 'function';
|
|
71
|
-
function: {
|
|
72
|
-
name: string;
|
|
73
|
-
arguments: string;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
interface AnthropicMessage {
|
|
77
|
-
role: 'user' | 'assistant';
|
|
78
|
-
content: string | AnthropicContent[];
|
|
79
|
-
}
|
|
80
|
-
interface AnthropicContent {
|
|
81
|
-
type: 'text' | 'tool_use' | 'tool_result';
|
|
82
|
-
text?: string;
|
|
83
|
-
id?: string;
|
|
84
|
-
name?: string;
|
|
85
|
-
input?: unknown;
|
|
86
|
-
tool_use_id?: string;
|
|
87
|
-
content?: string;
|
|
88
|
-
}
|
|
89
|
-
type Message = OpenAIMessage | AnthropicMessage | Record<string, unknown>;
|
|
90
|
-
interface ParsedTrace {
|
|
91
|
-
systemPrompt?: string;
|
|
92
|
-
userInput?: string;
|
|
93
|
-
output?: string;
|
|
94
|
-
llmCalls: ParsedLLMCall[];
|
|
95
|
-
toolCalls: ParsedToolCall[];
|
|
96
|
-
totalInputTokens: number;
|
|
97
|
-
totalOutputTokens: number;
|
|
98
|
-
models: string[];
|
|
99
|
-
provider?: 'openai' | 'anthropic' | 'gemini' | 'bedrock' | 'unknown';
|
|
100
|
-
}
|
|
101
|
-
interface ParsedLLMCall {
|
|
102
|
-
model?: string;
|
|
103
|
-
provider?: string;
|
|
104
|
-
inputTokens?: number;
|
|
105
|
-
outputTokens?: number;
|
|
106
|
-
input?: unknown;
|
|
107
|
-
output?: unknown;
|
|
108
|
-
toolCalls?: ParsedToolCall[];
|
|
109
|
-
}
|
|
110
|
-
interface ParsedToolCall {
|
|
111
|
-
name: string;
|
|
112
|
-
input: unknown;
|
|
113
|
-
output?: unknown;
|
|
114
|
-
}
|
|
115
|
-
interface CreateTraceRequest {
|
|
116
|
-
name?: string;
|
|
117
|
-
sessionId?: string;
|
|
118
|
-
userId?: string;
|
|
119
|
-
input?: unknown;
|
|
120
|
-
metadata?: Record<string, unknown>;
|
|
121
|
-
tags?: string[];
|
|
122
|
-
}
|
|
123
|
-
interface CompleteTraceRequest {
|
|
124
|
-
status: 'completed' | 'error';
|
|
125
|
-
output?: unknown;
|
|
126
|
-
errorMessage?: string;
|
|
127
|
-
errorStack?: string;
|
|
128
|
-
systemPrompt?: string;
|
|
129
|
-
llmCalls?: ParsedLLMCall[];
|
|
130
|
-
toolCalls?: ParsedToolCall[];
|
|
131
|
-
models?: string[];
|
|
132
|
-
totalInputTokens?: number;
|
|
133
|
-
totalOutputTokens?: number;
|
|
134
|
-
totalCostUsd?: number;
|
|
135
|
-
durationMs?: number;
|
|
136
|
-
metadata?: Record<string, unknown>;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Transport layer with queue-based batching
|
|
141
|
-
*
|
|
142
|
-
* Features:
|
|
143
|
-
* - Fire-and-forget API (sync enqueue)
|
|
144
|
-
* - Automatic batching (by size or interval)
|
|
145
|
-
* - Single flush promise (no duplicate requests)
|
|
146
|
-
* - Graceful error handling (never crashes caller)
|
|
147
|
-
* - Request timeout protection
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
|
-
interface TransportConfig {
|
|
151
|
-
apiKey: string;
|
|
152
|
-
endpoint: string;
|
|
153
|
-
debug: boolean;
|
|
154
|
-
disabled: boolean;
|
|
155
|
-
batchSize?: number;
|
|
156
|
-
flushIntervalMs?: number;
|
|
157
|
-
requestTimeoutMs?: number;
|
|
158
|
-
}
|
|
159
|
-
declare class Transport {
|
|
160
|
-
private readonly config;
|
|
161
|
-
private queue;
|
|
162
|
-
private flushPromise;
|
|
163
|
-
private flushTimer;
|
|
164
|
-
private pendingResolvers;
|
|
165
|
-
private idCounter;
|
|
166
|
-
constructor(config: TransportConfig);
|
|
167
|
-
/**
|
|
168
|
-
* Check if transport is enabled
|
|
169
|
-
*/
|
|
170
|
-
isEnabled(): boolean;
|
|
171
|
-
/**
|
|
172
|
-
* Enqueue trace creation (returns promise that resolves to trace ID)
|
|
173
|
-
*/
|
|
174
|
-
enqueueCreate(data: CreateTraceRequest): Promise<string | null>;
|
|
175
|
-
/**
|
|
176
|
-
* Enqueue trace completion (fire-and-forget)
|
|
177
|
-
*/
|
|
178
|
-
enqueueComplete(traceId: string, data: CompleteTraceRequest): void;
|
|
179
|
-
/**
|
|
180
|
-
* Flush all pending items
|
|
181
|
-
* Safe to call multiple times (deduplicates)
|
|
182
|
-
*/
|
|
183
|
-
flush(): Promise<void>;
|
|
184
|
-
/**
|
|
185
|
-
* Get pending item count (for testing/debugging)
|
|
186
|
-
*/
|
|
187
|
-
getPendingCount(): number;
|
|
188
|
-
private generateTempId;
|
|
189
|
-
private enqueue;
|
|
190
|
-
private scheduleFlush;
|
|
191
|
-
private cancelScheduledFlush;
|
|
192
|
-
private sendBatch;
|
|
193
|
-
private request;
|
|
194
|
-
private log;
|
|
195
30
|
}
|
|
196
31
|
|
|
197
32
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* Usage:
|
|
201
|
-
* const t = trace({ input: userMessage });
|
|
202
|
-
* try {
|
|
203
|
-
* const result = await myAgent(userMessage);
|
|
204
|
-
* t.success(result.messages);
|
|
205
|
-
* } catch (error) {
|
|
206
|
-
* t.error(error);
|
|
207
|
-
* throw error;
|
|
208
|
-
* }
|
|
33
|
+
* Global Configuration
|
|
209
34
|
*
|
|
210
|
-
*
|
|
211
|
-
* await flush(); // Before response
|
|
35
|
+
* Manages SDK configuration and transport instance.
|
|
212
36
|
*/
|
|
213
37
|
|
|
214
38
|
/**
|
|
215
|
-
* Initialize the SDK
|
|
216
|
-
*
|
|
217
|
-
* @example
|
|
218
|
-
* init({ apiKey: 'le_xxx' });
|
|
219
|
-
* init({ apiKey: 'le_xxx', debug: true });
|
|
39
|
+
* Initialize the SDK
|
|
40
|
+
* Call once at app startup
|
|
220
41
|
*/
|
|
221
42
|
declare function init(config?: LelemonConfig): void;
|
|
222
|
-
/**
|
|
223
|
-
* Start a new trace
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* const t = trace({ input: userMessage });
|
|
227
|
-
* try {
|
|
228
|
-
* const result = await myAgent(userMessage);
|
|
229
|
-
* t.success(result.messages);
|
|
230
|
-
* } catch (error) {
|
|
231
|
-
* t.error(error);
|
|
232
|
-
* throw error;
|
|
233
|
-
* }
|
|
234
|
-
*/
|
|
235
|
-
declare function trace(options: TraceOptions): Trace;
|
|
236
|
-
/**
|
|
237
|
-
* Flush all pending traces to the server
|
|
238
|
-
* Call this before process exit in serverless environments
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* // In Next.js API route
|
|
242
|
-
* export async function POST(req: Request) {
|
|
243
|
-
* // ... your code with traces ...
|
|
244
|
-
* await flush();
|
|
245
|
-
* return Response.json(result);
|
|
246
|
-
* }
|
|
247
|
-
*
|
|
248
|
-
* // With Vercel waitUntil
|
|
249
|
-
* import { waitUntil } from '@vercel/functions';
|
|
250
|
-
* waitUntil(flush());
|
|
251
|
-
*/
|
|
252
|
-
declare function flush(): Promise<void>;
|
|
253
43
|
/**
|
|
254
44
|
* Check if SDK is enabled
|
|
255
45
|
*/
|
|
256
46
|
declare function isEnabled(): boolean;
|
|
257
|
-
declare class Trace {
|
|
258
|
-
private id;
|
|
259
|
-
private idPromise;
|
|
260
|
-
private readonly transport;
|
|
261
|
-
private readonly startTime;
|
|
262
|
-
private readonly debug;
|
|
263
|
-
private readonly disabled;
|
|
264
|
-
private completed;
|
|
265
|
-
private llmCalls;
|
|
266
|
-
constructor(options: TraceOptions, transport: Transport, debug: boolean, disabled: boolean);
|
|
267
|
-
/**
|
|
268
|
-
* Log an LLM response for token tracking
|
|
269
|
-
* Optional - use if you want per-call token counts
|
|
270
|
-
*/
|
|
271
|
-
log(response: unknown): this;
|
|
272
|
-
/**
|
|
273
|
-
* Complete trace successfully (fire-and-forget)
|
|
274
|
-
*
|
|
275
|
-
* @param messages - Full message history (OpenAI/Anthropic format)
|
|
276
|
-
*/
|
|
277
|
-
success(messages: unknown): void;
|
|
278
|
-
/**
|
|
279
|
-
* Complete trace with error (fire-and-forget)
|
|
280
|
-
*
|
|
281
|
-
* @param error - The error that occurred
|
|
282
|
-
* @param messages - Optional message history up to failure
|
|
283
|
-
*/
|
|
284
|
-
error(error: Error | unknown, messages?: unknown): void;
|
|
285
|
-
/**
|
|
286
|
-
* Get the trace ID (may be null if not yet created or failed)
|
|
287
|
-
*/
|
|
288
|
-
getId(): string | null;
|
|
289
|
-
/**
|
|
290
|
-
* Wait for trace ID to be available
|
|
291
|
-
*/
|
|
292
|
-
waitForId(): Promise<string | null>;
|
|
293
|
-
private aggregateCalls;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
47
|
/**
|
|
297
|
-
*
|
|
298
|
-
* Auto-detects OpenAI/Anthropic/Gemini message formats and extracts relevant data
|
|
48
|
+
* Flush all pending traces
|
|
299
49
|
*/
|
|
50
|
+
declare function flush(): Promise<void>;
|
|
300
51
|
|
|
301
52
|
/**
|
|
302
|
-
*
|
|
53
|
+
* Observe Function
|
|
54
|
+
*
|
|
55
|
+
* Main entry point for wrapping LLM clients with automatic tracing.
|
|
303
56
|
*/
|
|
304
|
-
|
|
57
|
+
|
|
305
58
|
/**
|
|
306
|
-
*
|
|
307
|
-
*
|
|
59
|
+
* Wrap an LLM client with automatic tracing
|
|
60
|
+
*
|
|
61
|
+
* @param client - OpenAI or Anthropic client instance
|
|
62
|
+
* @param options - Optional context (sessionId, userId, etc.)
|
|
63
|
+
* @returns The wrapped client with the same type
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* import { observe } from '@lelemondev/sdk';
|
|
67
|
+
* import OpenAI from 'openai';
|
|
68
|
+
*
|
|
69
|
+
* const openai = observe(new OpenAI());
|
|
70
|
+
*
|
|
71
|
+
* // All calls are now automatically traced
|
|
72
|
+
* const response = await openai.chat.completions.create({...});
|
|
308
73
|
*/
|
|
309
|
-
declare function
|
|
74
|
+
declare function observe<T>(client: T, options?: ObserveOptions): T;
|
|
310
75
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
76
|
+
* Create a scoped observe function with preset context
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const observeWithSession = createObserve({
|
|
80
|
+
* sessionId: 'session-123',
|
|
81
|
+
* userId: 'user-456',
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* const openai = observeWithSession(new OpenAI());
|
|
313
85
|
*/
|
|
314
|
-
declare function
|
|
86
|
+
declare function createObserve(defaultOptions: ObserveOptions): <T>(client: T, options?: ObserveOptions) => T;
|
|
315
87
|
|
|
316
|
-
export { type
|
|
88
|
+
export { type LelemonConfig, type ObserveOptions, type ProviderName, createObserve, flush, init, isEnabled, observe };
|