@lelemondev/sdk 0.9.4 → 0.9.6

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.
@@ -1,4 +1,4 @@
1
1
  import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
2
- var oe=Object.defineProperty;var se=(e,t,n)=>t in e?oe(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var j=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ie=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var w=(e,t,n)=>se(e,typeof t!="symbol"?t+"":t,n);var B=ie((Be,pe)=>{pe.exports={name:"@lelemondev/sdk",version:"0.9.4",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 A=false;function L(e){A=e;}function m(){return A?true:ae("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function c(e,t){m()&&_("debug",e,t);}function E(e,t){m()&&_("info",e,t);}function k(e,t){_("warn",e,t);}function R(e,t,n,r){m()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function S(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function K(e){m()&&console.log(`${p} Wrapped client: provider=${e}`);}function N(e,t){m()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function U(e,t){m()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function z(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function F(e,t,n){m()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function V(e,t){m()&&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 ae(e){if(typeof process<"u"&&process.env)return process.env[e]}var ue=10,de=1e3,ce=1e4,x=class{constructor(t){w(this,"config");w(this,"queue",[]);w(this,"flushPromise",null);w(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ue,flushIntervalMs:t.flushIntervalMs??de,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();N(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),U(t.length,Date.now()-n);}catch(r){z(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;F(t,o,a?.length??0);let s=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),d=Date.now();try{let u=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(s),V(u.status,Date.now()-d),!u.ok){let re=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${re}`)}let y=await u.text();return y?JSON.parse(y):{}}catch(u){throw clearTimeout(s),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var le="@lelemondev/sdk",me="nodejs";function fe(){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 ge(){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 he(){try{if(typeof j<"u")return B().version??"unknown"}catch{}return "unknown"}var h=null;function H(e){if(!h){let n=fe(),r=ge();h={"telemetry.sdk.name":le,"telemetry.sdk.version":he(),"telemetry.sdk.language":me},n&&(h["process.runtime.name"]=n.name,h["process.runtime.version"]=n.version),r&&(h["os.type"]=r);}let t={...h};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var q={},f=null,M=null,W="https://www.lelemon.dev";function ye(e={}){q=e,e.debug&&L(true),M=H(e.service),E("Initializing SDK",{endpoint:e.endpoint??W,debug:e.debug??false,disabled:e.disabled??false,telemetry:M}),f=J(e),f.isEnabled()?E("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Y(){return q}function C(){return M}function we(){return g().isEnabled()}function g(){return f||(f=J(q)),f}async function Te(){f&&await f.flush();}function J(e){let t=e.apiKey??ve("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 x({apiKey:t??"",endpoint:e.endpoint??W,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function ve(e){if(typeof process<"u"&&process.env)return process.env[e]}var Q={};function Z(e){Q=e,c("Global context updated",e);}function v(){return Q}function D(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=v(),r=l(),o=b(),i=C(),a={provider:e.provider,model:e.model,input:P(e.input),rawResponse:e.rawResponse?T(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}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return R(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){S(e.provider,t instanceof Error?t:new Error(String(t)));return}}function $(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=v(),r=l(),o=C(),i={provider:e.provider,model:e.model,input:P(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};R(e.provider,e.model,e.durationMs,"error"),c("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){S(e.provider,t instanceof Error?t:new Error(String(t)));}}function O(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping span capture");return}let n=v(),r=l(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=C(),s={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete s._traceId,delete s._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:P(e.input),output:T(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:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:s,tags:n.tags};c(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){S("unknown",t instanceof Error?t:new Error(String(t)));}}var X=1e5,ke=["api_key","apikey","password","secret","authorization"],Se=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],xe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Ce(e){let t=e.toLowerCase();return xe.includes(t)?false:!!(ke.some(n=>t.includes(n))||Se.some(n=>t.includes(n)))}function P(e){return T(e,0)}function T(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string")return e.length>X?e.slice(0,X)+"...[truncated]":e;if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>T(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Ce(r)?n[r]="[REDACTED]":n[r]=T(o,t+1);return n}return String(e)}var ee=new AsyncLocalStorage;function b(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function l(){return ee.getStore()}function Ee(e){let t=l();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Re(e){let t=l();t&&t.pendingToolCalls.delete(e);}async function _e(e,t){let n=typeof e=="string"?{name:e}:e,r=l(),o=r?.traceId??b(),i=b(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return ee.run(a,async()=>{let s,d;try{return s=await t(),s}catch(u){throw d=u instanceof Error?u:new Error(String(u)),u}finally{Me(a,d?void 0:s,d);}})}function Me(e,t,n){let r=g();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=v(),i=Date.now()-e.startTime,a=n?null:t,s={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};c(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(s);}function qe(e){let t=l();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Ee(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&&Re(e.toolCallId);}var De="openrouter.ai",I="openrouter";function te(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(De):false}function ne(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="chat"&&i&&typeof i=="object"?$e(i):i}})}function $e(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?Oe(o):o}})}function Oe(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Pe(o.bind(t)):o}})}function Pe(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&je(a))return Ae(a,o,r);let s=Date.now()-r,d=a;return D({provider:I,model:o.model||d.model||"unknown",input:o.messages,rawResponse:a,durationMs:s,status:"success",streaming:!1}),a}catch(a){let s=Date.now()-r;throw $({provider:I,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function je(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ae(e,t,n){let r={choices:[{message:{content:"",role:"assistant"},finish_reason:""}],usage:{prompt_tokens:0,completion_tokens:0}},o=null,i,a=false;try{for await(let s of e){let d=s;!r.id&&d.id&&(r.id=d.id);let u=d.choices?.[0]?.delta?.content;u&&(a||(a=!0,i=Date.now()-n),r.choices[0].message.content+=u);let y=d.choices?.[0]?.finish_reason;y&&(r.choices[0].finish_reason=y),d.usage&&(r.usage=d.usage),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n;o?$({provider:I,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):D({provider:I,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function lt(e,t){return t&&Z(t),Y().disabled?(c("Tracing disabled, returning unwrapped client"),e):te(e)?(K("openrouter"),ne(e)):(k("Client is not configured for OpenRouter. Ensure baseURL is set to openrouter.ai."),e)}
3
- export{O as captureSpan,Te as flush,l as getTraceContext,ye as init,we as isEnabled,lt as observe,qe as span,_e as trace};//# sourceMappingURL=openrouter.mjs.map
2
+ var ie=Object.defineProperty;var ae=(e,t,n)=>t in e?ie(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 ue=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>ae(e,typeof t!="symbol"?t+"":t,n);var H=ue((We,me)=>{me.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 K=false;function N(e){K=e;}function m(){return K?true:de("LELEMON_DEBUG")==="true"}var l="[Lelemon]";function c(e,t){m()&&_("debug",e,t);}function E(e,t){m()&&_("info",e,t);}function k(e,t){_("warn",e,t);}function R(e,t,n,r){m()&&console.log(`${l} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function S(e,t){console.error(`${l} Failed to capture trace: provider=${e} error=${t.message}`);}function U(e){m()&&console.log(`${l} Wrapped client: provider=${e}`);}function z(e,t){m()&&console.log(`${l} Sending batch: count=${e} endpoint=${t}`);}function F(e,t){m()&&console.log(`${l} Batch sent successfully: count=${e} duration=${t}ms`);}function G(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${l} Batch send failed: count=${e} error=${n}`);}function B(e,t,n){m()&&console.log(`${l} Request: ${e} ${t} (${n} bytes)`);}function V(e,t){m()&&console.log(`${l} 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(`${l} ${t}`,n):r(`${l} ${t}`);}function de(e){if(typeof process<"u"&&process.env)return process.env[e]}var ce=10,le=1e3,pe=1e4,x=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??ce,flushIntervalMs:t.flushIntervalMs??le,requestTimeoutMs:t.requestTimeoutMs??pe};}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){G(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;B(t,o,a?.length??0);let s=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),d=Date.now();try{let u=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(s),V(u.status,Date.now()-d),!u.ok){let se=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${se}`)}let y=await u.text();return y?JSON.parse(y):{}}catch(u){throw clearTimeout(s),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var fe="@lelemondev/sdk",ge="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 he(){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 ye(){try{if(typeof L<"u")return H().version??"unknown"}catch{}return "unknown"}var b=null;function Y(e){if(!b){let n=be(),r=he();b={"telemetry.sdk.name":fe,"telemetry.sdk.version":ye(),"telemetry.sdk.language":ge},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 q={},f=null,M=null,X="https://api.lelemon.dev";function we(e={}){q=e,e.debug&&N(true),M=Y(e.service),E("Initializing SDK",{endpoint:e.endpoint??X,debug:e.debug??false,disabled:e.disabled??false,telemetry:M}),f=Q(e),f.isEnabled()?E("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function J(){return q}function C(){return M}function ve(){return g().isEnabled()}function g(){return f||(f=Q(q)),f}async function ke(){f&&await f.flush();}function Q(e){let t=e.apiKey??Se("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 x({apiKey:t??"",endpoint:e.endpoint??X,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Se(e){if(typeof process<"u"&&process.env)return process.env[e]}var O=Symbol.for("@lelemondev/sdk:globalContext");function ee(){let e=globalThis;return e[O]||(e[O]={context:{}}),e[O]}function te(e){ee().context=e,c("Global context updated",e);}function v(){return ee().context}function D(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=v(),r=p(),o=h(),i=C(),a={provider:e.provider,model:e.model,input:A(e.input),rawResponse:e.rawResponse?w(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}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return R(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){S(e.provider,t instanceof Error?t:new Error(String(t)));return}}function $(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=v(),r=p(),o=C(),i={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:h(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};R(e.provider,e.model,e.durationMs,"error"),c("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){S(e.provider,t instanceof Error?t:new Error(String(t)));}}function P(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping span capture");return}let n=v(),r=p(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=C(),s={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete s._traceId,delete s._parentSpanId;let d={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:A(e.input),output:w(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:h(),parentSpanId:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:s,tags:n.tags};c(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(d);}catch(t){S("unknown",t instanceof Error?t:new Error(String(t)));}}var Z=1e5,xe=["api_key","apikey","password","secret","authorization"],Ce=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Ie=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Ee(e){let t=e.toLowerCase();return Ie.includes(t)?false:!!(xe.some(n=>t.includes(n))||Ce.some(n=>t.includes(n)))}function A(e){return w(e,0)}function w(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=>w(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Ee(r)?n[r]="[REDACTED]":n[r]=w(o,t+1);return n}return String(e)}var j=Symbol.for("@lelemondev/sdk:traceStorage");function _e(){let e=globalThis;return e[j]||(e[j]=new AsyncLocalStorage),e[j]}var ne=_e();function h(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function p(){return ne.getStore()}function Me(e){let t=p();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function qe(e){let t=p();t&&t.pendingToolCalls.delete(e);}async function Oe(e,t){let n=typeof e=="string"?{name:e}:e,r=p(),o=r?.traceId??h(),i=h(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return ne.run(a,async()=>{let s,d;try{return s=await t(),s}catch(u){throw d=u instanceof Error?u:new Error(String(u)),u}finally{De(a,d?void 0:s,d);}})}function De(e,t,n){let r=g();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=v(),i=Date.now()-e.startTime,a=n?null:t,s={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};c(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(s);}function $e(e){let t=p();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Me(e.toolCallId);P({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&&qe(e.toolCallId);}var Pe="openrouter.ai",I="openrouter";function re(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(Pe):false}function oe(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="chat"&&i&&typeof i=="object"?Ae(i):i}})}function Ae(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?je(o):o}})}function je(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Le(o.bind(t)):o}})}function Le(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&Ke(a))return Ne(a,o,r);let s=Date.now()-r,d=a;return D({provider:I,model:o.model||d.model||"unknown",input:o.messages,rawResponse:a,durationMs:s,status:"success",streaming:!1}),a}catch(a){let s=Date.now()-r;throw $({provider:I,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function Ke(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ne(e,t,n){let r={choices:[{message:{content:"",role:"assistant"},finish_reason:""}],usage:{prompt_tokens:0,completion_tokens:0}},o=null,i,a=false;try{for await(let s of e){let d=s;!r.id&&d.id&&(r.id=d.id);let u=d.choices?.[0]?.delta?.content;u&&(a||(a=!0,i=Date.now()-n),r.choices[0].message.content+=u);let y=d.choices?.[0]?.finish_reason;y&&(r.choices[0].finish_reason=y),d.usage&&(r.usage=d.usage),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n;o?$({provider:I,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):D({provider:I,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function gt(e,t){return t&&te(t),J().disabled?(c("Tracing disabled, returning unwrapped client"),e):re(e)?(U("openrouter"),oe(e)):(k("Client is not configured for OpenRouter. Ensure baseURL is set to openrouter.ai."),e)}
3
+ export{P as captureSpan,ke as flush,p as getTraceContext,we as init,ve as isEnabled,gt as observe,$e as span,Oe as trace};//# sourceMappingURL=openrouter.mjs.map
4
4
  //# sourceMappingURL=openrouter.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lelemondev/sdk",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "description": "Automatic LLM observability. Wrap your client, everything is traced.",
5
5
  "author": "Lelemon <info@lelemon.dev>",
6
6
  "license": "MIT",