@lelemondev/sdk 0.9.5 → 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 ce=Object.defineProperty;var le=(e,t,n)=>t in e?ce(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var K=(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 v=(e,t,n)=>le(e,typeof t!="symbol"?t+"":t,n);var W=pe((nt,Ce)=>{Ce.exports={name:"@lelemondev/sdk",version:"0.9.5",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 L=false;function N(e){L=e;}function g(){return L?true:fe("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 M(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function U(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function z(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function F(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function V(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function B(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function H(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 fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var ge=10,me=1e3,he=1e4,E=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??ge,flushIntervalMs:t.flushIntervalMs??me,requestTimeoutMs:t.requestTimeoutMs??he};}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();z(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),F(t.length,Date.now()-n);}catch(r){V(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;B(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),H(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 ye="@lelemondev/sdk",we="nodejs";function be(){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 K<"u")return W().version??"unknown"}catch{}return "unknown"}var w=null;function J(e){if(!w){let n=be(),r=Te();w={"telemetry.sdk.name":ye,"telemetry.sdk.version":ve(),"telemetry.sdk.language":we},n&&(w["process.runtime.name"]=n.name,w["process.runtime.version"]=n.version),r&&(w["os.type"]=r);}let t={...w};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,X="https://api.lelemon.dev";function ke(e={}){O=e,e.debug&&N(true),$=J(e.service),q("Initializing SDK",{endpoint:e.endpoint??X,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),C=Z(e),C.isEnabled()?q("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Q(){return O}function R(){return $}function xe(){return y().isEnabled()}function y(){return C||(C=Z(O)),C}async function Ie(){C&&await C.flush();}function Z(e){let t=e.apiKey??Me("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 E({apiKey:t??"",endpoint:e.endpoint??X,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 te={};function ne(e){te=e,l("Global context updated",e);}function k(){return te}function G(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=k(),r=f(),o=T(),s=R(),i={provider:e.provider,model:e.model,input:A(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){M(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=k(),r=f(),o=R(),s={provider:e.provider,model:e.model,input:A(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){M(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=k(),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:A(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){M("unknown",t instanceof Error?t:new Error(String(t)));}}var ee=1e5,Ee=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Ge=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Pe(e){let t=e.toLowerCase();return Ge.includes(t)?false:!!(Ee.some(n=>t.includes(n))||Re.some(n=>t.includes(n)))}function A(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>ee?e.slice(0,ee)+"...[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))Pe(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var re=new async_hooks.AsyncLocalStorage;function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return re.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 De(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function _e(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??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 re.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{Oe(i,u?void 0:d,u);}})}function Oe(e,t,n){let r=y();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=k(),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 je(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=De(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&&_e(e.toolCallId);}var m="gemini";function oe(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 se(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"?Ae(s.bind(n)):s}})}function Ae(e){return function(n){let r=e(n);return Ke(r,n.model)}}function Ke(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?Le(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Ne(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ue(s.bind(n),t):s}})}function Le(e,t){return async function(r){let o=Date.now(),s=ae(r);try{let i=await e(r),d=Date.now()-o,u=ue(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=de(i.response);c.length>0&&P(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 Ne(e,t){return async function(r){let o=Date.now(),s=ae(r);try{let i=await e(r),d=ie(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*ie(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=G({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Be(o.candidates);c.length>0&&P(c,a);}}}}function Ue(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"?Fe(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?Ve(s.bind(n),t):s}})}function Fe(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=ue(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=de(i.response);c.length>0&&P(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 Ve(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ie(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 ae(e){return typeof e=="string"?e:e.contents?e.contents:e}function ue(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function de(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 Be(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&&ne(t),Q().disabled?(l("Tracing disabled, returning unwrapped client"),e):oe(e)?(U("gemini"),se(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 de=Object.defineProperty;var ce=(e,t,n)=>t in e?de(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var A=(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 le=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>ce(e,typeof t!="symbol"?t+"":t,n);var H=le((Ze,he)=>{he.exports={name:"@lelemondev/sdk",version:"0.9.5",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 K=false;function L(e){K=e;}function g(){return K?true:pe("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 x(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 N(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function U(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function z(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function F(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function V(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function B(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 pe(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,ge=1e3,me=1e4,M=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??fe,flushIntervalMs:t.flushIntervalMs??ge,requestTimeoutMs:t.requestTimeoutMs??me};}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();U(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),z(t.length,Date.now()-n);}catch(r){F(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;V(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),B(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 Ce="@lelemondev/sdk",ye="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 be(){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 Te(){try{if(typeof A<"u")return H().version??"unknown"}catch{}return "unknown"}var y=null;function Y(e){if(!y){let n=we(),r=be();y={"telemetry.sdk.name":Ce,"telemetry.sdk.version":Te(),"telemetry.sdk.language":ye},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,J="https://api.lelemon.dev";function Se(e={}){$=e,e.debug&&L(true),_=Y(e.service),P("Initializing SDK",{endpoint:e.endpoint??J,debug:e.debug??false,disabled:e.disabled??false,telemetry:_}),h=Q(e),h.isEnabled()?P("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function X(){return $}function E(){return _}function ke(){return C().isEnabled()}function C(){return h||(h=Q($)),h}async function xe(){h&&await h.flush();}function Q(e){let t=e.apiKey??Ie("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 M({apiKey:t??"",endpoint:e.endpoint??J,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ie(e){if(typeof process<"u"&&process.env)return process.env[e]}var ee={};function te(e){ee=e,l("Global context updated",e);}function S(){return ee}function R(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=S(),r=f(),o=b(),s=E(),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 w(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=S(),r=f(),o=E(),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:b(),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 O(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=E(),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:b(),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 Z=1e5,Me=["api_key","apikey","password","secret","authorization"],Ee=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Re=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Ge(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Me.some(n=>t.includes(n))||Ee.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>Z?e.slice(0,Z)+"...[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))Ge(r)?n[r]="[REDACTED]":n[r]=v(o,t+1);return n}return String(e)}var ne=new AsyncLocalStorage;function b(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ne.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 qe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function De(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??b(),s=b(),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 ne.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{$e(i,u?void 0:d,u);}})}function $e(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 Oe(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=qe(e.toolCallId);O({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&&De(e.toolCallId);}var m="gemini";function re(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 oe(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"?je(s.bind(n)):s}})}function je(e){return function(n){let r=e(n);return Ae(r,n.model)}}function Ae(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?Ke(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Le(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ne(s.bind(n),t):s}})}function Ke(e,t){return async function(r){let o=Date.now(),s=ie(r);try{let i=await e(r),d=Date.now()-o,u=ae(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ue(i.response);c.length>0&&G(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 Le(e,t){return async function(r){let o=Date.now(),s=ie(r);try{let i=await e(r),d=se(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*se(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=R({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Ve(o.candidates);c.length>0&&G(c,a);}}}}function Ne(e,t){return function(r){let o=e(r);return Ue(o,t)}}function Ue(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"?Fe(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=ae(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ue(i.response);c.length>0&&G(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=r;try{let i=await e(r),d=se(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 ie(e){return typeof e=="string"?e:e.contents?e.contents:e}function ae(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function ue(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 Ve(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 Tt(e,t){return t&&te(t),X().disabled?(l("Tracing disabled, returning unwrapped client"),e):re(e)?(N("gemini"),oe(e)):(x("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
|