@lelemondev/sdk 0.10.0 → 0.10.1
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 +170 -4
- package/dist/anthropic.d.mts +2 -2
- package/dist/anthropic.d.ts +2 -2
- package/dist/anthropic.js +2 -2
- package/dist/anthropic.mjs +2 -2
- package/dist/bedrock.d.mts +2 -2
- package/dist/bedrock.d.ts +2 -2
- package/dist/bedrock.js +1 -1
- package/dist/bedrock.mjs +1 -1
- package/dist/{capture-CiUL-4hv.d.mts → capture-DOj4Z9MB.d.mts} +16 -1
- package/dist/{capture-CiUL-4hv.d.ts → capture-DOj4Z9MB.d.ts} +16 -1
- package/dist/gemini.d.mts +2 -2
- package/dist/gemini.d.ts +2 -2
- package/dist/gemini.js +1 -1
- package/dist/gemini.mjs +1 -1
- package/dist/google-genai.d.mts +2 -2
- package/dist/google-genai.d.ts +2 -2
- package/dist/google-genai.js +1 -1
- package/dist/google-genai.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/openai.d.mts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +1 -1
- package/dist/openai.mjs +1 -1
- package/dist/openrouter.d.mts +2 -2
- package/dist/openrouter.d.ts +2 -2
- package/dist/openrouter.js +2 -2
- package/dist/openrouter.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,23 +31,189 @@ npm install @lelemondev/sdk
|
|
|
31
31
|
## Quick Start
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
// Import from provider-specific entry point for smaller bundle size
|
|
35
34
|
import { init, observe } from '@lelemondev/sdk/openai';
|
|
36
35
|
import OpenAI from 'openai';
|
|
37
36
|
|
|
38
|
-
// 1. Initialize once
|
|
39
37
|
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
40
38
|
|
|
41
|
-
// 2. Wrap your client
|
|
42
39
|
const openai = observe(new OpenAI());
|
|
43
40
|
|
|
44
|
-
// 3. Use normally - all calls traced automatically
|
|
45
41
|
const response = await openai.chat.completions.create({
|
|
46
42
|
model: 'gpt-4',
|
|
47
43
|
messages: [{ role: 'user', content: 'Hello!' }],
|
|
48
44
|
});
|
|
49
45
|
```
|
|
50
46
|
|
|
47
|
+
That's the bare minimum — it works, but your traces will be flat and anonymous. The next section shows you how to get **structured, beautiful traces** in your dashboard from day one.
|
|
48
|
+
|
|
49
|
+
## Recommended Usage
|
|
50
|
+
|
|
51
|
+
The difference between messy traces and clear, actionable ones comes down to three things: **naming your traces**, **identifying users and sessions**, and **grouping related calls together**.
|
|
52
|
+
|
|
53
|
+
### 1. Wrap your workflow with `trace()`
|
|
54
|
+
|
|
55
|
+
Without `trace()`, each LLM call shows up as an isolated entry. With it, you get a hierarchical view that shows exactly what happened and why.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { init, observe, trace, span, flush } from '@lelemondev/sdk/openai';
|
|
59
|
+
import OpenAI from 'openai';
|
|
60
|
+
|
|
61
|
+
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
62
|
+
const openai = observe(new OpenAI());
|
|
63
|
+
|
|
64
|
+
// ✅ Named trace groups everything into a clear hierarchy
|
|
65
|
+
const result = await trace('answer-question', async () => {
|
|
66
|
+
// This LLM call appears as a child span — you can see it nested
|
|
67
|
+
const response = await openai.chat.completions.create({
|
|
68
|
+
model: 'gpt-4',
|
|
69
|
+
messages: [{ role: 'user', content: 'What is observability?' }],
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return response.choices[0].message.content;
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**In the dashboard, this renders as:**
|
|
77
|
+
```
|
|
78
|
+
▼ answer-question (trace) 1.2s $0.003
|
|
79
|
+
▼ gpt-4 (llm) 1.2s $0.003 320 tokens
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Without `trace()`, you'd just see a flat `gpt-4` entry with no context.
|
|
83
|
+
|
|
84
|
+
### 2. Add `userId` and `sessionId`
|
|
85
|
+
|
|
86
|
+
These two fields unlock filtering, conversation grouping, and per-user analytics in the dashboard.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// ✅ Always pass userId and sessionId — this is what makes the dashboard useful
|
|
90
|
+
const openai = observe(new OpenAI(), {
|
|
91
|
+
userId: 'user-123', // Who is making this request
|
|
92
|
+
sessionId: 'conversation-abc', // Groups multi-turn conversations together
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **`userId`** → Filter traces by user, track costs per user, debug specific user issues
|
|
97
|
+
- **`sessionId`** → See an entire conversation across multiple requests as one session
|
|
98
|
+
|
|
99
|
+
### 3. Add spans for non-LLM operations
|
|
100
|
+
|
|
101
|
+
LLM calls are traced automatically, but your pipeline probably does more: vector search, tool calls, reranking, guardrails. Use `span()` to capture these so the full picture shows up in the dashboard.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { trace, span } from '@lelemondev/sdk/openai';
|
|
105
|
+
|
|
106
|
+
await trace('rag-pipeline', async () => {
|
|
107
|
+
// Capture vector search as a retrieval span
|
|
108
|
+
const t0 = Date.now();
|
|
109
|
+
const docs = await vectorDB.search(query, { topK: 5 });
|
|
110
|
+
span({
|
|
111
|
+
type: 'retrieval', // Shows with a blue badge in dashboard
|
|
112
|
+
name: 'vector-search', // Descriptive name — not "search" or "step-1"
|
|
113
|
+
input: { query, topK: 5 },
|
|
114
|
+
output: { count: docs.length },
|
|
115
|
+
durationMs: Date.now() - t0,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// LLM call is captured automatically as a child
|
|
119
|
+
const response = await openai.chat.completions.create({
|
|
120
|
+
model: 'gpt-4',
|
|
121
|
+
messages: [
|
|
122
|
+
{ role: 'system', content: 'Answer based on the provided context.' },
|
|
123
|
+
{ role: 'user', content: `Context: ${docs.join('\n')}\n\nQuestion: ${query}` },
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return response.choices[0].message.content;
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**In the dashboard:**
|
|
132
|
+
```
|
|
133
|
+
▼ rag-pipeline (trace) 2.4s $0.005
|
|
134
|
+
▼ vector-search (retrieval) 0.3s
|
|
135
|
+
▼ gpt-4 (llm) 2.1s $0.005 580 tokens
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Available span types:** `retrieval`, `embedding`, `tool`, `guardrail`, `rerank`, `custom`
|
|
139
|
+
|
|
140
|
+
### 4. Use descriptive names
|
|
141
|
+
|
|
142
|
+
Names are the first thing you see in the dashboard. Good names make traces scannable; bad names make them useless.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// ❌ Bad — these all look the same in the dashboard
|
|
146
|
+
await trace('process', async () => { ... });
|
|
147
|
+
await trace('handle', async () => { ... });
|
|
148
|
+
span({ type: 'tool', name: 'function' });
|
|
149
|
+
|
|
150
|
+
// ✅ Good — you can immediately understand what happened
|
|
151
|
+
await trace('sales-agent', async () => { ... });
|
|
152
|
+
await trace('summarize-document', async () => { ... });
|
|
153
|
+
span({ type: 'tool', name: 'get-weather-forecast' });
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Full example: AI agent with everything wired up
|
|
157
|
+
|
|
158
|
+
Here's a complete example combining all the best practices — this is what we recommend as the starting point for any production app:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { init, observe, trace, span, flush } from '@lelemondev/sdk/openai';
|
|
162
|
+
import OpenAI from 'openai';
|
|
163
|
+
|
|
164
|
+
// 1. Initialize once at app startup
|
|
165
|
+
init({ apiKey: process.env.LELEMON_API_KEY });
|
|
166
|
+
|
|
167
|
+
async function handleChat(userId: string, sessionId: string, message: string) {
|
|
168
|
+
// 2. Wrap client with user context
|
|
169
|
+
const openai = observe(new OpenAI(), { userId, sessionId });
|
|
170
|
+
|
|
171
|
+
// 3. Wrap the full workflow in a named trace
|
|
172
|
+
const result = await trace('customer-support-agent', async () => {
|
|
173
|
+
// 4. Capture non-LLM operations as typed spans
|
|
174
|
+
const t0 = Date.now();
|
|
175
|
+
const history = await db.getChatHistory(sessionId);
|
|
176
|
+
span({
|
|
177
|
+
type: 'retrieval',
|
|
178
|
+
name: 'load-chat-history',
|
|
179
|
+
input: { sessionId },
|
|
180
|
+
output: { messageCount: history.length },
|
|
181
|
+
durationMs: Date.now() - t0,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// 5. LLM call is automatically captured as a child span
|
|
185
|
+
const response = await openai.chat.completions.create({
|
|
186
|
+
model: 'gpt-4',
|
|
187
|
+
messages: [
|
|
188
|
+
{ role: 'system', content: 'You are a helpful customer support agent.' },
|
|
189
|
+
...history,
|
|
190
|
+
{ role: 'user', content: message },
|
|
191
|
+
],
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return response.choices[0].message.content;
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// In your server:
|
|
201
|
+
app.post('/chat', async (req, res) => {
|
|
202
|
+
const { message, conversationId } = req.body;
|
|
203
|
+
const answer = await handleChat(req.user.id, conversationId, message);
|
|
204
|
+
res.json({ answer });
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**In the dashboard, each request renders as:**
|
|
209
|
+
```
|
|
210
|
+
▼ customer-support-agent (trace) 1.8s $0.004 user: user-123 session: conv-abc
|
|
211
|
+
▼ load-chat-history (retrieval) 0.1s
|
|
212
|
+
▼ gpt-4 (llm) 1.7s $0.004 420 tokens
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
And because you set `sessionId`, all turns of the same conversation are grouped together — you can click into a session and see the entire conversation flow.
|
|
216
|
+
|
|
51
217
|
### Provider-Specific Imports
|
|
52
218
|
|
|
53
219
|
Each provider has its own entry point for optimal bundle size:
|
package/dist/anthropic.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-DOj4Z9MB.mjs';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-DOj4Z9MB.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Anthropic Provider Entry Point
|
package/dist/anthropic.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-DOj4Z9MB.js';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-DOj4Z9MB.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Anthropic Provider Entry Point
|
package/dist/anthropic.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('async_hooks');/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var z=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ge=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Q=ge((nt,he)=>{he.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var F=false;function G(e){F=e;}function y(){return F?true:fe("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function g(e,t){y()&&$("debug",e,t);}function O(e,t){y()&&$("info",e,t);}function E(e,t){$("warn",e,t);}function q(e,t,n,r){y()&&console.log(`${f} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function C(e,t){console.error(`${f} Failed to capture trace: provider=${e} error=${t.message}`);}function V(e){y()&&console.log(`${f} Wrapped client: provider=${e}`);}function H(e,t){y()&&console.log(`${f} Sending batch: count=${e} endpoint=${t}`);}function W(e,t){y()&&console.log(`${f} Batch sent successfully: count=${e} duration=${t}ms`);}function Y(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${f} Batch send failed: count=${e} error=${n}`);}function X(e,t,n){y()&&console.log(`${f} Request: ${e} ${t} (${n} bytes)`);}function Z(e,t){y()&&console.log(`${f} Response: status=${e} duration=${t}ms`);}function $(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${f} ${t}`,n):r(`${f} ${t}`);}function fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,ye=1e3,be=1e4,M=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??me,flushIntervalMs:t.flushIntervalMs??ye,requestTimeoutMs:t.requestTimeoutMs??be};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();H(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),W(t.length,Date.now()-n);}catch(r){Y(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,a=new AbortController,u=r?JSON.stringify(r):void 0;X(t,o,u?.length??0);let c=setTimeout(()=>{a.abort();},this.config.requestTimeoutMs),d=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:u,signal:a.signal});if(clearTimeout(c),Z(s.status,Date.now()-d),!s.ok){let i=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${i}`)}let l=await s.text();return l?JSON.parse(l):{}}catch(s){throw clearTimeout(c),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var ke="@lelemondev/sdk",we="nodejs";function Te(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function xe(){try{if(typeof z<"u")return Q().version??"unknown"}catch{}return "unknown"}var v=null;function te(e){if(!v){let n=Te(),r=ve();v={"telemetry.sdk.name":ke,"telemetry.sdk.version":xe(),"telemetry.sdk.language":we},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var K={},k=null,P=null,ne="https://api.lelemon.dev";function Se(e={}){K=e,e.debug&&G(true),P=te(e.service),O("Initializing SDK",{endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??false,telemetry:P}),k=re(e),k.isEnabled()?O("SDK initialized - tracing enabled"):g("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function R(){return K}function A(){return P}function _e(){return w().isEnabled()}function w(){return k||(k=re(K)),k}async function Ee(){k&&await k.flush();}function re(e){let t=e.apiKey??Ce("LELEMON_API_KEY");return !t&&!e.disabled&&E("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ce(e){if(typeof process<"u"&&process.env)return process.env[e]}var N=Symbol.for("@lelemondev/sdk:globalContext");function ie(){let e=globalThis;return e[N]||(e[N]={context:{}}),e[N]}function ae(e){ie().context=e,g("Global context updated",e);}function S(){return ie().context}function D(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping trace capture");return}let n=S(),r=m(),o=x(),a=A(),u={provider:e.provider,model:e.model,input:U(e.input),rawResponse:e.rawResponse?I(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...a?{_telemetry:a}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(u),o}catch(t){C(e.provider,t instanceof Error?t:new Error(String(t)));return}}function _(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping error capture");return}let n=S(),r=m(),o=A(),a={provider:e.provider,model:e.model,input:U(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:x(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),g("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(a);}catch(t){C(e.provider,t instanceof Error?t:new Error(String(t)));}}function L(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping span capture");return}let n=S(),r=m(),o=e.metadata?._traceId,a=e.metadata?._parentSpanId,u=A(),c={...n.metadata,...e.metadata,...u?{_telemetry:u}:{}};delete c._traceId,delete c._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:U(e.input),output:I(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:x(),parentSpanId:a??r?.currentSpanId,toolCallId:e.toolCallId,metadata:c,tags:n.tags};g(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){C("unknown",t instanceof Error?t:new Error(String(t)));}}var oe=1e5,Me=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Ae=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],se={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ue(){return R().redaction??{}}function De(e){let t=e.toLowerCase();return Ae.includes(t)?false:!!(Me.some(r=>t.includes(r))||Re.some(r=>t.includes(r))||(ue().keys??[]).some(r=>t.includes(r.toLowerCase())))}function je(e){let t=ue(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(se.emails,"[EMAIL]")),t.phones&&(n=n.replace(se.phones,"[PHONE]")),n}function U(e){return I(e,0)}function I(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=je(e);return n.length>oe&&(n=n.slice(0,oe)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>I(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))De(r)?n[r]="[REDACTED]":n[r]=I(o,t+1);return n}return String(e)}var B=Symbol.for("@lelemondev/sdk:traceStorage");function qe(){let e=globalThis;return e[B]||(e[B]=new async_hooks.AsyncLocalStorage),e[B]}var ce=qe();function x(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ce.getStore()}function j(e,t){let n=m();if(n)for(let r of e)n.pendingToolCalls.set(r,t),g(`Registered tool call ${r} \u2192 LLM span ${t}`);}function $e(e){let t=m();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Pe(e){let t=m();t&&t.pendingToolCalls.delete(e);}async function Ke(e,t){let n=typeof e=="string"?{name:e}:e,r=m(),o=r?.traceId??x(),a=x(),u={traceId:o,rootSpanId:a,currentSpanId:a,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ce.run(u,async()=>{let c,d;try{return c=await t(),c}catch(s){throw d=s instanceof Error?s:new Error(String(s)),s}finally{Ue(u,d?void 0:c,d);}})}var Ne=["text","content","message","output","response","result","answer"];function Le(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Ne)if(o in r&&typeof r[o]=="string")return r[o];return e}function Ue(e,t,n){let r=w();if(!r.isEnabled()){g("Transport disabled, skipping root span");return}let o=S(),a=Date.now()-e.startTime,u=n?null:Le(t,e.outputKey,e.outputTransform),c={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:u,inputTokens:0,outputTokens:0,durationMs:a,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};g(`Sending root span: ${e.name}`,{durationMs:a,hasError:!!n}),r.enqueue(c);}function Be(e){let t=m();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=$e(e.toolCallId);L({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Pe(e.toolCallId);}var T="anthropic";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="Anthropic")return true;let n=e;return !!(n.messages&&typeof n.messages=="object")}function le(e){return async function(...n){let r=Date.now(),o=n[0]||{},a=o.stream===true;try{let u=await e(...n);if(a&&Je(u))return Fe(u,o,r);let c=Date.now()-r,d=u,s=D({provider:T,model:o.model||d.model||"unknown",input:{system:o.system,messages:o.messages},rawResponse:u,durationMs:c,status:"success",streaming:!1});if(s&&d.content){let l=J(d.content);l.length>0&&j(l,s);}return u}catch(u){let c=Date.now()-r;throw _({provider:T,model:o.model||"unknown",input:{system:o.system,messages:o.messages},error:u instanceof Error?u:new Error(String(u)),durationMs:c,streaming:a}),u}}}function pe(e){return function(...n){let r=Date.now(),o=n[0]||{};try{let a=e(...n);return a&&typeof a=="object"?ze(a,o,r):a}catch(a){let u=Date.now()-r;throw _({provider:T,model:o.model||"unknown",input:{system:o.system,messages:o.messages},error:a instanceof Error?a:new Error(String(a)),durationMs:u,streaming:true}),a}}}function Je(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}function ze(e,t,n){let r=e;if(!r[Symbol.asyncIterator])return e;let o={content:[],usage:{input_tokens:0,output_tokens:0}},a=false,u,c=false,d=null,s=[],l=async function*(){try{for await(let i of r){if(i.type==="message_start"&&i.message&&(o.model=i.message.model,o.id=i.message.id,o.role=i.message.role,i.message.usage&&(o.usage={...i.message.usage})),i.type==="content_block_start"&&i.content_block&&(d=i.index??s.length,s[d]={...i.content_block},i.content_block.type==="text"&&(s[d].text=""),i.content_block.type==="thinking"&&(s[d].thinking="")),i.type==="content_block_delta"&&i.delta&&d!==null){let p=s[d];p&&(i.delta.text&&(c||(c=!0,u=Date.now()-n),p.type==="thinking"?p.thinking=(p.thinking||"")+i.delta.text:p.type==="text"&&(p.text=(p.text||"")+i.delta.text)),i.delta.partial_json&&p.type==="tool_use"&&(p._inputJson=(p._inputJson||"")+i.delta.partial_json));}if(i.type==="content_block_stop"&&d!==null){let p=s[d];if(p&&p.type==="tool_use"){let b=p._inputJson;if(b){try{p.input=JSON.parse(b);}catch{}delete p._inputJson;}}d=null;}i.type==="message_delta"&&(i.usage?.output_tokens&&(o.usage.output_tokens=i.usage.output_tokens),i.delta?.stop_reason&&(o.stop_reason=i.delta.stop_reason)),yield i;}}catch(i){if(!a){a=true;let p=Date.now()-n;_({provider:T,model:o.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:i instanceof Error?i:new Error(String(i)),durationMs:p,streaming:true});}throw i}finally{if(!a){a=true;let i=Date.now()-n;o.content=s.filter(Boolean);let p=D({provider:T,model:o.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:o,durationMs:i,status:"success",streaming:true,firstTokenMs:u});if(p&&o.content){let b=J(o.content);b.length>0&&j(b,p);}}}};return new Proxy(e,{get(i,p,b){return p===Symbol.asyncIterator?()=>l()[Symbol.asyncIterator]():Reflect.get(i,p,b)}})}async function*Fe(e,t,n){let r={content:[],usage:{input_tokens:0,output_tokens:0}},o=null,a,u=false,c=null,d=[];try{for await(let s of e){if(s.type==="message_start"&&s.message&&(r.model=s.message.model,r.id=s.message.id,r.role=s.message.role,s.message.usage&&(r.usage={...s.message.usage})),s.type==="content_block_start"&&s.content_block&&(c=s.index??d.length,d[c]={...s.content_block},s.content_block.type==="text"&&(d[c].text=""),s.content_block.type==="thinking"&&(d[c].thinking="")),s.type==="content_block_delta"&&s.delta&&c!==null){let l=d[c];l&&(s.delta.text&&(u||(u=!0,a=Date.now()-n),l.type==="thinking"?l.thinking=(l.thinking||"")+s.delta.text:l.type==="text"&&(l.text=(l.text||"")+s.delta.text)),s.delta.partial_json&&l.type==="tool_use"&&(l._inputJson=(l._inputJson||"")+s.delta.partial_json));}if(s.type==="content_block_stop"&&c!==null){let l=d[c];if(l&&l.type==="tool_use"){let i=l._inputJson;if(i){try{l.input=JSON.parse(i);}catch{}delete l._inputJson;}}c=null;}s.type==="message_delta"&&(s.usage?.output_tokens&&(r.usage.output_tokens=s.usage.output_tokens),s.delta?.stop_reason&&(r.stop_reason=s.delta.stop_reason)),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n;if(r.content=d.filter(Boolean),o)_({provider:T,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let l=D({provider:T,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:a});if(l&&r.content){let i=J(r.content);i.length>0&&j(i,l);}}}}function J(e){let t=[];for(let n of e)n.type==="tool_use"&&n.id&&t.push(n.id);return t}function Mt(e,t){return t&&ae(t),R().disabled?(g("Tracing disabled, returning unwrapped client"),e):de(e)?(V("anthropic"),Ve(e)):(E("Client is not an Anthropic client. Use @lelemondev/sdk/anthropic only with Anthropic SDK."),e)}function Ve(e){let t=e;return new Proxy(t,{get(n,r,o){let a=Reflect.get(n,r,o);return r==="messages"&&a&&typeof a=="object"?He(a):a}})}function He(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?le(o.bind(t)):n==="stream"&&typeof o=="function"?pe(o.bind(t)):o}})}
|
|
3
|
-
exports.captureSpan=L;exports.flush=Ee;exports.getTraceContext=m;exports.init=
|
|
2
|
+
var z=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ge=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Q=ge((nt,he)=>{he.exports={name:"@lelemondev/sdk",version:"0.10.1",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var F=false;function G(e){F=e;}function y(){return F?true:fe("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function g(e,t){y()&&$("debug",e,t);}function j(e,t){y()&&$("info",e,t);}function E(e,t){$("warn",e,t);}function q(e,t,n,r){y()&&console.log(`${f} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function C(e,t){console.error(`${f} Failed to capture trace: provider=${e} error=${t.message}`);}function V(e){y()&&console.log(`${f} Wrapped client: provider=${e}`);}function H(e,t){y()&&console.log(`${f} Sending batch: count=${e} endpoint=${t}`);}function W(e,t){y()&&console.log(`${f} Batch sent successfully: count=${e} duration=${t}ms`);}function Y(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${f} Batch send failed: count=${e} error=${n}`);}function X(e,t,n){y()&&console.log(`${f} Request: ${e} ${t} (${n} bytes)`);}function Z(e,t){y()&&console.log(`${f} Response: status=${e} duration=${t}ms`);}function $(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${f} ${t}`,n):r(`${f} ${t}`);}function fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,ye=1e3,be=1e4,M=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??me,flushIntervalMs:t.flushIntervalMs??ye,requestTimeoutMs:t.requestTimeoutMs??be};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();H(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),W(t.length,Date.now()-n);}catch(r){Y(t.length,r);}}async request(t,n,r){let s=`${this.config.endpoint}${n}`,a=new AbortController,u=r?JSON.stringify(r):void 0;X(t,s,u?.length??0);let c=setTimeout(()=>{a.abort();},this.config.requestTimeoutMs),d=Date.now();try{let o=await fetch(s,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:u,signal:a.signal});if(clearTimeout(c),Z(o.status,Date.now()-d),!o.ok){let i=await o.text().catch(()=>"Unknown error");throw new Error(`HTTP ${o.status}: ${i}`)}let l=await o.text();return l?JSON.parse(l):{}}catch(o){throw clearTimeout(c),o instanceof Error&&o.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):o}}};var ke="@lelemondev/sdk",we="nodejs";function Te(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Se(){try{if(typeof z<"u")return Q().version??"unknown"}catch{}return "unknown"}var v=null;function te(e){if(!v){let n=Te(),r=ve();v={"telemetry.sdk.name":ke,"telemetry.sdk.version":Se(),"telemetry.sdk.language":we},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var K={},k=null,P=null,ne="https://api.lelemon.dev";function Ie(e={}){K=e,e.debug&&G(true),P=te(e.service),j("Initializing SDK",{endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??false,telemetry:P}),k=re(e),k.isEnabled()?j("SDK initialized - tracing enabled"):g("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function R(){return K}function A(){return P}function _e(){return w().isEnabled()}function w(){return k||(k=re(K)),k}async function Ee(){k&&await k.flush();}function re(e){let t=e.apiKey??Ce("LELEMON_API_KEY");return !t&&!e.disabled&&E("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ce(e){if(typeof process<"u"&&process.env)return process.env[e]}var N=Symbol.for("@lelemondev/sdk:globalContext");function ie(){let e=globalThis;return e[N]||(e[N]={context:{}}),e[N]}function ae(e){ie().context=e,g("Global context updated",e);}function I(){return ie().context}function D(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping trace capture");return}let n=I(),r=m(),s=S(),a=A(),u={provider:e.provider,model:e.model,input:U(e.input),rawResponse:e.rawResponse?x(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:s,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...a?{_telemetry:a}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(u),s}catch(t){C(e.provider,t instanceof Error?t:new Error(String(t)));return}}function _(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping error capture");return}let n=I(),r=m(),s=A(),a={provider:e.provider,model:e.model,input:U(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:S(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),g("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(a);}catch(t){C(e.provider,t instanceof Error?t:new Error(String(t)));}}function L(e){try{let t=w();if(!t.isEnabled()){g("Transport disabled, skipping span capture");return}let n=I(),r=m(),s=e.metadata?._traceId,a=e.metadata?._parentSpanId,u=A(),c={...n.metadata,...e.metadata,...u?{_telemetry:u}:{}};delete c._traceId,delete c._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:U(e.input),output:x(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:s??r?.traceId,spanId:S(),parentSpanId:a??r?.currentSpanId,toolCallId:e.toolCallId,metadata:c,tags:n.tags};g(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){C("unknown",t instanceof Error?t:new Error(String(t)));}}var se=1e5,Me=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Ae=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],oe={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ue(){return R().redaction??{}}function De(e){let t=e.toLowerCase();return Ae.includes(t)?false:!!(Me.some(r=>t.includes(r))||Re.some(r=>t.includes(r))||(ue().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Oe(e){let t=ue(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(oe.emails,"[EMAIL]")),t.phones&&(n=n.replace(oe.phones,"[PHONE]")),n}function U(e){return x(e,0)}function x(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=Oe(e);return n.length>se&&(n=n.slice(0,se)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>x(n,t+1));if(typeof e=="object"){let n={};for(let[r,s]of Object.entries(e))De(r)?n[r]="[REDACTED]":n[r]=x(s,t+1);return n}return String(e)}var B=Symbol.for("@lelemondev/sdk:traceStorage");function qe(){let e=globalThis;return e[B]||(e[B]=new async_hooks.AsyncLocalStorage),e[B]}var ce=qe();function S(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ce.getStore()}function O(e,t){let n=m();if(n)for(let r of e)n.pendingToolCalls.set(r,t),g(`Registered tool call ${r} \u2192 LLM span ${t}`);}function $e(e){let t=m();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Pe(e){let t=m();t&&t.pendingToolCalls.delete(e);}async function Ke(e,t){let n=typeof e=="string"?{name:e}:e,r=m(),s=r?.traceId??S(),a=S(),u={traceId:s,rootSpanId:a,currentSpanId:a,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,style:n.style,pendingToolCalls:new Map};return ce.run(u,async()=>{let c,d;try{return c=await t(),c}catch(o){throw d=o instanceof Error?o:new Error(String(o)),o}finally{Ue(u,d?void 0:c,d);}})}var Ne=["text","content","message","output","response","result","answer"];function Le(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let s=e;return t in s?s[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let s of Ne)if(s in r&&typeof r[s]=="string")return r[s];return e}function Ue(e,t,n){let r=w();if(!r.isEnabled()){g("Transport disabled, skipping root span");return}let s=I(),a=Date.now()-e.startTime,u=n?null:Le(t,e.outputKey,e.outputTransform),c={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:u,inputTokens:0,outputTokens:0,durationMs:a,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??s.sessionId,userId:e.userId??s.userId,metadata:{...s.metadata,...e.metadata,...e.style?{_style:e.style}:{}},tags:e.tags??s.tags};g(`Sending root span: ${e.name}`,{durationMs:a,hasError:!!n}),r.enqueue(c);}function Be(e){let t=m();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=$e(e.toolCallId);L({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n,...e.style?{_style:e.style}:{}}}),e.toolCallId&&Pe(e.toolCallId);}var T="anthropic";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="Anthropic")return true;let n=e;return !!(n.messages&&typeof n.messages=="object")}function le(e){return async function(...n){let r=Date.now(),s=n[0]||{},a=s.stream===true;try{let u=await e(...n);if(a&&Je(u))return Fe(u,s,r);let c=Date.now()-r,d=u,o=D({provider:T,model:s.model||d.model||"unknown",input:{system:s.system,messages:s.messages},rawResponse:u,durationMs:c,status:"success",streaming:!1});if(o&&d.content){let l=J(d.content);l.length>0&&O(l,o);}return u}catch(u){let c=Date.now()-r;throw _({provider:T,model:s.model||"unknown",input:{system:s.system,messages:s.messages},error:u instanceof Error?u:new Error(String(u)),durationMs:c,streaming:a}),u}}}function pe(e){return function(...n){let r=Date.now(),s=n[0]||{};try{let a=e(...n);return a&&typeof a=="object"?ze(a,s,r):a}catch(a){let u=Date.now()-r;throw _({provider:T,model:s.model||"unknown",input:{system:s.system,messages:s.messages},error:a instanceof Error?a:new Error(String(a)),durationMs:u,streaming:true}),a}}}function Je(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}function ze(e,t,n){let r=e;if(!r[Symbol.asyncIterator])return e;let s={content:[],usage:{input_tokens:0,output_tokens:0}},a=false,u,c=false,d=null,o=[],l=async function*(){try{for await(let i of r){if(i.type==="message_start"&&i.message&&(s.model=i.message.model,s.id=i.message.id,s.role=i.message.role,i.message.usage&&(s.usage={...i.message.usage})),i.type==="content_block_start"&&i.content_block&&(d=i.index??o.length,o[d]={...i.content_block},i.content_block.type==="text"&&(o[d].text=""),i.content_block.type==="thinking"&&(o[d].thinking="")),i.type==="content_block_delta"&&i.delta&&d!==null){let p=o[d];p&&(i.delta.text&&(c||(c=!0,u=Date.now()-n),p.type==="thinking"?p.thinking=(p.thinking||"")+i.delta.text:p.type==="text"&&(p.text=(p.text||"")+i.delta.text)),i.delta.partial_json&&p.type==="tool_use"&&(p._inputJson=(p._inputJson||"")+i.delta.partial_json));}if(i.type==="content_block_stop"&&d!==null){let p=o[d];if(p&&p.type==="tool_use"){let b=p._inputJson;if(b){try{p.input=JSON.parse(b);}catch{}delete p._inputJson;}}d=null;}i.type==="message_delta"&&(i.usage?.output_tokens&&(s.usage.output_tokens=i.usage.output_tokens),i.delta?.stop_reason&&(s.stop_reason=i.delta.stop_reason)),yield i;}}catch(i){if(!a){a=true;let p=Date.now()-n;_({provider:T,model:s.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:i instanceof Error?i:new Error(String(i)),durationMs:p,streaming:true});}throw i}finally{if(!a){a=true;let i=Date.now()-n;s.content=o.filter(Boolean);let p=D({provider:T,model:s.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:s,durationMs:i,status:"success",streaming:true,firstTokenMs:u});if(p&&s.content){let b=J(s.content);b.length>0&&O(b,p);}}}};return new Proxy(e,{get(i,p,b){return p===Symbol.asyncIterator?()=>l()[Symbol.asyncIterator]():Reflect.get(i,p,b)}})}async function*Fe(e,t,n){let r={content:[],usage:{input_tokens:0,output_tokens:0}},s=null,a,u=false,c=null,d=[];try{for await(let o of e){if(o.type==="message_start"&&o.message&&(r.model=o.message.model,r.id=o.message.id,r.role=o.message.role,o.message.usage&&(r.usage={...o.message.usage})),o.type==="content_block_start"&&o.content_block&&(c=o.index??d.length,d[c]={...o.content_block},o.content_block.type==="text"&&(d[c].text=""),o.content_block.type==="thinking"&&(d[c].thinking="")),o.type==="content_block_delta"&&o.delta&&c!==null){let l=d[c];l&&(o.delta.text&&(u||(u=!0,a=Date.now()-n),l.type==="thinking"?l.thinking=(l.thinking||"")+o.delta.text:l.type==="text"&&(l.text=(l.text||"")+o.delta.text)),o.delta.partial_json&&l.type==="tool_use"&&(l._inputJson=(l._inputJson||"")+o.delta.partial_json));}if(o.type==="content_block_stop"&&c!==null){let l=d[c];if(l&&l.type==="tool_use"){let i=l._inputJson;if(i){try{l.input=JSON.parse(i);}catch{}delete l._inputJson;}}c=null;}o.type==="message_delta"&&(o.usage?.output_tokens&&(r.usage.output_tokens=o.usage.output_tokens),o.delta?.stop_reason&&(r.stop_reason=o.delta.stop_reason)),yield o;}}catch(o){throw s=o instanceof Error?o:new Error(String(o)),o}finally{let o=Date.now()-n;if(r.content=d.filter(Boolean),s)_({provider:T,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:s,durationMs:o,streaming:true});else {let l=D({provider:T,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:r,durationMs:o,status:"success",streaming:true,firstTokenMs:a});if(l&&r.content){let i=J(r.content);i.length>0&&O(i,l);}}}}function J(e){let t=[];for(let n of e)n.type==="tool_use"&&n.id&&t.push(n.id);return t}function Mt(e,t){return t&&ae(t),R().disabled?(g("Tracing disabled, returning unwrapped client"),e):de(e)?(V("anthropic"),Ve(e)):(E("Client is not an Anthropic client. Use @lelemondev/sdk/anthropic only with Anthropic SDK."),e)}function Ve(e){let t=e;return new Proxy(t,{get(n,r,s){let a=Reflect.get(n,r,s);return r==="messages"&&a&&typeof a=="object"?He(a):a}})}function He(e){return new Proxy(e,{get(t,n,r){let s=Reflect.get(t,n,r);return n==="create"&&typeof s=="function"?le(s.bind(t)):n==="stream"&&typeof s=="function"?pe(s.bind(t)):s}})}
|
|
3
|
+
exports.captureSpan=L;exports.flush=Ee;exports.getTraceContext=m;exports.init=Ie;exports.isEnabled=_e;exports.observe=Mt;exports.span=Be;exports.trace=Ke;//# sourceMappingURL=anthropic.js.map
|
|
4
4
|
//# sourceMappingURL=anthropic.js.map
|
package/dist/anthropic.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var J=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var pe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Z=pe((Qe,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var z=false;function F(e){z=e;}function y(){return z?true:ge("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function g(e,t){y()&&q("debug",e,t);}function j(e,t){y()&&q("info",e,t);}function _(e,t){q("warn",e,t);}function O(e,t,n,r){y()&&console.log(`${f} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${f} Failed to capture trace: provider=${e} error=${t.message}`);}function G(e){y()&&console.log(`${f} Wrapped client: provider=${e}`);}function V(e,t){y()&&console.log(`${f} Sending batch: count=${e} endpoint=${t}`);}function H(e,t){y()&&console.log(`${f} Batch sent successfully: count=${e} duration=${t}ms`);}function W(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${f} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){y()&&console.log(`${f} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){y()&&console.log(`${f} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${f} ${t}`,n):r(`${f} ${t}`);}function ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,me=1e3,ye=1e4,C=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??fe,flushIntervalMs:t.flushIntervalMs??me,requestTimeoutMs:t.requestTimeoutMs??ye};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();V(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),H(t.length,Date.now()-n);}catch(r){W(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,a=new AbortController,u=r?JSON.stringify(r):void 0;Y(t,o,u?.length??0);let c=setTimeout(()=>{a.abort();},this.config.requestTimeoutMs),d=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:u,signal:a.signal});if(clearTimeout(c),X(s.status,Date.now()-d),!s.ok){let i=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${i}`)}let l=await s.text();return l?JSON.parse(l):{}}catch(s){throw clearTimeout(c),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var he="@lelemondev/sdk",ke="nodejs";function we(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function Te(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function ve(){try{if(typeof J<"u")return Z().version??"unknown"}catch{}return "unknown"}var T=null;function ee(e){if(!T){let n=we(),r=Te();T={"telemetry.sdk.name":he,"telemetry.sdk.version":ve(),"telemetry.sdk.language":ke},n&&(T["process.runtime.name"]=n.name,T["process.runtime.version"]=n.version),r&&(T["os.type"]=r);}let t={...T};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var P={},h=null,$=null,te="https://api.lelemon.dev";function Ie(e={}){P=e,e.debug&&F(true),$=ee(e.service),j("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),h=ne(e),h.isEnabled()?j("SDK initialized - tracing enabled"):g("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function M(){return P}function R(){return $}function Se(){return k().isEnabled()}function k(){return h||(h=ne(P)),h}async function _e(){h&&await h.flush();}function ne(e){let t=e.apiKey??Ee("LELEMON_API_KEY");return !t&&!e.disabled&&_("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new C({apiKey:t??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ee(e){if(typeof process<"u"&&process.env)return process.env[e]}var K=Symbol.for("@lelemondev/sdk:globalContext");function se(){let e=globalThis;return e[K]||(e[K]={context:{}}),e[K]}function ie(e){se().context=e,g("Global context updated",e);}function I(){return se().context}function A(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping trace capture");return}let n=I(),r=m(),o=v(),a=R(),u={provider:e.provider,model:e.model,input:L(e.input),rawResponse:e.rawResponse?x(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...a?{_telemetry:a}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return O(e.provider,e.model,e.durationMs,e.status),t.enqueue(u),o}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function S(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping error capture");return}let n=I(),r=m(),o=R(),a={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:v(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};O(e.provider,e.model,e.durationMs,"error"),g("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(a);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function N(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping span capture");return}let n=I(),r=m(),o=e.metadata?._traceId,a=e.metadata?._parentSpanId,u=R(),c={...n.metadata,...e.metadata,...u?{_telemetry:u}:{}};delete c._traceId,delete c._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:L(e.input),output:x(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:v(),parentSpanId:a??r?.currentSpanId,toolCallId:e.toolCallId,metadata:c,tags:n.tags};g(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,Ce=["api_key","apikey","password","secret","authorization"],Me=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Re=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],oe={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ae(){return M().redaction??{}}function Ae(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Ce.some(r=>t.includes(r))||Me.some(r=>t.includes(r))||(ae().keys??[]).some(r=>t.includes(r.toLowerCase())))}function De(e){let t=ae(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(oe.emails,"[EMAIL]")),t.phones&&(n=n.replace(oe.phones,"[PHONE]")),n}function L(e){return x(e,0)}function x(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=De(e);return n.length>re&&(n=n.slice(0,re)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>x(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Ae(r)?n[r]="[REDACTED]":n[r]=x(o,t+1);return n}return String(e)}var U=Symbol.for("@lelemondev/sdk:traceStorage");function Oe(){let e=globalThis;return e[U]||(e[U]=new AsyncLocalStorage),e[U]}var ue=Oe();function v(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ue.getStore()}function D(e,t){let n=m();if(n)for(let r of e)n.pendingToolCalls.set(r,t),g(`Registered tool call ${r} \u2192 LLM span ${t}`);}function qe(e){let t=m();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function $e(e){let t=m();t&&t.pendingToolCalls.delete(e);}async function Pe(e,t){let n=typeof e=="string"?{name:e}:e,r=m(),o=r?.traceId??v(),a=v(),u={traceId:o,rootSpanId:a,currentSpanId:a,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ue.run(u,async()=>{let c,d;try{return c=await t(),c}catch(s){throw d=s instanceof Error?s:new Error(String(s)),s}finally{Le(u,d?void 0:c,d);}})}var Ke=["text","content","message","output","response","result","answer"];function Ne(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Ke)if(o in r&&typeof r[o]=="string")return r[o];return e}function Le(e,t,n){let r=k();if(!r.isEnabled()){g("Transport disabled, skipping root span");return}let o=I(),a=Date.now()-e.startTime,u=n?null:Ne(t,e.outputKey,e.outputTransform),c={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:u,inputTokens:0,outputTokens:0,durationMs:a,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};g(`Sending root span: ${e.name}`,{durationMs:a,hasError:!!n}),r.enqueue(c);}function Ue(e){let t=m();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=qe(e.toolCallId);N({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&$e(e.toolCallId);}var w="anthropic";function ce(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="Anthropic")return true;let n=e;return !!(n.messages&&typeof n.messages=="object")}function de(e){return async function(...n){let r=Date.now(),o=n[0]||{},a=o.stream===true;try{let u=await e(...n);if(a&&Be(u))return ze(u,o,r);let c=Date.now()-r,d=u,s=A({provider:w,model:o.model||d.model||"unknown",input:{system:o.system,messages:o.messages},rawResponse:u,durationMs:c,status:"success",streaming:!1});if(s&&d.content){let l=B(d.content);l.length>0&&D(l,s);}return u}catch(u){let c=Date.now()-r;throw S({provider:w,model:o.model||"unknown",input:{system:o.system,messages:o.messages},error:u instanceof Error?u:new Error(String(u)),durationMs:c,streaming:a}),u}}}function le(e){return function(...n){let r=Date.now(),o=n[0]||{};try{let a=e(...n);return a&&typeof a=="object"?Je(a,o,r):a}catch(a){let u=Date.now()-r;throw S({provider:w,model:o.model||"unknown",input:{system:o.system,messages:o.messages},error:a instanceof Error?a:new Error(String(a)),durationMs:u,streaming:true}),a}}}function Be(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}function Je(e,t,n){let r=e;if(!r[Symbol.asyncIterator])return e;let o={content:[],usage:{input_tokens:0,output_tokens:0}},a=false,u,c=false,d=null,s=[],l=async function*(){try{for await(let i of r){if(i.type==="message_start"&&i.message&&(o.model=i.message.model,o.id=i.message.id,o.role=i.message.role,i.message.usage&&(o.usage={...i.message.usage})),i.type==="content_block_start"&&i.content_block&&(d=i.index??s.length,s[d]={...i.content_block},i.content_block.type==="text"&&(s[d].text=""),i.content_block.type==="thinking"&&(s[d].thinking="")),i.type==="content_block_delta"&&i.delta&&d!==null){let p=s[d];p&&(i.delta.text&&(c||(c=!0,u=Date.now()-n),p.type==="thinking"?p.thinking=(p.thinking||"")+i.delta.text:p.type==="text"&&(p.text=(p.text||"")+i.delta.text)),i.delta.partial_json&&p.type==="tool_use"&&(p._inputJson=(p._inputJson||"")+i.delta.partial_json));}if(i.type==="content_block_stop"&&d!==null){let p=s[d];if(p&&p.type==="tool_use"){let b=p._inputJson;if(b){try{p.input=JSON.parse(b);}catch{}delete p._inputJson;}}d=null;}i.type==="message_delta"&&(i.usage?.output_tokens&&(o.usage.output_tokens=i.usage.output_tokens),i.delta?.stop_reason&&(o.stop_reason=i.delta.stop_reason)),yield i;}}catch(i){if(!a){a=true;let p=Date.now()-n;S({provider:w,model:o.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:i instanceof Error?i:new Error(String(i)),durationMs:p,streaming:true});}throw i}finally{if(!a){a=true;let i=Date.now()-n;o.content=s.filter(Boolean);let p=A({provider:w,model:o.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:o,durationMs:i,status:"success",streaming:true,firstTokenMs:u});if(p&&o.content){let b=B(o.content);b.length>0&&D(b,p);}}}};return new Proxy(e,{get(i,p,b){return p===Symbol.asyncIterator?()=>l()[Symbol.asyncIterator]():Reflect.get(i,p,b)}})}async function*ze(e,t,n){let r={content:[],usage:{input_tokens:0,output_tokens:0}},o=null,a,u=false,c=null,d=[];try{for await(let s of e){if(s.type==="message_start"&&s.message&&(r.model=s.message.model,r.id=s.message.id,r.role=s.message.role,s.message.usage&&(r.usage={...s.message.usage})),s.type==="content_block_start"&&s.content_block&&(c=s.index??d.length,d[c]={...s.content_block},s.content_block.type==="text"&&(d[c].text=""),s.content_block.type==="thinking"&&(d[c].thinking="")),s.type==="content_block_delta"&&s.delta&&c!==null){let l=d[c];l&&(s.delta.text&&(u||(u=!0,a=Date.now()-n),l.type==="thinking"?l.thinking=(l.thinking||"")+s.delta.text:l.type==="text"&&(l.text=(l.text||"")+s.delta.text)),s.delta.partial_json&&l.type==="tool_use"&&(l._inputJson=(l._inputJson||"")+s.delta.partial_json));}if(s.type==="content_block_stop"&&c!==null){let l=d[c];if(l&&l.type==="tool_use"){let i=l._inputJson;if(i){try{l.input=JSON.parse(i);}catch{}delete l._inputJson;}}c=null;}s.type==="message_delta"&&(s.usage?.output_tokens&&(r.usage.output_tokens=s.usage.output_tokens),s.delta?.stop_reason&&(r.stop_reason=s.delta.stop_reason)),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n;if(r.content=d.filter(Boolean),o)S({provider:w,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let l=A({provider:w,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:a});if(l&&r.content){let i=B(r.content);i.length>0&&D(i,l);}}}}function B(e){let t=[];for(let n of e)n.type==="tool_use"&&n.id&&t.push(n.id);return t}function Tt(e,t){return t&&ie(t),M().disabled?(g("Tracing disabled, returning unwrapped client"),e):ce(e)?(G("anthropic"),Ge(e)):(_("Client is not an Anthropic client. Use @lelemondev/sdk/anthropic only with Anthropic SDK."),e)}function Ge(e){let t=e;return new Proxy(t,{get(n,r,o){let a=Reflect.get(n,r,o);return r==="messages"&&a&&typeof a=="object"?Ve(a):a}})}function Ve(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?de(o.bind(t)):n==="stream"&&typeof o=="function"?le(o.bind(t)):o}})}
|
|
3
|
-
export{N as captureSpan,_e as flush,m as getTraceContext,
|
|
2
|
+
var J=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var pe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Z=pe((Qe,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.10.1",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var z=false;function F(e){z=e;}function y(){return z?true:ge("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function g(e,t){y()&&q("debug",e,t);}function O(e,t){y()&&q("info",e,t);}function _(e,t){q("warn",e,t);}function j(e,t,n,r){y()&&console.log(`${f} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${f} Failed to capture trace: provider=${e} error=${t.message}`);}function G(e){y()&&console.log(`${f} Wrapped client: provider=${e}`);}function V(e,t){y()&&console.log(`${f} Sending batch: count=${e} endpoint=${t}`);}function H(e,t){y()&&console.log(`${f} Batch sent successfully: count=${e} duration=${t}ms`);}function W(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${f} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){y()&&console.log(`${f} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){y()&&console.log(`${f} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${f} ${t}`,n):r(`${f} ${t}`);}function ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,me=1e3,ye=1e4,C=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??fe,flushIntervalMs:t.flushIntervalMs??me,requestTimeoutMs:t.requestTimeoutMs??ye};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();V(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),H(t.length,Date.now()-n);}catch(r){W(t.length,r);}}async request(t,n,r){let s=`${this.config.endpoint}${n}`,a=new AbortController,u=r?JSON.stringify(r):void 0;Y(t,s,u?.length??0);let c=setTimeout(()=>{a.abort();},this.config.requestTimeoutMs),d=Date.now();try{let o=await fetch(s,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:u,signal:a.signal});if(clearTimeout(c),X(o.status,Date.now()-d),!o.ok){let i=await o.text().catch(()=>"Unknown error");throw new Error(`HTTP ${o.status}: ${i}`)}let l=await o.text();return l?JSON.parse(l):{}}catch(o){throw clearTimeout(c),o instanceof Error&&o.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):o}}};var he="@lelemondev/sdk",ke="nodejs";function we(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function Te(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function ve(){try{if(typeof J<"u")return Z().version??"unknown"}catch{}return "unknown"}var T=null;function ee(e){if(!T){let n=we(),r=Te();T={"telemetry.sdk.name":he,"telemetry.sdk.version":ve(),"telemetry.sdk.language":ke},n&&(T["process.runtime.name"]=n.name,T["process.runtime.version"]=n.version),r&&(T["os.type"]=r);}let t={...T};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var P={},h=null,$=null,te="https://api.lelemon.dev";function xe(e={}){P=e,e.debug&&F(true),$=ee(e.service),O("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),h=ne(e),h.isEnabled()?O("SDK initialized - tracing enabled"):g("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function M(){return P}function R(){return $}function Ie(){return k().isEnabled()}function k(){return h||(h=ne(P)),h}async function _e(){h&&await h.flush();}function ne(e){let t=e.apiKey??Ee("LELEMON_API_KEY");return !t&&!e.disabled&&_("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new C({apiKey:t??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ee(e){if(typeof process<"u"&&process.env)return process.env[e]}var K=Symbol.for("@lelemondev/sdk:globalContext");function oe(){let e=globalThis;return e[K]||(e[K]={context:{}}),e[K]}function ie(e){oe().context=e,g("Global context updated",e);}function x(){return oe().context}function A(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping trace capture");return}let n=x(),r=m(),s=v(),a=R(),u={provider:e.provider,model:e.model,input:L(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:s,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...a?{_telemetry:a}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return j(e.provider,e.model,e.durationMs,e.status),t.enqueue(u),s}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function I(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping error capture");return}let n=x(),r=m(),s=R(),a={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:v(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags};j(e.provider,e.model,e.durationMs,"error"),g("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(a);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function N(e){try{let t=k();if(!t.isEnabled()){g("Transport disabled, skipping span capture");return}let n=x(),r=m(),s=e.metadata?._traceId,a=e.metadata?._parentSpanId,u=R(),c={...n.metadata,...e.metadata,...u?{_telemetry:u}:{}};delete c._traceId,delete c._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:L(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:s??r?.traceId,spanId:v(),parentSpanId:a??r?.currentSpanId,toolCallId:e.toolCallId,metadata:c,tags:n.tags};g(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,Ce=["api_key","apikey","password","secret","authorization"],Me=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Re=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],se={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ae(){return M().redaction??{}}function Ae(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Ce.some(r=>t.includes(r))||Me.some(r=>t.includes(r))||(ae().keys??[]).some(r=>t.includes(r.toLowerCase())))}function De(e){let t=ae(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(se.emails,"[EMAIL]")),t.phones&&(n=n.replace(se.phones,"[PHONE]")),n}function L(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=De(e);return n.length>re&&(n=n.slice(0,re)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,s]of Object.entries(e))Ae(r)?n[r]="[REDACTED]":n[r]=S(s,t+1);return n}return String(e)}var U=Symbol.for("@lelemondev/sdk:traceStorage");function je(){let e=globalThis;return e[U]||(e[U]=new AsyncLocalStorage),e[U]}var ue=je();function v(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ue.getStore()}function D(e,t){let n=m();if(n)for(let r of e)n.pendingToolCalls.set(r,t),g(`Registered tool call ${r} \u2192 LLM span ${t}`);}function qe(e){let t=m();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function $e(e){let t=m();t&&t.pendingToolCalls.delete(e);}async function Pe(e,t){let n=typeof e=="string"?{name:e}:e,r=m(),s=r?.traceId??v(),a=v(),u={traceId:s,rootSpanId:a,currentSpanId:a,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,style:n.style,pendingToolCalls:new Map};return ue.run(u,async()=>{let c,d;try{return c=await t(),c}catch(o){throw d=o instanceof Error?o:new Error(String(o)),o}finally{Le(u,d?void 0:c,d);}})}var Ke=["text","content","message","output","response","result","answer"];function Ne(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let s=e;return t in s?s[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let s of Ke)if(s in r&&typeof r[s]=="string")return r[s];return e}function Le(e,t,n){let r=k();if(!r.isEnabled()){g("Transport disabled, skipping root span");return}let s=x(),a=Date.now()-e.startTime,u=n?null:Ne(t,e.outputKey,e.outputTransform),c={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:u,inputTokens:0,outputTokens:0,durationMs:a,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??s.sessionId,userId:e.userId??s.userId,metadata:{...s.metadata,...e.metadata,...e.style?{_style:e.style}:{}},tags:e.tags??s.tags};g(`Sending root span: ${e.name}`,{durationMs:a,hasError:!!n}),r.enqueue(c);}function Ue(e){let t=m();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=qe(e.toolCallId);N({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n,...e.style?{_style:e.style}:{}}}),e.toolCallId&&$e(e.toolCallId);}var w="anthropic";function ce(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="Anthropic")return true;let n=e;return !!(n.messages&&typeof n.messages=="object")}function de(e){return async function(...n){let r=Date.now(),s=n[0]||{},a=s.stream===true;try{let u=await e(...n);if(a&&Be(u))return ze(u,s,r);let c=Date.now()-r,d=u,o=A({provider:w,model:s.model||d.model||"unknown",input:{system:s.system,messages:s.messages},rawResponse:u,durationMs:c,status:"success",streaming:!1});if(o&&d.content){let l=B(d.content);l.length>0&&D(l,o);}return u}catch(u){let c=Date.now()-r;throw I({provider:w,model:s.model||"unknown",input:{system:s.system,messages:s.messages},error:u instanceof Error?u:new Error(String(u)),durationMs:c,streaming:a}),u}}}function le(e){return function(...n){let r=Date.now(),s=n[0]||{};try{let a=e(...n);return a&&typeof a=="object"?Je(a,s,r):a}catch(a){let u=Date.now()-r;throw I({provider:w,model:s.model||"unknown",input:{system:s.system,messages:s.messages},error:a instanceof Error?a:new Error(String(a)),durationMs:u,streaming:true}),a}}}function Be(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}function Je(e,t,n){let r=e;if(!r[Symbol.asyncIterator])return e;let s={content:[],usage:{input_tokens:0,output_tokens:0}},a=false,u,c=false,d=null,o=[],l=async function*(){try{for await(let i of r){if(i.type==="message_start"&&i.message&&(s.model=i.message.model,s.id=i.message.id,s.role=i.message.role,i.message.usage&&(s.usage={...i.message.usage})),i.type==="content_block_start"&&i.content_block&&(d=i.index??o.length,o[d]={...i.content_block},i.content_block.type==="text"&&(o[d].text=""),i.content_block.type==="thinking"&&(o[d].thinking="")),i.type==="content_block_delta"&&i.delta&&d!==null){let p=o[d];p&&(i.delta.text&&(c||(c=!0,u=Date.now()-n),p.type==="thinking"?p.thinking=(p.thinking||"")+i.delta.text:p.type==="text"&&(p.text=(p.text||"")+i.delta.text)),i.delta.partial_json&&p.type==="tool_use"&&(p._inputJson=(p._inputJson||"")+i.delta.partial_json));}if(i.type==="content_block_stop"&&d!==null){let p=o[d];if(p&&p.type==="tool_use"){let b=p._inputJson;if(b){try{p.input=JSON.parse(b);}catch{}delete p._inputJson;}}d=null;}i.type==="message_delta"&&(i.usage?.output_tokens&&(s.usage.output_tokens=i.usage.output_tokens),i.delta?.stop_reason&&(s.stop_reason=i.delta.stop_reason)),yield i;}}catch(i){if(!a){a=true;let p=Date.now()-n;I({provider:w,model:s.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:i instanceof Error?i:new Error(String(i)),durationMs:p,streaming:true});}throw i}finally{if(!a){a=true;let i=Date.now()-n;s.content=o.filter(Boolean);let p=A({provider:w,model:s.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:s,durationMs:i,status:"success",streaming:true,firstTokenMs:u});if(p&&s.content){let b=B(s.content);b.length>0&&D(b,p);}}}};return new Proxy(e,{get(i,p,b){return p===Symbol.asyncIterator?()=>l()[Symbol.asyncIterator]():Reflect.get(i,p,b)}})}async function*ze(e,t,n){let r={content:[],usage:{input_tokens:0,output_tokens:0}},s=null,a,u=false,c=null,d=[];try{for await(let o of e){if(o.type==="message_start"&&o.message&&(r.model=o.message.model,r.id=o.message.id,r.role=o.message.role,o.message.usage&&(r.usage={...o.message.usage})),o.type==="content_block_start"&&o.content_block&&(c=o.index??d.length,d[c]={...o.content_block},o.content_block.type==="text"&&(d[c].text=""),o.content_block.type==="thinking"&&(d[c].thinking="")),o.type==="content_block_delta"&&o.delta&&c!==null){let l=d[c];l&&(o.delta.text&&(u||(u=!0,a=Date.now()-n),l.type==="thinking"?l.thinking=(l.thinking||"")+o.delta.text:l.type==="text"&&(l.text=(l.text||"")+o.delta.text)),o.delta.partial_json&&l.type==="tool_use"&&(l._inputJson=(l._inputJson||"")+o.delta.partial_json));}if(o.type==="content_block_stop"&&c!==null){let l=d[c];if(l&&l.type==="tool_use"){let i=l._inputJson;if(i){try{l.input=JSON.parse(i);}catch{}delete l._inputJson;}}c=null;}o.type==="message_delta"&&(o.usage?.output_tokens&&(r.usage.output_tokens=o.usage.output_tokens),o.delta?.stop_reason&&(r.stop_reason=o.delta.stop_reason)),yield o;}}catch(o){throw s=o instanceof Error?o:new Error(String(o)),o}finally{let o=Date.now()-n;if(r.content=d.filter(Boolean),s)I({provider:w,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},error:s,durationMs:o,streaming:true});else {let l=A({provider:w,model:r.model||t.model||"unknown",input:{system:t.system,messages:t.messages},rawResponse:r,durationMs:o,status:"success",streaming:true,firstTokenMs:a});if(l&&r.content){let i=B(r.content);i.length>0&&D(i,l);}}}}function B(e){let t=[];for(let n of e)n.type==="tool_use"&&n.id&&t.push(n.id);return t}function Tt(e,t){return t&&ie(t),M().disabled?(g("Tracing disabled, returning unwrapped client"),e):ce(e)?(G("anthropic"),Ge(e)):(_("Client is not an Anthropic client. Use @lelemondev/sdk/anthropic only with Anthropic SDK."),e)}function Ge(e){let t=e;return new Proxy(t,{get(n,r,s){let a=Reflect.get(n,r,s);return r==="messages"&&a&&typeof a=="object"?Ve(a):a}})}function Ve(e){return new Proxy(e,{get(t,n,r){let s=Reflect.get(t,n,r);return n==="create"&&typeof s=="function"?de(s.bind(t)):n==="stream"&&typeof s=="function"?le(s.bind(t)):s}})}
|
|
3
|
+
export{N as captureSpan,_e as flush,m as getTraceContext,xe as init,Ie as isEnabled,Tt as observe,Ue as span,Pe as trace};//# sourceMappingURL=anthropic.mjs.map
|
|
4
4
|
//# sourceMappingURL=anthropic.mjs.map
|
package/dist/bedrock.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-DOj4Z9MB.mjs';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-DOj4Z9MB.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* AWS Bedrock Provider Entry Point
|
package/dist/bedrock.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-DOj4Z9MB.js';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-DOj4Z9MB.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* AWS Bedrock Provider Entry Point
|
package/dist/bedrock.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('async_hooks');/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var z=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var me=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Z=me((it,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var F=false;function G(e){F=e;}function k(){return F?true:fe("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&q("debug",e,t);}function B(e,t){k()&&q("info",e,t);}function R(e,t){q("warn",e,t);}function O(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function M(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function V(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function J(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function W(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){k()&&console.log(`${m} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${m} ${t}`,n):r(`${m} ${t}`);}function fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var ge=10,ye=1e3,ke=1e4,D=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ge,flushIntervalMs:t.flushIntervalMs??ye,requestTimeoutMs:t.requestTimeoutMs??ke};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();J(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),W(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;Y(t,o,a?.length??0);let u=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),p=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(u),X(s.status,Date.now()-p),!s.ok){let d=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${d}`)}let c=await s.text();return c?JSON.parse(c):{}}catch(s){throw clearTimeout(u),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var we="@lelemondev/sdk",Te="nodejs";function he(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Ie(){try{if(typeof z<"u")return Z().version??"unknown"}catch{}return "unknown"}var v=null;function ee(e){if(!v){let n=he(),r=ve();v={"telemetry.sdk.name":we,"telemetry.sdk.version":Ie(),"telemetry.sdk.language":Te},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var U={},w=null,P=null,te="https://api.lelemon.dev";function xe(e={}){U=e,e.debug&&G(true),P=ee(e.service),B("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:P}),w=ne(e),w.isEnabled()?B("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function _(){return U}function A(){return P}function Ce(){return T().isEnabled()}function T(){return w||(w=ne(U)),w}async function Ee(){w&&await w.flush();}function ne(e){let t=e.apiKey??Re("LELEMON_API_KEY");return !t&&!e.disabled&&R("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new D({apiKey:t??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Re(e){if(typeof process<"u"&&process.env)return process.env[e]}var $=Symbol.for("@lelemondev/sdk:globalContext");function se(){let e=globalThis;return e[$]||(e[$]={context:{}}),e[$]}function ie(e){se().context=e,l("Global context updated",e);}function x(){return se().context}function C(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=I(),i=A(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return O(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));return}}function h(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=A(),i={provider:e.provider,model:e.model,input:N(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:I(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};O(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=A(),u={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete u._traceId,delete u._parentSpanId;let p={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:N(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:I(),parentSpanId:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:u,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(p);}catch(t){M("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,Me=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],_e=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],oe={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ae(){return _().redaction??{}}function Ae(e){let t=e.toLowerCase();return _e.includes(t)?false:!!(Me.some(r=>t.includes(r))||De.some(r=>t.includes(r))||(ae().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Be(e){let t=ae(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(oe.emails,"[EMAIL]")),t.phones&&(n=n.replace(oe.phones,"[PHONE]")),n}function N(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=Be(e);return n.length>re&&(n=n.slice(0,re)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Ae(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function qe(){let e=globalThis;return e[K]||(e[K]=new async_hooks.AsyncLocalStorage),e[K]}var ue=qe();function I(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ue.getStore()}function L(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function Pe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ue(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function $e(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??I(),i=I(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ue.run(a,async()=>{let u,p;try{return u=await t(),u}catch(s){throw p=s instanceof Error?s:new Error(String(s)),s}finally{Ke(a,p?void 0:u,p);}})}var je=["text","content","message","output","response","result","answer"];function Ne(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of je)if(o in r&&typeof r[o]=="string")return r[o];return e}function Ke(e,t,n){let r=T();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),i=Date.now()-e.startTime,a=n?null:Ne(t,e.outputKey,e.outputTransform),u={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(u);}function Le(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Pe(e.toolCallId);j({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Ue(e.toolCallId);}var g="bedrock";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="BedrockRuntimeClient")return true;let n=e;return typeof n.send!="function"||!n.config||typeof n.config!="object"?false:"region"in n.config}function ce(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="send"&&typeof i=="function"?ze(i.bind(n)):i}})}function ze(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Fe(e,n);case "ConverseStreamCommand":return Ge(e,n);case "InvokeModelCommand":return Je(e,n);case "InvokeModelWithResponseStreamCommand":return We(e,n);default:return e(n)}}}async function Fe(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=C({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:le(o),durationMs:i,status:"success",streaming:!1});if(a){let u=pe(o);u.length>0&&L(u,a);}return o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Ge(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:Ve(o.stream,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Ve(e,t,n){let r={output:{message:{role:"assistant",content:[]}},usage:{inputTokens:0,outputTokens:0}},o=null,i,a=false,u=new Map,p=new Map;try{for await(let s of e){if(s.contentBlockStart){let c=s.contentBlockStart.contentBlockIndex;if(s.contentBlockStart.start?.toolUse){let d=s.contentBlockStart.start.toolUse;u.set(c,{toolUse:{toolUseId:d.toolUseId,name:d.name,input:{}}}),p.set(c,"");}else u.set(c,{text:""});}if(s.contentBlockDelta){let c=s.contentBlockDelta.contentBlockIndex,d=u.get(c);if(d&&s.contentBlockDelta.delta?.text&&(a||(a=!0,i=Date.now()-n),d.text=(d.text||"")+s.contentBlockDelta.delta.text),d?.toolUse&&s.contentBlockDelta.delta?.toolUse?.input){let y=p.get(c)||"";p.set(c,y+s.contentBlockDelta.delta.toolUse.input);}}if(s.contentBlockStop){let c=s.contentBlockStop.contentBlockIndex,d=u.get(c),y=p.get(c);if(d?.toolUse&&y)try{d.toolUse.input=JSON.parse(y);}catch{}}s.messageStop?.stopReason&&(r.stopReason=s.messageStop.stopReason),s.metadata?.usage&&(r.usage={inputTokens:s.metadata.usage.inputTokens||0,outputTokens:s.metadata.usage.outputTokens||0}),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n,c=Array.from(u.entries()).sort((d,y)=>d[0]-y[0]).map(([,d])=>d);if(r.output.message.content=c,o)h({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=C({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:le(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=pe(r);y.length>0&&L(y,d);}}}}async function Je(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Ye(o.body);return C({provider:g,model:r.modelId||"unknown",input:E(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function We(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:He(o.body,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*He(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Xe(i.chunk.bytes);a&&r.push(a);}yield i;}}catch(i){throw o=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-n;o?h({provider:g,model:t.modelId||"unknown",input:E(t.body),error:o,durationMs:i,streaming:true}):C({provider:g,model:t.modelId||"unknown",input:E(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function le(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function pe(e){let t=[],n=e.output?.message?.content;if(Array.isArray(n))for(let r of n)r.toolUse?.toolUseId&&t.push(r.toolUse.toolUseId);return t}function E(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Ye(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Xe(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Bt(e,t){return t&&ie(t),_().disabled?(l("Tracing disabled, returning unwrapped client"),e):de(e)?(V("bedrock"),ce(e)):(R("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
2
|
+
var z=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var me=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Z=me((it,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.10.1",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var F=false;function G(e){F=e;}function k(){return F?true:fe("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&q("debug",e,t);}function B(e,t){k()&&q("info",e,t);}function R(e,t){q("warn",e,t);}function O(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function M(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function V(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function J(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function W(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){k()&&console.log(`${m} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${m} ${t}`,n):r(`${m} ${t}`);}function fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var ge=10,ye=1e3,ke=1e4,D=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ge,flushIntervalMs:t.flushIntervalMs??ye,requestTimeoutMs:t.requestTimeoutMs??ke};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();J(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),W(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;Y(t,o,a?.length??0);let u=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),p=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(u),X(s.status,Date.now()-p),!s.ok){let d=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${d}`)}let c=await s.text();return c?JSON.parse(c):{}}catch(s){throw clearTimeout(u),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var we="@lelemondev/sdk",Te="nodejs";function he(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Ie(){try{if(typeof z<"u")return Z().version??"unknown"}catch{}return "unknown"}var v=null;function ee(e){if(!v){let n=he(),r=ve();v={"telemetry.sdk.name":we,"telemetry.sdk.version":Ie(),"telemetry.sdk.language":Te},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var U={},w=null,P=null,te="https://api.lelemon.dev";function xe(e={}){U=e,e.debug&&G(true),P=ee(e.service),B("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:P}),w=ne(e),w.isEnabled()?B("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function _(){return U}function A(){return P}function Ce(){return T().isEnabled()}function T(){return w||(w=ne(U)),w}async function Ee(){w&&await w.flush();}function ne(e){let t=e.apiKey??Re("LELEMON_API_KEY");return !t&&!e.disabled&&R("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new D({apiKey:t??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Re(e){if(typeof process<"u"&&process.env)return process.env[e]}var $=Symbol.for("@lelemondev/sdk:globalContext");function se(){let e=globalThis;return e[$]||(e[$]={context:{}}),e[$]}function ie(e){se().context=e,l("Global context updated",e);}function x(){return se().context}function C(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=I(),i=A(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return O(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));return}}function h(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=A(),i={provider:e.provider,model:e.model,input:N(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:I(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};O(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=T();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=A(),u={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete u._traceId,delete u._parentSpanId;let p={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:N(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:I(),parentSpanId:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:u,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(p);}catch(t){M("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,Me=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],_e=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],oe={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ae(){return _().redaction??{}}function Ae(e){let t=e.toLowerCase();return _e.includes(t)?false:!!(Me.some(r=>t.includes(r))||De.some(r=>t.includes(r))||(ae().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Be(e){let t=ae(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(oe.emails,"[EMAIL]")),t.phones&&(n=n.replace(oe.phones,"[PHONE]")),n}function N(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=Be(e);return n.length>re&&(n=n.slice(0,re)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Ae(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function qe(){let e=globalThis;return e[K]||(e[K]=new async_hooks.AsyncLocalStorage),e[K]}var ue=qe();function I(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ue.getStore()}function L(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function Pe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ue(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function $e(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??I(),i=I(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,style:n.style,pendingToolCalls:new Map};return ue.run(a,async()=>{let u,p;try{return u=await t(),u}catch(s){throw p=s instanceof Error?s:new Error(String(s)),s}finally{Ke(a,p?void 0:u,p);}})}var je=["text","content","message","output","response","result","answer"];function Ne(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of je)if(o in r&&typeof r[o]=="string")return r[o];return e}function Ke(e,t,n){let r=T();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),i=Date.now()-e.startTime,a=n?null:Ne(t,e.outputKey,e.outputTransform),u={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata,...e.style?{_style:e.style}:{}},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(u);}function Le(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Pe(e.toolCallId);j({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n,...e.style?{_style:e.style}:{}}}),e.toolCallId&&Ue(e.toolCallId);}var g="bedrock";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="BedrockRuntimeClient")return true;let n=e;return typeof n.send!="function"||!n.config||typeof n.config!="object"?false:"region"in n.config}function ce(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="send"&&typeof i=="function"?ze(i.bind(n)):i}})}function ze(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Fe(e,n);case "ConverseStreamCommand":return Ge(e,n);case "InvokeModelCommand":return Je(e,n);case "InvokeModelWithResponseStreamCommand":return We(e,n);default:return e(n)}}}async function Fe(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=C({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:le(o),durationMs:i,status:"success",streaming:!1});if(a){let u=pe(o);u.length>0&&L(u,a);}return o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Ge(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:Ve(o.stream,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Ve(e,t,n){let r={output:{message:{role:"assistant",content:[]}},usage:{inputTokens:0,outputTokens:0}},o=null,i,a=false,u=new Map,p=new Map;try{for await(let s of e){if(s.contentBlockStart){let c=s.contentBlockStart.contentBlockIndex;if(s.contentBlockStart.start?.toolUse){let d=s.contentBlockStart.start.toolUse;u.set(c,{toolUse:{toolUseId:d.toolUseId,name:d.name,input:{}}}),p.set(c,"");}else u.set(c,{text:""});}if(s.contentBlockDelta){let c=s.contentBlockDelta.contentBlockIndex,d=u.get(c);if(d&&s.contentBlockDelta.delta?.text&&(a||(a=!0,i=Date.now()-n),d.text=(d.text||"")+s.contentBlockDelta.delta.text),d?.toolUse&&s.contentBlockDelta.delta?.toolUse?.input){let y=p.get(c)||"";p.set(c,y+s.contentBlockDelta.delta.toolUse.input);}}if(s.contentBlockStop){let c=s.contentBlockStop.contentBlockIndex,d=u.get(c),y=p.get(c);if(d?.toolUse&&y)try{d.toolUse.input=JSON.parse(y);}catch{}}s.messageStop?.stopReason&&(r.stopReason=s.messageStop.stopReason),s.metadata?.usage&&(r.usage={inputTokens:s.metadata.usage.inputTokens||0,outputTokens:s.metadata.usage.outputTokens||0}),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n,c=Array.from(u.entries()).sort((d,y)=>d[0]-y[0]).map(([,d])=>d);if(r.output.message.content=c,o)h({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=C({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:le(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=pe(r);y.length>0&&L(y,d);}}}}async function Je(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Ye(o.body);return C({provider:g,model:r.modelId||"unknown",input:E(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function We(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:He(o.body,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*He(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Xe(i.chunk.bytes);a&&r.push(a);}yield i;}}catch(i){throw o=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-n;o?h({provider:g,model:t.modelId||"unknown",input:E(t.body),error:o,durationMs:i,streaming:true}):C({provider:g,model:t.modelId||"unknown",input:E(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function le(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function pe(e){let t=[],n=e.output?.message?.content;if(Array.isArray(n))for(let r of n)r.toolUse?.toolUseId&&t.push(r.toolUse.toolUseId);return t}function E(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Ye(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Xe(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Bt(e,t){return t&&ie(t),_().disabled?(l("Tracing disabled, returning unwrapped client"),e):de(e)?(V("bedrock"),ce(e)):(R("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
3
3
|
exports.captureSpan=j;exports.flush=Ee;exports.getTraceContext=f;exports.init=xe;exports.isEnabled=Ce;exports.observe=Bt;exports.span=Le;exports.trace=$e;//# sourceMappingURL=bedrock.js.map
|
|
4
4
|
//# sourceMappingURL=bedrock.js.map
|