@lelemondev/sdk 0.9.6 → 0.9.7
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 +46 -1
- 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 +2 -2
- package/dist/bedrock.mjs +2 -2
- package/dist/{capture-ChybLulj.d.mts → capture-CC0517bj.d.mts} +68 -9
- package/dist/{capture-ChybLulj.d.ts → capture-CC0517bj.d.ts} +68 -9
- package/dist/gemini.d.mts +2 -2
- package/dist/gemini.d.ts +2 -2
- package/dist/gemini.js +2 -2
- package/dist/gemini.mjs +2 -2
- 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 +2 -2
- package/dist/openai.mjs +2 -2
- 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
|
@@ -9,6 +9,16 @@ interface ServiceConfig {
|
|
|
9
9
|
/** Deployment environment (e.g., "production", "staging", "development") */
|
|
10
10
|
environment?: string;
|
|
11
11
|
}
|
|
12
|
+
interface RedactionConfig {
|
|
13
|
+
/** Custom regex patterns to redact (replaced with [REDACTED]) */
|
|
14
|
+
patterns?: RegExp[];
|
|
15
|
+
/** Additional key names to redact (case-insensitive, partial match) */
|
|
16
|
+
keys?: string[];
|
|
17
|
+
/** Redact all email addresses (replaced with [EMAIL]) */
|
|
18
|
+
emails?: boolean;
|
|
19
|
+
/** Redact phone numbers with 9+ digits (replaced with [PHONE]) */
|
|
20
|
+
phones?: boolean;
|
|
21
|
+
}
|
|
12
22
|
interface LelemonConfig {
|
|
13
23
|
/** API key (or set LELEMON_API_KEY env var) */
|
|
14
24
|
apiKey?: string;
|
|
@@ -26,6 +36,8 @@ interface LelemonConfig {
|
|
|
26
36
|
requestTimeoutMs?: number;
|
|
27
37
|
/** Service metadata for telemetry */
|
|
28
38
|
service?: ServiceConfig;
|
|
39
|
+
/** Optional PII redaction configuration */
|
|
40
|
+
redaction?: RedactionConfig;
|
|
29
41
|
}
|
|
30
42
|
interface SDKTelemetry {
|
|
31
43
|
/** SDK name */
|
|
@@ -139,6 +151,10 @@ interface TraceContext {
|
|
|
139
151
|
metadata?: Record<string, unknown>;
|
|
140
152
|
/** Trace tags */
|
|
141
153
|
tags?: string[];
|
|
154
|
+
/** Output extraction config */
|
|
155
|
+
outputKey?: string | false;
|
|
156
|
+
/** Output transform function */
|
|
157
|
+
outputTransform?: (result: unknown) => unknown;
|
|
142
158
|
/** Map of toolCallId → llmSpanId for linking tool spans to their parent LLM */
|
|
143
159
|
pendingToolCalls: Map<string, string>;
|
|
144
160
|
}
|
|
@@ -151,6 +167,38 @@ interface TraceOptions {
|
|
|
151
167
|
metadata?: Record<string, unknown>;
|
|
152
168
|
/** Tags for filtering */
|
|
153
169
|
tags?: string[];
|
|
170
|
+
/**
|
|
171
|
+
* Key to extract from result object for cleaner output display.
|
|
172
|
+
* If not specified, auto-detection tries: text, content, message, output, response, result, answer.
|
|
173
|
+
* Set to `false` to disable auto-extraction and show raw result.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* // Auto-extract 'text' field
|
|
177
|
+
* trace({ name: 'agent' }, async () => ({ text: 'hello', tokens: 100 }));
|
|
178
|
+
* // Output: "hello"
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* // Explicit key
|
|
182
|
+
* trace({ name: 'agent', outputKey: 'response' }, async () => ({ response: 'hello' }));
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* // Disable auto-extraction
|
|
186
|
+
* trace({ name: 'agent', outputKey: false }, async () => ({ a: 1, b: 2 }));
|
|
187
|
+
* // Output: { a: 1, b: 2 }
|
|
188
|
+
*/
|
|
189
|
+
outputKey?: string | false;
|
|
190
|
+
/**
|
|
191
|
+
* Transform function for custom output formatting.
|
|
192
|
+
* Takes precedence over outputKey.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* trace({
|
|
196
|
+
* name: 'agent',
|
|
197
|
+
* outputTransform: (r) => `Response: ${r.text} (${r.tokens} tokens)`
|
|
198
|
+
* }, async () => ({ text: 'hello', tokens: 100 }));
|
|
199
|
+
* // Output: "Response: hello (100 tokens)"
|
|
200
|
+
*/
|
|
201
|
+
outputTransform?: (result: unknown) => unknown;
|
|
154
202
|
}
|
|
155
203
|
interface SpanOptions {
|
|
156
204
|
/** Span type */
|
|
@@ -179,22 +227,33 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
179
227
|
/**
|
|
180
228
|
* Execute a function within a trace context.
|
|
181
229
|
* Creates a root "agent" span that contains all LLM calls and tool executions.
|
|
182
|
-
* The result of the function becomes the output of the root span.
|
|
183
230
|
*
|
|
184
|
-
*
|
|
231
|
+
* **Output Auto-Extraction:** If the function returns an object with common text fields
|
|
232
|
+
* (`text`, `content`, `message`, `output`, `response`, `result`, `answer`),
|
|
233
|
+
* the SDK automatically extracts that field for cleaner display.
|
|
234
|
+
* Use `outputKey` to specify a custom field, or `outputKey: false` to disable.
|
|
235
|
+
*
|
|
236
|
+
* @example Simple usage
|
|
185
237
|
* ```typescript
|
|
186
238
|
* await trace('sales-agent', async () => {
|
|
187
|
-
*
|
|
188
|
-
*
|
|
239
|
+
* return { text: 'Hello!', tokens: 100 };
|
|
240
|
+
* // Output shown: "Hello!" (auto-extracted from 'text')
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @example With options and explicit outputKey
|
|
245
|
+
* ```typescript
|
|
246
|
+
* await trace({ name: 'agent', outputKey: 'reply' }, async () => {
|
|
247
|
+
* return { reply: 'Hello!', cost: 0.01 };
|
|
248
|
+
* // Output shown: "Hello!"
|
|
189
249
|
* });
|
|
190
250
|
* ```
|
|
191
251
|
*
|
|
192
|
-
* @example
|
|
252
|
+
* @example Disable auto-extraction
|
|
193
253
|
* ```typescript
|
|
194
|
-
* await trace({ name: '
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* return client.send(new ConverseCommand({...}));
|
|
254
|
+
* await trace({ name: 'agent', outputKey: false }, async () => {
|
|
255
|
+
* return { a: 1, b: 2 };
|
|
256
|
+
* // Output shown: { a: 1, b: 2 }
|
|
198
257
|
* });
|
|
199
258
|
* ```
|
|
200
259
|
*/
|
|
@@ -9,6 +9,16 @@ interface ServiceConfig {
|
|
|
9
9
|
/** Deployment environment (e.g., "production", "staging", "development") */
|
|
10
10
|
environment?: string;
|
|
11
11
|
}
|
|
12
|
+
interface RedactionConfig {
|
|
13
|
+
/** Custom regex patterns to redact (replaced with [REDACTED]) */
|
|
14
|
+
patterns?: RegExp[];
|
|
15
|
+
/** Additional key names to redact (case-insensitive, partial match) */
|
|
16
|
+
keys?: string[];
|
|
17
|
+
/** Redact all email addresses (replaced with [EMAIL]) */
|
|
18
|
+
emails?: boolean;
|
|
19
|
+
/** Redact phone numbers with 9+ digits (replaced with [PHONE]) */
|
|
20
|
+
phones?: boolean;
|
|
21
|
+
}
|
|
12
22
|
interface LelemonConfig {
|
|
13
23
|
/** API key (or set LELEMON_API_KEY env var) */
|
|
14
24
|
apiKey?: string;
|
|
@@ -26,6 +36,8 @@ interface LelemonConfig {
|
|
|
26
36
|
requestTimeoutMs?: number;
|
|
27
37
|
/** Service metadata for telemetry */
|
|
28
38
|
service?: ServiceConfig;
|
|
39
|
+
/** Optional PII redaction configuration */
|
|
40
|
+
redaction?: RedactionConfig;
|
|
29
41
|
}
|
|
30
42
|
interface SDKTelemetry {
|
|
31
43
|
/** SDK name */
|
|
@@ -139,6 +151,10 @@ interface TraceContext {
|
|
|
139
151
|
metadata?: Record<string, unknown>;
|
|
140
152
|
/** Trace tags */
|
|
141
153
|
tags?: string[];
|
|
154
|
+
/** Output extraction config */
|
|
155
|
+
outputKey?: string | false;
|
|
156
|
+
/** Output transform function */
|
|
157
|
+
outputTransform?: (result: unknown) => unknown;
|
|
142
158
|
/** Map of toolCallId → llmSpanId for linking tool spans to their parent LLM */
|
|
143
159
|
pendingToolCalls: Map<string, string>;
|
|
144
160
|
}
|
|
@@ -151,6 +167,38 @@ interface TraceOptions {
|
|
|
151
167
|
metadata?: Record<string, unknown>;
|
|
152
168
|
/** Tags for filtering */
|
|
153
169
|
tags?: string[];
|
|
170
|
+
/**
|
|
171
|
+
* Key to extract from result object for cleaner output display.
|
|
172
|
+
* If not specified, auto-detection tries: text, content, message, output, response, result, answer.
|
|
173
|
+
* Set to `false` to disable auto-extraction and show raw result.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* // Auto-extract 'text' field
|
|
177
|
+
* trace({ name: 'agent' }, async () => ({ text: 'hello', tokens: 100 }));
|
|
178
|
+
* // Output: "hello"
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* // Explicit key
|
|
182
|
+
* trace({ name: 'agent', outputKey: 'response' }, async () => ({ response: 'hello' }));
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* // Disable auto-extraction
|
|
186
|
+
* trace({ name: 'agent', outputKey: false }, async () => ({ a: 1, b: 2 }));
|
|
187
|
+
* // Output: { a: 1, b: 2 }
|
|
188
|
+
*/
|
|
189
|
+
outputKey?: string | false;
|
|
190
|
+
/**
|
|
191
|
+
* Transform function for custom output formatting.
|
|
192
|
+
* Takes precedence over outputKey.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* trace({
|
|
196
|
+
* name: 'agent',
|
|
197
|
+
* outputTransform: (r) => `Response: ${r.text} (${r.tokens} tokens)`
|
|
198
|
+
* }, async () => ({ text: 'hello', tokens: 100 }));
|
|
199
|
+
* // Output: "Response: hello (100 tokens)"
|
|
200
|
+
*/
|
|
201
|
+
outputTransform?: (result: unknown) => unknown;
|
|
154
202
|
}
|
|
155
203
|
interface SpanOptions {
|
|
156
204
|
/** Span type */
|
|
@@ -179,22 +227,33 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
179
227
|
/**
|
|
180
228
|
* Execute a function within a trace context.
|
|
181
229
|
* Creates a root "agent" span that contains all LLM calls and tool executions.
|
|
182
|
-
* The result of the function becomes the output of the root span.
|
|
183
230
|
*
|
|
184
|
-
*
|
|
231
|
+
* **Output Auto-Extraction:** If the function returns an object with common text fields
|
|
232
|
+
* (`text`, `content`, `message`, `output`, `response`, `result`, `answer`),
|
|
233
|
+
* the SDK automatically extracts that field for cleaner display.
|
|
234
|
+
* Use `outputKey` to specify a custom field, or `outputKey: false` to disable.
|
|
235
|
+
*
|
|
236
|
+
* @example Simple usage
|
|
185
237
|
* ```typescript
|
|
186
238
|
* await trace('sales-agent', async () => {
|
|
187
|
-
*
|
|
188
|
-
*
|
|
239
|
+
* return { text: 'Hello!', tokens: 100 };
|
|
240
|
+
* // Output shown: "Hello!" (auto-extracted from 'text')
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @example With options and explicit outputKey
|
|
245
|
+
* ```typescript
|
|
246
|
+
* await trace({ name: 'agent', outputKey: 'reply' }, async () => {
|
|
247
|
+
* return { reply: 'Hello!', cost: 0.01 };
|
|
248
|
+
* // Output shown: "Hello!"
|
|
189
249
|
* });
|
|
190
250
|
* ```
|
|
191
251
|
*
|
|
192
|
-
* @example
|
|
252
|
+
* @example Disable auto-extraction
|
|
193
253
|
* ```typescript
|
|
194
|
-
* await trace({ name: '
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* return client.send(new ConverseCommand({...}));
|
|
254
|
+
* await trace({ name: 'agent', outputKey: false }, async () => {
|
|
255
|
+
* return { a: 1, b: 2 };
|
|
256
|
+
* // Output shown: { a: 1, b: 2 }
|
|
198
257
|
* });
|
|
199
258
|
* ```
|
|
200
259
|
*/
|
package/dist/gemini.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-CC0517bj.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-CC0517bj.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Google Gemini Provider Entry Point
|
package/dist/gemini.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-CC0517bj.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-CC0517bj.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Google Gemini Provider Entry Point
|
package/dist/gemini.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('async_hooks');/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var pe=Object.defineProperty;var fe=(e,t,n)=>t in e?pe(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var N=(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 v=(e,t,n)=>fe(e,typeof t!="symbol"?t+"":t,n);var X=ge((st,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.9.6",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"},"./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"],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/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var U=false;function z(e){U=e;}function g(){return U?true:me("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&_("debug",e,t);}function q(e,t){g()&&_("info",e,t);}function I(e,t){_("warn",e,t);}function D(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function V(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function B(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function Y(e,t){g()&&console.log(`${p} 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(`${p} ${t}`,n):r(`${p} ${t}`);}function me(e){if(typeof process<"u"&&process.env)return process.env[e]}var he=10,Ce=1e3,ye=1e4,M=class{constructor(t){v(this,"config");v(this,"queue",[]);v(this,"flushPromise",null);v(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??he,flushIntervalMs:t.flushIntervalMs??Ce,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}),B(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;W(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),Y(a.status,Date.now()-u),!a.ok){let k=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${k}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var we="@lelemondev/sdk",Te="nodejs";function ve(){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 Se(){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 N<"u")return X().version??"unknown"}catch{}return "unknown"}var b=null;function Q(e){if(!b){let n=ve(),r=Se();b={"telemetry.sdk.name":we,"telemetry.sdk.version":xe(),"telemetry.sdk.language":Te},n&&(b["process.runtime.name"]=n.name,b["process.runtime.version"]=n.version),r&&(b["os.type"]=r);}let t={...b};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var O={},C=null,$=null,Z="https://api.lelemon.dev";function Ie(e={}){O=e,e.debug&&z(true),$=Q(e.service),q("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),C=te(e),C.isEnabled()?q("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function ee(){return O}function R(){return $}function Ee(){return y().isEnabled()}function y(){return C||(C=te(O)),C}async function Me(){C&&await C.flush();}function te(e){let t=e.apiKey??Re("LELEMON_API_KEY");return !t&&!e.disabled&&I("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??Z,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 A=Symbol.for("@lelemondev/sdk:globalContext");function re(){let e=globalThis;return e[A]||(e[A]={context:{}}),e[A]}function oe(e){re().context=e,l("Global context updated",e);}function x(){return re().context}function G(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=T(),s=R(),i={provider:e.provider,model:e.model,input:K(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return D(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function w(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=R(),s={provider:e.provider,model:e.model,input:K(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:T(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};D(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=R(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:K(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:T(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Ge=["api_key","apikey","password","secret","authorization"],Pe=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],qe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function De(e){let t=e.toLowerCase();return qe.includes(t)?false:!!(Ge.some(n=>t.includes(n))||Pe.some(n=>t.includes(n)))}function K(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")return e.length>ne?e.slice(0,ne)+"...[truncated]":e;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))De(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function $e(){let e=globalThis;return e[L]||(e[L]=new async_hooks.AsyncLocalStorage),e[L]}var se=$e();function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return se.getStore()}function P(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 Oe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ae(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function je(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),s=T(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return se.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{Ke(i,u?void 0:d,u);}})}function Ke(e,t,n){let r=y();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),s=Date.now()-e.startTime,i=n?null:t,d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}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=Oe(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&&Ae(e.toolCallId);}var m="gemini";function ie(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ae(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Ne(s.bind(n)):s}})}function Ne(e){return function(n){let r=e(n);return Ue(r,n.model)}}function Ue(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?ze(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Fe(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ve(s.bind(n),t):s}})}function ze(e,t){return async function(r){let o=Date.now(),s=de(r);try{let i=await e(r),d=Date.now()-o,u=ce(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=le(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Fe(e,t){return async function(r){let o=Date.now(),s=de(r);try{let i=await e(r),d=ue(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ue(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],k=c[c.length-1];k?.text!==void 0?k.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)w({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=G({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Ye(o.candidates);c.length>0&&P(c,a);}}}}function Ve(e,t){return function(r){let o=e(r);return Be(o,t)}}function Be(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?He(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?We(s.bind(n),t):s}})}function He(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=ce(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=le(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function We(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ue(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function de(e){return typeof e=="string"?e:e.contents?e.contents:e}function ce(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function le(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Ye(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function qt(e,t){return t&&oe(t),ee().disabled?(l("Tracing disabled, returning unwrapped client"),e):ie(e)?(F("gemini"),ae(e)):(I("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
-
exports.captureSpan=
|
|
2
|
+
var ge=Object.defineProperty;var me=(e,t,n)=>t in e?ge(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var U=(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 he=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var v=(e,t,n)=>me(e,typeof t!="symbol"?t+"":t,n);var Z=he((ct,Te)=>{Te.exports={name:"@lelemondev/sdk",version:"0.9.7",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"},"./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"],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/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var z=false;function F(e){z=e;}function g(){return z?true:ye("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&$("debug",e,t);}function D(e,t){g()&&$("info",e,t);}function I(e,t){$("warn",e,t);}function q(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function B(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function V(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function H(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function W(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){g()&&console.log(`${p} 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(`${p} ${t}`,n):r(`${p} ${t}`);}function ye(e){if(typeof process<"u"&&process.env)return process.env[e]}var Ce=10,be=1e3,we=1e4,M=class{constructor(t){v(this,"config");v(this,"queue",[]);v(this,"flushPromise",null);v(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??Ce,flushIntervalMs:t.flushIntervalMs??be,requestTimeoutMs:t.requestTimeoutMs??we};}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}`,s=new AbortController,i=r?JSON.stringify(r):void 0;Y(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),X(a.status,Date.now()-u),!a.ok){let x=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${x}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var ve="@lelemondev/sdk",Se="nodejs";function ke(){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 xe(){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 U<"u")return Z().version??"unknown"}catch{}return "unknown"}var b=null;function Q(e){if(!b){let n=ke(),r=xe();b={"telemetry.sdk.name":ve,"telemetry.sdk.version":Ie(),"telemetry.sdk.language":Se},n&&(b["process.runtime.name"]=n.name,b["process.runtime.version"]=n.version),r&&(b["os.type"]=r);}let t={...b};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var A={},y=null,O=null,ee="https://api.lelemon.dev";function Me(e={}){A=e,e.debug&&F(true),O=Q(e.service),D("Initializing SDK",{endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??false,telemetry:O}),y=te(e),y.isEnabled()?D("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function R(){return A}function G(){return O}function Re(){return C().isEnabled()}function C(){return y||(y=te(A)),y}async function Ge(){y&&await y.flush();}function te(e){let t=e.apiKey??_e("LELEMON_API_KEY");return !t&&!e.disabled&&I("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function _e(e){if(typeof process<"u"&&process.env)return process.env[e]}var j=Symbol.for("@lelemondev/sdk:globalContext");function oe(){let e=globalThis;return e[j]||(e[j]={context:{}}),e[j]}function se(e){oe().context=e,l("Global context updated",e);}function k(){return oe().context}function _(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=k(),r=f(),o=T(),s=G(),i={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:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function w(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=k(),r=f(),o=G(),s={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:T(),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"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function K(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=k(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=G(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={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:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:T(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Pe=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],qe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],re={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ie(){return R().redaction??{}}function $e(e){let t=e.toLowerCase();return qe.includes(t)?false:!!(Pe.some(r=>t.includes(r))||De.some(r=>t.includes(r))||(ie().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Oe(e){let t=ie(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(re.emails,"[EMAIL]")),t.phones&&(n=n.replace(re.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=Oe(e);return n.length>ne&&(n=n.slice(0,ne)+"...[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))$e(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var N=Symbol.for("@lelemondev/sdk:traceStorage");function je(){let e=globalThis;return e[N]||(e[N]=new async_hooks.AsyncLocalStorage),e[N]}var ae=je();function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ae.getStore()}function P(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 Ke(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Le(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Ne(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),s=T(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,pendingToolCalls:new Map};return ae.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{Fe(i,u?void 0:d,u);}})}var Ue=["text","content","message","output","response","result","answer"];function ze(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 Ue)if(o in r&&typeof r[o]=="string")return r[o];return e}function Fe(e,t,n){let r=C();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=k(),s=Date.now()-e.startTime,i=n?null:ze(t,e.outputKey,e.outputTransform),d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Be(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=Ke(e.toolCallId);K({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&&Le(e.toolCallId);}var m="gemini";function ue(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function de(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Ve(s.bind(n)):s}})}function Ve(e){return function(n){let r=e(n);return He(r,n.model)}}function He(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?We(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Ye(s.bind(n),t):r==="startChat"&&typeof s=="function"?Xe(s.bind(n),t):s}})}function We(e,t){return async function(r){let o=Date.now(),s=le(r);try{let i=await e(r),d=Date.now()-o,u=pe(i.response),a=_({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=fe(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Ye(e,t){return async function(r){let o=Date.now(),s=le(r);try{let i=await e(r),d=ce(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ce(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],x=c[c.length-1];x?.text!==void 0?x.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)w({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=_({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=et(o.candidates);c.length>0&&P(c,a);}}}}function Xe(e,t){return function(r){let o=e(r);return Ze(o,t)}}function Ze(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Je(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?Qe(s.bind(n),t):s}})}function Je(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=pe(i.response),a=_({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=fe(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Qe(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ce(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function le(e){return typeof e=="string"?e:e.contents?e.contents:e}function pe(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function fe(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function et(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function At(e,t){return t&&se(t),R().disabled?(l("Tracing disabled, returning unwrapped client"),e):ue(e)?(B("gemini"),de(e)):(I("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
+
exports.captureSpan=K;exports.flush=Ge;exports.getTraceContext=f;exports.init=Me;exports.isEnabled=Re;exports.observe=At;exports.span=Be;exports.trace=Ne;//# sourceMappingURL=gemini.js.map
|
|
4
4
|
//# sourceMappingURL=gemini.js.map
|
package/dist/gemini.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var le=Object.defineProperty;var pe=(e,t,n)=>t in e?le(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var L=(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 fe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>pe(e,typeof t!="symbol"?t+"":t,n);var Y=fe((nt,ye)=>{ye.exports={name:"@lelemondev/sdk",version:"0.9.6",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"},"./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"],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/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var N=false;function U(e){N=e;}function g(){return N?true:ge("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&D("debug",e,t);}function P(e,t){g()&&D("info",e,t);}function k(e,t){D("warn",e,t);}function q(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function I(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function z(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function F(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function B(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function H(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function W(e,t){g()&&console.log(`${p} Response: status=${e} duration=${t}ms`);}function D(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${p} ${t}`,n):r(`${p} ${t}`);}function ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,he=1e3,Ce=1e4,E=class{constructor(t){T(this,"config");T(this,"queue",[]);T(this,"flushPromise",null);T(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??me,flushIntervalMs:t.flushIntervalMs??he,requestTimeoutMs:t.requestTimeoutMs??Ce};}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();F(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),V(t.length,Date.now()-n);}catch(r){B(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;H(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),W(a.status,Date.now()-u),!a.ok){let x=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${x}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var be="@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 L<"u")return Y().version??"unknown"}catch{}return "unknown"}var y=null;function J(e){if(!y){let n=Te(),r=ve();y={"telemetry.sdk.name":be,"telemetry.sdk.version":Se(),"telemetry.sdk.language":we},n&&(y["process.runtime.name"]=n.name,y["process.runtime.version"]=n.version),r&&(y["os.type"]=r);}let t={...y};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var $={},h=null,_=null,Q="https://api.lelemon.dev";function ke(e={}){$=e,e.debug&&U(true),_=J(e.service),P("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:_}),h=ee(e),h.isEnabled()?P("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Z(){return $}function M(){return _}function Ie(){return C().isEnabled()}function C(){return h||(h=ee($)),h}async function Ee(){h&&await h.flush();}function ee(e){let t=e.apiKey??Me("LELEMON_API_KEY");return !t&&!e.disabled&&k("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new E({apiKey:t??"",endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Me(e){if(typeof process<"u"&&process.env)return process.env[e]}var O=Symbol.for("@lelemondev/sdk:globalContext");function ne(){let e=globalThis;return e[O]||(e[O]={context:{}}),e[O]}function re(e){ne().context=e,l("Global context updated",e);}function S(){return ne().context}function R(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=S(),r=f(),o=w(),s=M(),i={provider:e.provider,model:e.model,input:j(e.input),rawResponse:e.rawResponse?v(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));return}}function b(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=S(),r=f(),o=M(),s={provider:e.provider,model:e.model,input:j(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:w(),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"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));}}function A(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=S(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=M(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:j(e.input),output:v(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:w(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){I("unknown",t instanceof Error?t:new Error(String(t)));}}var te=1e5,Re=["api_key","apikey","password","secret","authorization"],Ge=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Pe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function qe(e){let t=e.toLowerCase();return Pe.includes(t)?false:!!(Re.some(n=>t.includes(n))||Ge.some(n=>t.includes(n)))}function j(e){return v(e,0)}function v(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string")return e.length>te?e.slice(0,te)+"...[truncated]":e;if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>v(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))qe(r)?n[r]="[REDACTED]":n[r]=v(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function _e(){let e=globalThis;return e[K]||(e[K]=new AsyncLocalStorage),e[K]}var oe=_e();function w(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return oe.getStore()}function G(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 $e(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Oe(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Ae(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??w(),s=w(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return oe.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{je(i,u?void 0:d,u);}})}function je(e,t,n){let r=C();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=S(),s=Date.now()-e.startTime,i=n?null:t,d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Ke(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=$e(e.toolCallId);A({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&&Oe(e.toolCallId);}var m="gemini";function se(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ie(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Le(s.bind(n)):s}})}function Le(e){return function(n){let r=e(n);return Ne(r,n.model)}}function Ne(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?Ue(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?ze(s.bind(n),t):r==="startChat"&&typeof s=="function"?Fe(s.bind(n),t):s}})}function Ue(e,t){return async function(r){let o=Date.now(),s=ue(r);try{let i=await e(r),d=Date.now()-o,u=de(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ce(i.response);c.length>0&&G(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function ze(e,t){return async function(r){let o=Date.now(),s=ue(r);try{let i=await e(r),d=ae(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ae(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],x=c[c.length-1];x?.text!==void 0?x.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)b({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=R({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=We(o.candidates);c.length>0&&G(c,a);}}}}function Fe(e,t){return function(r){let o=e(r);return Ve(o,t)}}function Ve(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Be(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?He(s.bind(n),t):s}})}function Be(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=de(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ce(i.response);c.length>0&&G(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function He(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ae(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function ue(e){return typeof e=="string"?e:e.contents?e.contents:e}function de(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function ce(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function We(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function xt(e,t){return t&&re(t),Z().disabled?(l("Tracing disabled, returning unwrapped client"),e):se(e)?(z("gemini"),ie(e)):(k("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
-
export{
|
|
2
|
+
var fe=Object.defineProperty;var ge=(e,t,n)=>t in e?fe(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var N=(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 T=(e,t,n)=>ge(e,typeof t!="symbol"?t+"":t,n);var X=me((at,we)=>{we.exports={name:"@lelemondev/sdk",version:"0.9.7",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"},"./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"],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/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var U=false;function z(e){U=e;}function g(){return U?true:he("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&q("debug",e,t);}function P(e,t){g()&&q("info",e,t);}function x(e,t){q("warn",e,t);}function D(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function I(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function B(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function Y(e,t){g()&&console.log(`${p} 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(`${p} ${t}`,n):r(`${p} ${t}`);}function he(e){if(typeof process<"u"&&process.env)return process.env[e]}var ye=10,Ce=1e3,be=1e4,E=class{constructor(t){T(this,"config");T(this,"queue",[]);T(this,"flushPromise",null);T(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ye,flushIntervalMs:t.flushIntervalMs??Ce,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();B(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),V(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;W(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),Y(a.status,Date.now()-u),!a.ok){let k=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${k}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var Te="@lelemondev/sdk",ve="nodejs";function Se(){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 ke(){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 N<"u")return X().version??"unknown"}catch{}return "unknown"}var C=null;function J(e){if(!C){let n=Se(),r=ke();C={"telemetry.sdk.name":Te,"telemetry.sdk.version":xe(),"telemetry.sdk.language":ve},n&&(C["process.runtime.name"]=n.name,C["process.runtime.version"]=n.version),r&&(C["os.type"]=r);}let t={...C};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var O={},h=null,$=null,Q="https://api.lelemon.dev";function Ee(e={}){O=e,e.debug&&z(true),$=J(e.service),P("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),h=ee(e),h.isEnabled()?P("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function M(){return O}function R(){return $}function Me(){return y().isEnabled()}function y(){return h||(h=ee(O)),h}async function Re(){h&&await h.flush();}function ee(e){let t=e.apiKey??Ge("LELEMON_API_KEY");return !t&&!e.disabled&&x("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new E({apiKey:t??"",endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var A=Symbol.for("@lelemondev/sdk:globalContext");function re(){let e=globalThis;return e[A]||(e[A]={context:{}}),e[A]}function oe(e){re().context=e,l("Global context updated",e);}function S(){return re().context}function G(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=S(),r=f(),o=w(),s=R(),i={provider:e.provider,model:e.model,input:K(e.input),rawResponse:e.rawResponse?v(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return D(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));return}}function b(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=S(),r=f(),o=R(),s={provider:e.provider,model:e.model,input:K(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:w(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};D(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=S(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=R(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:K(e.input),output:v(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:w(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){I("unknown",t instanceof Error?t:new Error(String(t)));}}var te=1e5,_e=["api_key","apikey","password","secret","authorization"],Pe=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],De=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],ne={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function se(){return M().redaction??{}}function qe(e){let t=e.toLowerCase();return De.includes(t)?false:!!(_e.some(r=>t.includes(r))||Pe.some(r=>t.includes(r))||(se().keys??[]).some(r=>t.includes(r.toLowerCase())))}function $e(e){let t=se(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(ne.emails,"[EMAIL]")),t.phones&&(n=n.replace(ne.phones,"[PHONE]")),n}function K(e){return v(e,0)}function v(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=$e(e);return n.length>te&&(n=n.slice(0,te)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>v(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))qe(r)?n[r]="[REDACTED]":n[r]=v(o,t+1);return n}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function Ae(){let e=globalThis;return e[L]||(e[L]=new AsyncLocalStorage),e[L]}var ie=Ae();function w(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ie.getStore()}function _(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 je(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ke(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Le(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??w(),s=w(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,pendingToolCalls:new Map};return ie.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{ze(i,u?void 0:d,u);}})}var Ne=["text","content","message","output","response","result","answer"];function Ue(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 ze(e,t,n){let r=y();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=S(),s=Date.now()-e.startTime,i=n?null:Ue(t,e.outputKey,e.outputTransform),d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Fe(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=je(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&&Ke(e.toolCallId);}var m="gemini";function ae(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ue(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Be(s.bind(n)):s}})}function Be(e){return function(n){let r=e(n);return Ve(r,n.model)}}function Ve(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?He(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?We(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ye(s.bind(n),t):s}})}function He(e,t){return async function(r){let o=Date.now(),s=ce(r);try{let i=await e(r),d=Date.now()-o,u=le(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=pe(i.response);c.length>0&&_(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function We(e,t){return async function(r){let o=Date.now(),s=ce(r);try{let i=await e(r),d=de(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*de(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],k=c[c.length-1];k?.text!==void 0?k.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)b({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=G({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Qe(o.candidates);c.length>0&&_(c,a);}}}}function Ye(e,t){return function(r){let o=e(r);return Xe(o,t)}}function Xe(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Ze(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?Je(s.bind(n),t):s}})}function Ze(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=le(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=pe(i.response);c.length>0&&_(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Je(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=de(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function ce(e){return typeof e=="string"?e:e.contents?e.contents:e}function le(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function pe(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Qe(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Rt(e,t){return t&&oe(t),M().disabled?(l("Tracing disabled, returning unwrapped client"),e):ae(e)?(F("gemini"),ue(e)):(x("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
+
export{j as captureSpan,Re as flush,f as getTraceContext,Ee as init,Me as isEnabled,Rt as observe,Fe as span,Le as trace};//# sourceMappingURL=gemini.mjs.map
|
|
4
4
|
//# sourceMappingURL=gemini.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, 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-CC0517bj.mjs';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, 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-CC0517bj.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Observe Function
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, 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-CC0517bj.js';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, 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-CC0517bj.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Observe Function
|