@lelemondev/sdk 0.9.8 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -11
- package/dist/anthropic.js +2 -2
- package/dist/anthropic.mjs +2 -2
- package/dist/bedrock.js +2 -2
- package/dist/bedrock.mjs +2 -2
- package/dist/gemini.d.mts +2 -0
- package/dist/gemini.d.ts +2 -0
- package/dist/gemini.js +2 -2
- package/dist/gemini.mjs +2 -2
- package/dist/google-genai.d.mts +31 -0
- package/dist/google-genai.d.ts +31 -0
- package/dist/google-genai.js +4 -0
- package/dist/google-genai.mjs +4 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/openai.js +2 -2
- package/dist/openai.mjs +2 -2
- package/dist/openrouter.js +2 -2
- package/dist/openrouter.mjs +2 -2
- package/package.json +17 -6
package/dist/openai.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var ye=Object.defineProperty;var be=(e,n,t)=>n in e?ye(e,n,{enumerable:true,configurable:true,writable:true,value:t}):e[n]=t;var G=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,t)=>(typeof require<"u"?require:n)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var he=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var v=(e,n,t)=>be(e,typeof n!="symbol"?n+"":n,t);var Q=he((ln,Ie)=>{Ie.exports={name:"@lelemondev/sdk",version:"0.9.8",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 B=false;function V(e){B=e;}function w(){return B?true:ke("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function d(e,n){w()&&q("debug",e,n);}function D(e,n){w()&&q("info",e,n);}function E(e,n){q("warn",e,n);}function P(e,n,t,r){w()&&console.log(`${f} Captured trace: provider=${e} model=${n} duration=${t}ms status=${r}`);}function R(e,n){console.error(`${f} Failed to capture trace: provider=${e} error=${n.message}`);}function H(e){w()&&console.log(`${f} Wrapped client: provider=${e}`);}function W(e,n){w()&&console.log(`${f} Sending batch: count=${e} endpoint=${n}`);}function Y(e,n){w()&&console.log(`${f} Batch sent successfully: count=${e} duration=${n}ms`);}function X(e,n){let t=n instanceof Error?n.message:String(n);console.error(`${f} Batch send failed: count=${e} error=${t}`);}function Z(e,n,t){w()&&console.log(`${f} Request: ${e} ${n} (${t} bytes)`);}function J(e,n){w()&&console.log(`${f} Response: status=${e} duration=${n}ms`);}function q(e,n,t){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;t!==void 0?r(`${f} ${n}`,t):r(`${f} ${n}`);}function ke(e){if(typeof process<"u"&&process.env)return process.env[e]}var Te=10,Ce=1e3,ve=1e4,_=class{constructor(n){v(this,"config");v(this,"queue",[]);v(this,"flushPromise",null);v(this,"flushTimer",null);this.config={apiKey:n.apiKey,endpoint:n.endpoint,debug:n.debug,disabled:n.disabled,batchSize:n.batchSize??Te,flushIntervalMs:n.flushIntervalMs??Ce,requestTimeoutMs:n.requestTimeoutMs??ve};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(n){this.config.disabled||(this.queue.push(n),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 n=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(n).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(n){if(n.length===0)return;let t=Date.now();W(n.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:n}),Y(n.length,Date.now()-t);}catch(r){X(n.length,r);}}async request(n,t,r){let o=`${this.config.endpoint}${t}`,s=new AbortController,i=r?JSON.stringify(r):void 0;Z(n,o,i?.length??0);let a=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),c=Date.now();try{let u=await fetch(o,{method:n,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(a),J(u.status,Date.now()-c),!u.ok){let x=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${x}`)}let l=await u.text();return l?JSON.parse(l):{}}catch(u){throw clearTimeout(a),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var Se="@lelemondev/sdk",xe="nodejs";function Ee(){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 Re(){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 _e(){try{if(typeof G<"u")return Q().version??"unknown"}catch{}return "unknown"}var T=null;function ne(e){if(!T){let t=Ee(),r=Re();T={"telemetry.sdk.name":Se,"telemetry.sdk.version":_e(),"telemetry.sdk.language":xe},t&&(T["process.runtime.name"]=t.name,T["process.runtime.version"]=t.version),r&&(T["os.type"]=r);}let n={...T};return e?.name&&(n["service.name"]=e.name),e?.version&&(n["service.version"]=e.version),e?.environment&&(n["deployment.environment"]=e.environment),n}var $={},y=null,j=null,te="https://api.lelemon.dev";function Oe(e={}){$=e,e.debug&&V(true),j=ne(e.service),D("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:j}),y=re(e),y.isEnabled()?D("SDK initialized - tracing enabled"):d("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function A(){return $}function O(){return j}function Me(){return b().isEnabled()}function b(){return y||(y=re($)),y}async function De(){y&&await y.flush();}function re(e){let n=e.apiKey??Pe("LELEMON_API_KEY");return !n&&!e.disabled&&E("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new _({apiKey:n??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!n,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Pe(e){if(typeof process<"u"&&process.env)return process.env[e]}var N=Symbol.for("@lelemondev/sdk:globalContext");function ie(){let e=globalThis;return e[N]||(e[N]={context:{}}),e[N]}function ae(e){ie().context=e,d("Global context updated",e);}function S(){return ie().context}function h(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping trace capture");return}let t=S(),r=m(),o=C(),s=O(),i={provider:e.provider,model:e.model,input:L(e.input),rawResponse:e.rawResponse?I(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...t.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:t.tags,spanType:e.spanType,name:e.name};return P(e.provider,e.model,e.durationMs,e.status),n.enqueue(i),o}catch(n){R(e.provider,n instanceof Error?n:new Error(String(n)));return}}function k(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping error capture");return}let t=S(),r=m(),o=O(),s={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:r?.traceId,spanId:C(),parentSpanId:r?.currentSpanId,metadata:{...t.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:t.tags};P(e.provider,e.model,e.durationMs,"error"),d("Error details",{message:e.error.message,stack:e.error.stack}),n.enqueue(s);}catch(n){R(e.provider,n instanceof Error?n:new Error(String(n)));}}function K(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping span capture");return}let t=S(),r=m(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=O(),a={...t.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete a._traceId,delete a._parentSpanId;let c={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:L(e.input),output:I(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:o??r?.traceId,spanId:C(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:a,tags:t.tags};d(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),n.enqueue(c);}catch(n){R("unknown",n instanceof Error?n:new Error(String(n)));}}var oe=1e5,qe=["api_key","apikey","password","secret","authorization"],je=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],$e=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],se={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ue(){return A().redaction??{}}function Ne(e){let n=e.toLowerCase();return $e.includes(n)?false:!!(qe.some(r=>n.includes(r))||je.some(r=>n.includes(r))||(ue().keys??[]).some(r=>n.includes(r.toLowerCase())))}function Ke(e){let n=ue(),t=e;for(let r of n.patterns??[])r.lastIndex=0,t=t.replace(r,"[REDACTED]");return n.emails&&(t=t.replace(se.emails,"[EMAIL]")),n.phones&&(t=t.replace(se.phones,"[PHONE]")),t}function L(e){return I(e,0)}function I(e,n){if(n>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let t=Ke(e);return t.length>oe&&(t=t.slice(0,oe)+"...[truncated]"),t}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(t=>I(t,n+1));if(typeof e=="object"){let t={};for(let[r,o]of Object.entries(e))Ne(r)?t[r]="[REDACTED]":t[r]=I(o,n+1);return t}return String(e)}var z=Symbol.for("@lelemondev/sdk:traceStorage");function ze(){let e=globalThis;return e[z]||(e[z]=new AsyncLocalStorage),e[z]}var ce=ze();function C(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ce.getStore()}function F(e,n){let t=m();if(t)for(let r of e)t.pendingToolCalls.set(r,n),d(`Registered tool call ${r} \u2192 LLM span ${n}`);}function Fe(e){let n=m();if(n)return e&&n.pendingToolCalls.has(e)?n.pendingToolCalls.get(e):n.currentSpanId}function Ue(e){let n=m();n&&n.pendingToolCalls.delete(e);}async function Ge(e,n){let t=typeof e=="string"?{name:e}:e,r=m(),o=r?.traceId??C(),s=C(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:t.name,startTime:Date.now(),input:t.input,metadata:t.metadata,tags:t.tags,outputKey:t.outputKey,outputTransform:t.outputTransform,sessionId:t.sessionId,userId:t.userId,pendingToolCalls:new Map};return ce.run(i,async()=>{let a,c;try{return a=await n(),a}catch(u){throw c=u instanceof Error?u:new Error(String(u)),u}finally{He(i,c?void 0:a,c);}})}var Be=["text","content","message","output","response","result","answer"];function Ve(e,n,t){if(t)try{return t(e)}catch{return e}if(n===false)return e;if(typeof n=="string"&&e&&typeof e=="object"){let o=e;return n in o?o[n]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Be)if(o in r&&typeof r[o]=="string")return r[o];return e}function He(e,n,t){let r=b();if(!r.isEnabled()){d("Transport disabled, skipping root span");return}let o=S(),s=Date.now()-e.startTime,i=t?null:Ve(n,e.outputKey,e.outputTransform),a={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:t?"error":"success",errorMessage:t?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};d(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!t}),r.enqueue(a);}function We(e){let n=m();if(!n){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let t=Fe(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:n.traceId,_parentSpanId:t}}),e.toolCallId&&Ue(e.toolCallId);}var p="openai";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="OpenAI")return true;let t=e;return !!(t.chat&&t.completions)||!!t.responses}function le(e){return async function(...t){let r=Date.now(),o=t[0]||{},s=o.stream===true;try{let i=await e(...t);if(s&&pe(i))return Ye(i,o,r);let a=Date.now()-r,c=i,u=h({provider:p,model:o.model||c.model||"unknown",input:o.messages,rawResponse:i,durationMs:a,status:"success",streaming:!1});if(u){let l=we(c);l.length>0&&F(l,u);}return i}catch(i){let a=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.messages,error:i instanceof Error?i:new Error(String(i)),durationMs:a,streaming:s}),i}}}function pe(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ye(e,n,t){let r={choices:[{message:{content:"",tool_calls:[]},finish_reason:""}],usage:{prompt_tokens:0,completion_tokens:0}},o=null,s,i=false,a=new Map;try{for await(let c of e){let u=c,l=u?.choices?.[0]?.delta?.content;l&&(i||(i=!0,s=Date.now()-t),r.choices[0].message.content+=l);let x=u?.choices?.[0]?.delta?.tool_calls;if(x)for(let g of x){a.has(g.index)||a.set(g.index,{id:"",function:{name:"",arguments:""}});let M=a.get(g.index);g.id&&(M.id=g.id),g.function?.name&&(M.function.name=g.function.name),g.function?.arguments&&(M.function.arguments+=g.function.arguments);}let U=u?.choices?.[0]?.finish_reason;U&&(r.choices[0].finish_reason=U),u?.usage&&(r.usage=u.usage),yield c;}}catch(c){throw o=c instanceof Error?c:new Error(String(c)),c}finally{let c=Date.now()-t;if(a.size>0&&(r.choices[0].message.tool_calls=Array.from(a.entries()).sort((u,l)=>u[0]-l[0]).map(([,u])=>u)),o)k({provider:p,model:n.model||"unknown",input:n.messages,error:o,durationMs:c,streaming:true});else {let u=h({provider:p,model:n.model||"unknown",input:n.messages,rawResponse:r,durationMs:c,status:"success",streaming:true,firstTokenMs:s});if(u){let l=we(r);l.length>0&&F(l,u);}}}}function fe(e){return async function(...t){let r=Date.now(),o=t[0]||{},s=o.stream===true;try{let i=await e(...t);if(s&&pe(i))return Xe(i,o,r);let a=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:{instructions:o.instructions,input:o.input},rawResponse:i,durationMs:a,status:"success",streaming:!1}),i}catch(i){let a=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:{instructions:o.instructions,input:o.input},error:i instanceof Error?i:new Error(String(i)),durationMs:a,streaming:s}),i}}}async function*Xe(e,n,t){let r=[],o=null,s=null;try{for await(let i of e){r.push(i);let a=i;a.type==="response.done"&&a.response&&(o=a.response),yield i;}}catch(i){throw s=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-t;s?k({provider:p,model:n.model||"unknown",input:{instructions:n.instructions,input:n.input},error:s,durationMs:i,streaming:true}):h({provider:p,model:n.model||"unknown",input:{instructions:n.instructions,input:n.input},rawResponse:o||{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function me(e){return async function(...t){let r=Date.now(),o=t[0]||{};try{let s=await e(...t),i=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:o.prompt,rawResponse:s,durationMs:i,status:"success",streaming:!1}),s}catch(s){let i=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.prompt,error:s instanceof Error?s:new Error(String(s)),durationMs:i,streaming:false}),s}}}function ge(e){return async function(...t){let r=Date.now(),o=t[0]||{};try{let s=await e(...t),i=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:o.input,rawResponse:s,durationMs:i,status:"success",streaming:!1,spanType:"embedding"}),s}catch(s){let i=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.input,error:s instanceof Error?s:new Error(String(s)),durationMs:i,streaming:false}),s}}}function we(e){let n=[],t=e.choices?.[0]?.message?.tool_calls;if(Array.isArray(t))for(let r of t)r.id&&n.push(r.id);return n}function Dn(e,n){return n&&ae(n),A().disabled?(d("Tracing disabled, returning unwrapped client"),e):de(e)?(H("openai"),Je(e)):(E("Client is not an OpenAI client. Use @lelemondev/sdk/openai only with OpenAI SDK."),e)}function Je(e){let n=e;return new Proxy(n,{get(t,r,o){let s=Reflect.get(t,r,o);return r==="chat"&&s&&typeof s=="object"?Qe(s):r==="responses"&&s&&typeof s=="object"?nn(s):r==="completions"&&s&&typeof s=="object"?tn(s):r==="embeddings"&&s&&typeof s=="object"?rn(s):s}})}function Qe(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="completions"&&o&&typeof o=="object"?en(o):o}})}function en(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?le(o.bind(n)):o}})}function nn(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?fe(o.bind(n)):o}})}function tn(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?me(o.bind(n)):o}})}function rn(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?ge(o.bind(n)):o}})}
|
|
3
|
-
export{
|
|
2
|
+
var U=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,t)=>(typeof require<"u"?require:n)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var we=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var J=we((an,Te)=>{Te.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var G=false;function B(e){G=e;}function w(){return G?true:ye("LELEMON_DEBUG")==="true"}var f="[Lelemon]";function d(e,n){w()&&P("debug",e,n);}function M(e,n){w()&&P("info",e,n);}function x(e,n){P("warn",e,n);}function D(e,n,t,r){w()&&console.log(`${f} Captured trace: provider=${e} model=${n} duration=${t}ms status=${r}`);}function E(e,n){console.error(`${f} Failed to capture trace: provider=${e} error=${n.message}`);}function V(e){w()&&console.log(`${f} Wrapped client: provider=${e}`);}function H(e,n){w()&&console.log(`${f} Sending batch: count=${e} endpoint=${n}`);}function W(e,n){w()&&console.log(`${f} Batch sent successfully: count=${e} duration=${n}ms`);}function Y(e,n){let t=n instanceof Error?n.message:String(n);console.error(`${f} Batch send failed: count=${e} error=${t}`);}function X(e,n,t){w()&&console.log(`${f} Request: ${e} ${n} (${t} bytes)`);}function Z(e,n){w()&&console.log(`${f} Response: status=${e} duration=${n}ms`);}function P(e,n,t){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;t!==void 0?r(`${f} ${n}`,t):r(`${f} ${n}`);}function ye(e){if(typeof process<"u"&&process.env)return process.env[e]}var be=10,he=1e3,ke=1e4,R=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(n){this.config={apiKey:n.apiKey,endpoint:n.endpoint,debug:n.debug,disabled:n.disabled,batchSize:n.batchSize??be,flushIntervalMs:n.flushIntervalMs??he,requestTimeoutMs:n.requestTimeoutMs??ke};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(n){this.config.disabled||(this.queue.push(n),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 n=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(n).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(n){if(n.length===0)return;let t=Date.now();H(n.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:n}),W(n.length,Date.now()-t);}catch(r){Y(n.length,r);}}async request(n,t,r){let o=`${this.config.endpoint}${t}`,s=new AbortController,i=r?JSON.stringify(r):void 0;X(n,o,i?.length??0);let a=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),c=Date.now();try{let u=await fetch(o,{method:n,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(a),Z(u.status,Date.now()-c),!u.ok){let S=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${S}`)}let l=await u.text();return l?JSON.parse(l):{}}catch(u){throw clearTimeout(a),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var Ce="@lelemondev/sdk",ve="nodejs";function Ie(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function Se(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function xe(){try{if(typeof U<"u")return J().version??"unknown"}catch{}return "unknown"}var T=null;function ee(e){if(!T){let t=Ie(),r=Se();T={"telemetry.sdk.name":Ce,"telemetry.sdk.version":xe(),"telemetry.sdk.language":ve},t&&(T["process.runtime.name"]=t.name,T["process.runtime.version"]=t.version),r&&(T["os.type"]=r);}let n={...T};return e?.name&&(n["service.name"]=e.name),e?.version&&(n["service.version"]=e.version),e?.environment&&(n["deployment.environment"]=e.environment),n}var j={},y=null,q=null,ne="https://api.lelemon.dev";function Re(e={}){j=e,e.debug&&B(true),q=ee(e.service),M("Initializing SDK",{endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??false,telemetry:q}),y=te(e),y.isEnabled()?M("SDK initialized - tracing enabled"):d("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function _(){return j}function A(){return q}function _e(){return b().isEnabled()}function b(){return y||(y=te(j)),y}async function Ae(){y&&await y.flush();}function te(e){let n=e.apiKey??Oe("LELEMON_API_KEY");return !n&&!e.disabled&&x("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new R({apiKey:n??"",endpoint:e.endpoint??ne,debug:e.debug??false,disabled:e.disabled??!n,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Oe(e){if(typeof process<"u"&&process.env)return process.env[e]}var $=Symbol.for("@lelemondev/sdk:globalContext");function se(){let e=globalThis;return e[$]||(e[$]={context:{}}),e[$]}function ie(e){se().context=e,d("Global context updated",e);}function I(){return se().context}function h(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping trace capture");return}let t=I(),r=m(),o=C(),s=A(),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:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...t.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:t.tags,spanType:e.spanType,name:e.name};return D(e.provider,e.model,e.durationMs,e.status),n.enqueue(i),o}catch(n){E(e.provider,n instanceof Error?n:new Error(String(n)));return}}function k(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping error capture");return}let t=I(),r=m(),o=A(),s={provider:e.provider,model:e.model,input:K(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:r?.traceId,spanId:C(),parentSpanId:r?.currentSpanId,metadata:{...t.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:t.tags};D(e.provider,e.model,e.durationMs,"error"),d("Error details",{message:e.error.message,stack:e.error.stack}),n.enqueue(s);}catch(n){E(e.provider,n instanceof Error?n:new Error(String(n)));}}function N(e){try{let n=b();if(!n.isEnabled()){d("Transport disabled, skipping span capture");return}let t=I(),r=m(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=A(),a={...t.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete a._traceId,delete a._parentSpanId;let c={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:r?.sessionId??t.sessionId,userId:r?.userId??t.userId,traceId:o??r?.traceId,spanId:C(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:a,tags:t.tags};d(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),n.enqueue(c);}catch(n){E("unknown",n instanceof Error?n:new Error(String(n)));}}var re=1e5,Me=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Pe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],oe={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ae(){return _().redaction??{}}function qe(e){let n=e.toLowerCase();return Pe.includes(n)?false:!!(Me.some(r=>n.includes(r))||De.some(r=>n.includes(r))||(ae().keys??[]).some(r=>n.includes(r.toLowerCase())))}function je(e){let n=ae(),t=e;for(let r of n.patterns??[])r.lastIndex=0,t=t.replace(r,"[REDACTED]");return n.emails&&(t=t.replace(oe.emails,"[EMAIL]")),n.phones&&(t=t.replace(oe.phones,"[PHONE]")),t}function K(e){return v(e,0)}function v(e,n){if(n>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let t=je(e);return t.length>re&&(t=t.slice(0,re)+"...[truncated]"),t}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(t=>v(t,n+1));if(typeof e=="object"){let t={};for(let[r,o]of Object.entries(e))qe(r)?t[r]="[REDACTED]":t[r]=v(o,n+1);return t}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function Ne(){let e=globalThis;return e[L]||(e[L]=new AsyncLocalStorage),e[L]}var ue=Ne();function C(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function m(){return ue.getStore()}function z(e,n){let t=m();if(t)for(let r of e)t.pendingToolCalls.set(r,n),d(`Registered tool call ${r} \u2192 LLM span ${n}`);}function Ke(e){let n=m();if(n)return e&&n.pendingToolCalls.has(e)?n.pendingToolCalls.get(e):n.currentSpanId}function Le(e){let n=m();n&&n.pendingToolCalls.delete(e);}async function ze(e,n){let t=typeof e=="string"?{name:e}:e,r=m(),o=r?.traceId??C(),s=C(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:t.name,startTime:Date.now(),input:t.input,metadata:t.metadata,tags:t.tags,outputKey:t.outputKey,outputTransform:t.outputTransform,sessionId:t.sessionId,userId:t.userId,pendingToolCalls:new Map};return ue.run(i,async()=>{let a,c;try{return a=await n(),a}catch(u){throw c=u instanceof Error?u:new Error(String(u)),u}finally{Ge(i,c?void 0:a,c);}})}var Fe=["text","content","message","output","response","result","answer"];function Ue(e,n,t){if(t)try{return t(e)}catch{return e}if(n===false)return e;if(typeof n=="string"&&e&&typeof e=="object"){let o=e;return n in o?o[n]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Fe)if(o in r&&typeof r[o]=="string")return r[o];return e}function Ge(e,n,t){let r=b();if(!r.isEnabled()){d("Transport disabled, skipping root span");return}let o=I(),s=Date.now()-e.startTime,i=t?null:Ue(n,e.outputKey,e.outputTransform),a={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:t?"error":"success",errorMessage:t?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};d(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!t}),r.enqueue(a);}function Be(e){let n=m();if(!n){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let t=Ke(e.toolCallId);N({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:n.traceId,_parentSpanId:t}}),e.toolCallId&&Le(e.toolCallId);}var p="openai";function ce(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="OpenAI")return true;let t=e;return !!(t.chat&&t.completions)||!!t.responses}function de(e){return async function(...t){let r=Date.now(),o=t[0]||{},s=o.stream===true;try{let i=await e(...t);if(s&&le(i))return Ve(i,o,r);let a=Date.now()-r,c=i,u=h({provider:p,model:o.model||c.model||"unknown",input:o.messages,rawResponse:i,durationMs:a,status:"success",streaming:!1});if(u){let l=ge(c);l.length>0&&z(l,u);}return i}catch(i){let a=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.messages,error:i instanceof Error?i:new Error(String(i)),durationMs:a,streaming:s}),i}}}function le(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ve(e,n,t){let r={choices:[{message:{content:"",tool_calls:[]},finish_reason:""}],usage:{prompt_tokens:0,completion_tokens:0}},o=null,s,i=false,a=new Map;try{for await(let c of e){let u=c,l=u?.choices?.[0]?.delta?.content;l&&(i||(i=!0,s=Date.now()-t),r.choices[0].message.content+=l);let S=u?.choices?.[0]?.delta?.tool_calls;if(S)for(let g of S){a.has(g.index)||a.set(g.index,{id:"",function:{name:"",arguments:""}});let O=a.get(g.index);g.id&&(O.id=g.id),g.function?.name&&(O.function.name=g.function.name),g.function?.arguments&&(O.function.arguments+=g.function.arguments);}let F=u?.choices?.[0]?.finish_reason;F&&(r.choices[0].finish_reason=F),u?.usage&&(r.usage=u.usage),yield c;}}catch(c){throw o=c instanceof Error?c:new Error(String(c)),c}finally{let c=Date.now()-t;if(a.size>0&&(r.choices[0].message.tool_calls=Array.from(a.entries()).sort((u,l)=>u[0]-l[0]).map(([,u])=>u)),o)k({provider:p,model:n.model||"unknown",input:n.messages,error:o,durationMs:c,streaming:true});else {let u=h({provider:p,model:n.model||"unknown",input:n.messages,rawResponse:r,durationMs:c,status:"success",streaming:true,firstTokenMs:s});if(u){let l=ge(r);l.length>0&&z(l,u);}}}}function pe(e){return async function(...t){let r=Date.now(),o=t[0]||{},s=o.stream===true;try{let i=await e(...t);if(s&&le(i))return He(i,o,r);let a=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:{instructions:o.instructions,input:o.input},rawResponse:i,durationMs:a,status:"success",streaming:!1}),i}catch(i){let a=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:{instructions:o.instructions,input:o.input},error:i instanceof Error?i:new Error(String(i)),durationMs:a,streaming:s}),i}}}async function*He(e,n,t){let r=[],o=null,s=null;try{for await(let i of e){r.push(i);let a=i;a.type==="response.done"&&a.response&&(o=a.response),yield i;}}catch(i){throw s=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-t;s?k({provider:p,model:n.model||"unknown",input:{instructions:n.instructions,input:n.input},error:s,durationMs:i,streaming:true}):h({provider:p,model:n.model||"unknown",input:{instructions:n.instructions,input:n.input},rawResponse:o||{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function fe(e){return async function(...t){let r=Date.now(),o=t[0]||{};try{let s=await e(...t),i=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:o.prompt,rawResponse:s,durationMs:i,status:"success",streaming:!1}),s}catch(s){let i=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.prompt,error:s instanceof Error?s:new Error(String(s)),durationMs:i,streaming:false}),s}}}function me(e){return async function(...t){let r=Date.now(),o=t[0]||{};try{let s=await e(...t),i=Date.now()-r;return h({provider:p,model:o.model||"unknown",input:o.input,rawResponse:s,durationMs:i,status:"success",streaming:!1,spanType:"embedding"}),s}catch(s){let i=Date.now()-r;throw k({provider:p,model:o.model||"unknown",input:o.input,error:s instanceof Error?s:new Error(String(s)),durationMs:i,streaming:false}),s}}}function ge(e){let n=[],t=e.choices?.[0]?.message?.tool_calls;if(Array.isArray(t))for(let r of t)r.id&&n.push(r.id);return n}function _n(e,n){return n&&ie(n),_().disabled?(d("Tracing disabled, returning unwrapped client"),e):ce(e)?(V("openai"),Ye(e)):(x("Client is not an OpenAI client. Use @lelemondev/sdk/openai only with OpenAI SDK."),e)}function Ye(e){let n=e;return new Proxy(n,{get(t,r,o){let s=Reflect.get(t,r,o);return r==="chat"&&s&&typeof s=="object"?Xe(s):r==="responses"&&s&&typeof s=="object"?Je(s):r==="completions"&&s&&typeof s=="object"?Qe(s):r==="embeddings"&&s&&typeof s=="object"?en(s):s}})}function Xe(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="completions"&&o&&typeof o=="object"?Ze(o):o}})}function Ze(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?de(o.bind(n)):o}})}function Je(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?pe(o.bind(n)):o}})}function Qe(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?fe(o.bind(n)):o}})}function en(e){return new Proxy(e,{get(n,t,r){let o=Reflect.get(n,t,r);return t==="create"&&typeof o=="function"?me(o.bind(n)):o}})}
|
|
3
|
+
export{N as captureSpan,Ae as flush,m as getTraceContext,Re as init,_e as isEnabled,_n as observe,Be as span,ze as trace};//# sourceMappingURL=openai.mjs.map
|
|
4
4
|
//# sourceMappingURL=openai.mjs.map
|
package/dist/openrouter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('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 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 le=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var w=(e,t,n)=>ce(e,typeof t!="symbol"?t+"":t,n);var Y=le((nt,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.9.8",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 f(){return U?true:pe("LELEMON_DEBUG")==="true"}var l="[Lelemon]";function c(e,t){f()&&O("debug",e,t);}function _(e,t){f()&&O("info",e,t);}function I(e,t){O("warn",e,t);}function M(e,t,n,r){f()&&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 F(e){f()&&console.log(`${l} Wrapped client: provider=${e}`);}function B(e,t){f()&&console.log(`${l} Sending batch: count=${e} endpoint=${t}`);}function G(e,t){f()&&console.log(`${l} Batch sent successfully: count=${e} duration=${t}ms`);}function V(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${l} Batch send failed: count=${e} error=${n}`);}function H(e,t,n){f()&&console.log(`${l} Request: ${e} ${t} (${n} bytes)`);}function W(e,t){f()&&console.log(`${l} Response: status=${e} duration=${t}ms`);}function O(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 pe(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,me=1e3,ge=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??fe,flushIntervalMs:t.flushIntervalMs??me,requestTimeoutMs:t.requestTimeoutMs??ge};}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}),G(t.length,Date.now()-n);}catch(r){V(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;H(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),W(u.status,Date.now()-d),!u.ok){let ue=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${ue}`)}let T=await u.text();return T?JSON.parse(T):{}}catch(u){throw clearTimeout(s),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var ye="@lelemondev/sdk",he="nodejs";function Te(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function we(){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 ke(){try{if(typeof N<"u")return Y().version??"unknown"}catch{}return "unknown"}var y=null;function Z(e){if(!y){let n=Te(),r=we();y={"telemetry.sdk.name":ye,"telemetry.sdk.version":ke(),"telemetry.sdk.language":he},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 q={},g=null,D=null,J="https://api.lelemon.dev";function Ie(e={}){q=e,e.debug&&z(true),D=Z(e.service),_("Initializing SDK",{endpoint:e.endpoint??J,debug:e.debug??false,disabled:e.disabled??false,telemetry:D}),g=Q(e),g.isEnabled()?_("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function C(){return q}function E(){return D}function Se(){return b().isEnabled()}function b(){return g||(g=Q(q)),g}async function xe(){g&&await g.flush();}function Q(e){let t=e.apiKey??Ce("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 x({apiKey:t??"",endpoint:e.endpoint??J,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ce(e){if(typeof process<"u"&&process.env)return process.env[e]}var A=Symbol.for("@lelemondev/sdk:globalContext");function ne(){let e=globalThis;return e[A]||(e[A]={context:{}}),e[A]}function re(e){ne().context=e,c("Global context updated",e);}function v(){return ne().context}function P(e){try{let t=b();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=v(),r=p(),o=h(),i=E(),a={provider:e.provider,model:e.model,input:L(e.input),rawResponse:e.rawResponse?k(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return M(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=b();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=v(),r=p(),o=E(),i={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:h(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};M(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 j(e){try{let t=b();if(!t.isEnabled()){c("Transport disabled, skipping span capture");return}let n=v(),r=p(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=E(),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:L(e.input),output:k(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId: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 ee=1e5,Ee=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],_e=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],te={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function oe(){return C().redaction??{}}function Me(e){let t=e.toLowerCase();return _e.includes(t)?false:!!(Ee.some(r=>t.includes(r))||Re.some(r=>t.includes(r))||(oe().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Oe(e){let t=oe(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(te.emails,"[EMAIL]")),t.phones&&(n=n.replace(te.phones,"[PHONE]")),n}function L(e){return k(e,0)}function k(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>ee&&(n=n.slice(0,ee)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>k(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Me(r)?n[r]="[REDACTED]":n[r]=k(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function qe(){let e=globalThis;return e[K]||(e[K]=new async_hooks.AsyncLocalStorage),e[K]}var se=qe();function h(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function p(){return se.getStore()}function Ae(e){let t=p();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Pe(e){let t=p();t&&t.pendingToolCalls.delete(e);}async function $e(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,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return se.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{Ke(a,d?void 0:s,d);}})}var je=["text","content","message","output","response","result","answer"];function Le(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of je)if(o in r&&typeof r[o]=="string")return r[o];return e}function Ke(e,t,n){let r=b();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=v(),i=Date.now()-e.startTime,a=n?null:Le(t,e.outputKey,e.outputTransform),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:e.sessionId??o.sessionId,userId:e.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 Ne(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=Ae(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&&Pe(e.toolCallId);}var Ue="openrouter.ai",R="openrouter";function ie(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(Ue):false}function ae(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"?ze(i):i}})}function ze(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?Fe(o):o}})}function Fe(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Be(o.bind(t)):o}})}function Be(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&Ge(a))return Ve(a,o,r);let s=Date.now()-r,d=a;return P({provider:R,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:R,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function Ge(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ve(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 T=d.choices?.[0]?.finish_reason;T&&(r.choices[0].finish_reason=T),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:R,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):P({provider:R,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function Rt(e,t){return t&&re(t),C().disabled?(c("Tracing disabled, returning unwrapped client"),e):ie(e)?(F("openrouter"),ae(e)):(I("Client is not configured for OpenRouter. Ensure baseURL is set to openrouter.ai."),e)}
|
|
3
|
-
exports.captureSpan
|
|
2
|
+
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 ue=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var W=ue((Je,fe)=>{fe.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var N=false;function U(e){N=e;}function f(){return N?true:de("LELEMON_DEBUG")==="true"}var l="[Lelemon]";function c(e,t){f()&&M("debug",e,t);}function R(e,t){f()&&M("info",e,t);}function v(e,t){M("warn",e,t);}function _(e,t,n,r){f()&&console.log(`${l} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function I(e,t){console.error(`${l} Failed to capture trace: provider=${e} error=${t.message}`);}function z(e){f()&&console.log(`${l} Wrapped client: provider=${e}`);}function F(e,t){f()&&console.log(`${l} Sending batch: count=${e} endpoint=${t}`);}function B(e,t){f()&&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 V(e,t,n){f()&&console.log(`${l} Request: ${e} ${t} (${n} bytes)`);}function H(e,t){f()&&console.log(`${l} Response: status=${e} duration=${t}ms`);}function M(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,S=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??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();F(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),B(t.length,Date.now()-n);}catch(r){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;V(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),H(u.status,Date.now()-d),!u.ok){let ae=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${ae}`)}let T=await u.text();return T?JSON.parse(T):{}}catch(u){throw clearTimeout(s),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var me="@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 ye(){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 K<"u")return W().version??"unknown"}catch{}return "unknown"}var y=null;function X(e){if(!y){let n=be(),r=ye();y={"telemetry.sdk.name":me,"telemetry.sdk.version":he(),"telemetry.sdk.language":ge},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 q={},g=null,O=null,Z="https://api.lelemon.dev";function we(e={}){q=e,e.debug&&U(true),O=X(e.service),R("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:O}),g=J(e),g.isEnabled()?R("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function x(){return q}function C(){return O}function ke(){return b().isEnabled()}function b(){return g||(g=J(q)),g}async function ve(){g&&await g.flush();}function J(e){let t=e.apiKey??Ie("LELEMON_API_KEY");return !t&&!e.disabled&&v("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new S({apiKey:t??"",endpoint:e.endpoint??Z,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 D=Symbol.for("@lelemondev/sdk:globalContext");function te(){let e=globalThis;return e[D]||(e[D]={context:{}}),e[D]}function ne(e){te().context=e,c("Global context updated",e);}function k(){return te().context}function A(e){try{let t=b();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=k(),r=p(),o=h(),i=C(),a={provider:e.provider,model:e.model,input:j(e.input),rawResponse:e.rawResponse?w(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return _(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));return}}function P(e){try{let t=b();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=k(),r=p(),o=C(),i={provider:e.provider,model:e.model,input:j(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:h(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};_(e.provider,e.model,e.durationMs,"error"),c("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));}}function $(e){try{let t=b();if(!t.isEnabled()){c("Transport disabled, skipping span capture");return}let n=k(),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:j(e.input),output:w(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId: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){I("unknown",t instanceof Error?t:new Error(String(t)));}}var Q=1e5,Se=["api_key","apikey","password","secret","authorization"],xe=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Ce=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],ee={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function re(){return x().redaction??{}}function Ee(e){let t=e.toLowerCase();return Ce.includes(t)?false:!!(Se.some(r=>t.includes(r))||xe.some(r=>t.includes(r))||(re().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Re(e){let t=re(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(ee.emails,"[EMAIL]")),t.phones&&(n=n.replace(ee.phones,"[PHONE]")),n}function j(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"){let n=Re(e);return n.length>Q&&(n=n.slice(0,Q)+"...[truncated]"),n}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 L=Symbol.for("@lelemondev/sdk:traceStorage");function Me(){let e=globalThis;return e[L]||(e[L]=new async_hooks.AsyncLocalStorage),e[L]}var oe=Me();function h(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function p(){return oe.getStore()}function Oe(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 De(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,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return oe.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{$e(a,d?void 0:s,d);}})}var Ae=["text","content","message","output","response","result","answer"];function Pe(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 Ae)if(o in r&&typeof r[o]=="string")return r[o];return e}function $e(e,t,n){let r=b();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=k(),i=Date.now()-e.startTime,a=n?null:Pe(t,e.outputKey,e.outputTransform),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:e.sessionId??o.sessionId,userId:e.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 je(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=Oe(e.toolCallId);$({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 Le="openrouter.ai",E="openrouter";function se(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(Le):false}function ie(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"?Ke(i):i}})}function Ke(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?Ne(o):o}})}function Ne(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Ue(o.bind(t)):o}})}function Ue(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&ze(a))return Fe(a,o,r);let s=Date.now()-r,d=a;return A({provider:E,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 P({provider:E,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function ze(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Fe(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 T=d.choices?.[0]?.finish_reason;T&&(r.choices[0].finish_reason=T),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?P({provider:E,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):A({provider:E,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function St(e,t){return t&&ne(t),x().disabled?(c("Tracing disabled, returning unwrapped client"),e):se(e)?(z("openrouter"),ie(e)):(v("Client is not configured for OpenRouter. Ensure baseURL is set to openrouter.ai."),e)}
|
|
3
|
+
exports.captureSpan=$;exports.flush=ve;exports.getTraceContext=p;exports.init=we;exports.isEnabled=ke;exports.observe=St;exports.span=je;exports.trace=De;//# sourceMappingURL=openrouter.js.map
|
|
4
4
|
//# sourceMappingURL=openrouter.js.map
|
package/dist/openrouter.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var ue=Object.defineProperty;var de=(e,t,n)=>t in e?ue(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 ce=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>de(e,typeof t!="symbol"?t+"":t,n);var W=ce((Qe,ge)=>{ge.exports={name:"@lelemondev/sdk",version:"0.9.8",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var N=false;function U(e){N=e;}function f(){return N?true:le("LELEMON_DEBUG")==="true"}var l="[Lelemon]";function c(e,t){f()&&M("debug",e,t);}function R(e,t){f()&&M("info",e,t);}function v(e,t){M("warn",e,t);}function _(e,t,n,r){f()&&console.log(`${l} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function I(e,t){console.error(`${l} Failed to capture trace: provider=${e} error=${t.message}`);}function z(e){f()&&console.log(`${l} Wrapped client: provider=${e}`);}function F(e,t){f()&&console.log(`${l} Sending batch: count=${e} endpoint=${t}`);}function B(e,t){f()&&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 V(e,t,n){f()&&console.log(`${l} Request: ${e} ${t} (${n} bytes)`);}function H(e,t){f()&&console.log(`${l} Response: status=${e} duration=${t}ms`);}function M(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 le(e){if(typeof process<"u"&&process.env)return process.env[e]}var pe=10,fe=1e3,me=1e4,S=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??pe,flushIntervalMs:t.flushIntervalMs??fe,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();F(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),B(t.length,Date.now()-n);}catch(r){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;V(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),H(u.status,Date.now()-d),!u.ok){let ae=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${ae}`)}let h=await u.text();return h?JSON.parse(h):{}}catch(u){throw clearTimeout(s),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):u}}};var be="@lelemondev/sdk",ye="nodejs";function he(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function 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 we(){try{if(typeof K<"u")return W().version??"unknown"}catch{}return "unknown"}var b=null;function X(e){if(!b){let n=he(),r=Te();b={"telemetry.sdk.name":be,"telemetry.sdk.version":we(),"telemetry.sdk.language":ye},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 D={},m=null,O=null,Z="https://api.lelemon.dev";function ve(e={}){D=e,e.debug&&U(true),O=X(e.service),R("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:O}),m=J(e),m.isEnabled()?R("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function x(){return D}function C(){return O}function Ie(){return g().isEnabled()}function g(){return m||(m=J(D)),m}async function Se(){m&&await m.flush();}function J(e){let t=e.apiKey??xe("LELEMON_API_KEY");return !t&&!e.disabled&&v("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new S({apiKey:t??"",endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function xe(e){if(typeof process<"u"&&process.env)return process.env[e]}var q=Symbol.for("@lelemondev/sdk:globalContext");function te(){let e=globalThis;return e[q]||(e[q]={context:{}}),e[q]}function ne(e){te().context=e,c("Global context updated",e);}function k(){return te().context}function A(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=k(),r=p(),o=y(),i=C(),a={provider:e.provider,model:e.model,input:j(e.input),rawResponse:e.rawResponse?w(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return _(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));return}}function P(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=k(),r=p(),o=C(),i={provider:e.provider,model:e.model,input:j(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:y(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};_(e.provider,e.model,e.durationMs,"error"),c("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));}}function $(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping span capture");return}let n=k(),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:j(e.input),output:w(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:y(),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){I("unknown",t instanceof Error?t:new Error(String(t)));}}var Q=1e5,Ce=["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"],ee={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function re(){return x().redaction??{}}function _e(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Ce.some(r=>t.includes(r))||Ee.some(r=>t.includes(r))||(re().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Me(e){let t=re(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(ee.emails,"[EMAIL]")),t.phones&&(n=n.replace(ee.phones,"[PHONE]")),n}function j(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"){let n=Me(e);return n.length>Q&&(n=n.slice(0,Q)+"...[truncated]"),n}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))_e(r)?n[r]="[REDACTED]":n[r]=w(o,t+1);return n}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function De(){let e=globalThis;return e[L]||(e[L]=new AsyncLocalStorage),e[L]}var oe=De();function y(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function p(){return oe.getStore()}function qe(e){let t=p();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ae(e){let t=p();t&&t.pendingToolCalls.delete(e);}async function Pe(e,t){let n=typeof e=="string"?{name:e}:e,r=p(),o=r?.traceId??y(),i=y(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return oe.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{Le(a,d?void 0:s,d);}})}var $e=["text","content","message","output","response","result","answer"];function je(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 $e)if(o in r&&typeof r[o]=="string")return r[o];return e}function Le(e,t,n){let r=g();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=k(),i=Date.now()-e.startTime,a=n?null:je(t,e.outputKey,e.outputTransform),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:e.sessionId??o.sessionId,userId:e.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 Ke(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=qe(e.toolCallId);$({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Ae(e.toolCallId);}var Ne="openrouter.ai",E="openrouter";function se(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(Ne):false}function ie(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"?Ue(i):i}})}function Ue(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?ze(o):o}})}function ze(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Fe(o.bind(t)):o}})}function Fe(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&Be(a))return Ge(a,o,r);let s=Date.now()-r,d=a;return A({provider:E,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 P({provider:E,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function Be(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*Ge(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 h=d.choices?.[0]?.finish_reason;h&&(r.choices[0].finish_reason=h),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?P({provider:E,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):A({provider:E,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function wt(e,t){return t&&ne(t),x().disabled?(c("Tracing disabled, returning unwrapped client"),e):se(e)?(z("openrouter"),ie(e)):(v("Client is not configured for OpenRouter. Ensure baseURL is set to openrouter.ai."),e)}
|
|
3
|
-
export{
|
|
2
|
+
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 ae=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var H=ae((Ye,pe)=>{pe.exports={name:"@lelemondev/sdk",version:"0.10.0",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./google-genai":{types:"./dist/google-genai.d.ts",import:"./dist/google-genai.mjs",require:"./dist/google-genai.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],"google-genai":["./dist/google-genai.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/genai":"^1.0.0","@google/generative-ai":"^0.24.1","@anthropic-ai/sdk":"^0.82.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^4.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",vite:"^6.0.0",typedoc:"^0.28.18",typescript:"^6.0.0",vitest:"^4.0.0"}};});var K=false;function N(e){K=e;}function f(){return K?true:ue("LELEMON_DEBUG")==="true"}var l="[Lelemon]";function c(e,t){f()&&_("debug",e,t);}function E(e,t){f()&&_("info",e,t);}function k(e,t){_("warn",e,t);}function R(e,t,n,r){f()&&console.log(`${l} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function v(e,t){console.error(`${l} Failed to capture trace: provider=${e} error=${t.message}`);}function U(e){f()&&console.log(`${l} Wrapped client: provider=${e}`);}function z(e,t){f()&&console.log(`${l} Sending batch: count=${e} endpoint=${t}`);}function F(e,t){f()&&console.log(`${l} Batch sent successfully: count=${e} duration=${t}ms`);}function B(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${l} Batch send failed: count=${e} error=${n}`);}function G(e,t,n){f()&&console.log(`${l} Request: ${e} ${t} (${n} bytes)`);}function V(e,t){f()&&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 ue(e){if(typeof process<"u"&&process.env)return process.env[e]}var de=10,ce=1e3,le=1e4,I=class{config;queue=[];flushPromise=null;flushTimer=null;constructor(t){this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??de,flushIntervalMs:t.flushIntervalMs??ce,requestTimeoutMs:t.requestTimeoutMs??le};}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){B(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;G(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 ie=await u.text().catch(()=>"Unknown error");throw new Error(`HTTP ${u.status}: ${ie}`)}let h=await u.text();return h?JSON.parse(h):{}}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",me="nodejs";function ge(){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 ye(){try{if(typeof L<"u")return H().version??"unknown"}catch{}return "unknown"}var b=null;function Y(e){if(!b){let n=ge(),r=be();b={"telemetry.sdk.name":fe,"telemetry.sdk.version":ye(),"telemetry.sdk.language":me},n&&(b["process.runtime.name"]=n.name,b["process.runtime.version"]=n.version),r&&(b["os.type"]=r);}let t={...b};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var O={},m=null,M=null,X="https://api.lelemon.dev";function Te(e={}){O=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}),m=Z(e),m.isEnabled()?E("SDK initialized - tracing enabled"):c("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function S(){return O}function x(){return M}function we(){return g().isEnabled()}function g(){return m||(m=Z(O)),m}async function ke(){m&&await m.flush();}function Z(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 I({apiKey:t??"",endpoint:e.endpoint??X,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=Symbol.for("@lelemondev/sdk:globalContext");function ee(){let e=globalThis;return e[q]||(e[q]={context:{}}),e[q]}function te(e){ee().context=e,c("Global context updated",e);}function w(){return ee().context}function D(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping trace capture");return}let n=w(),r=p(),o=y(),i=x(),a={provider:e.provider,model:e.model,input:$(e.input),rawResponse:e.rawResponse?T(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return R(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){v(e.provider,t instanceof Error?t:new Error(String(t)));return}}function A(e){try{let t=g();if(!t.isEnabled()){c("Transport disabled, skipping error capture");return}let n=w(),r=p(),o=x(),i={provider:e.provider,model:e.model,input:$(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:y(),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){v(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=w(),r=p(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=x(),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:$(e.input),output:T(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:y(),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){v("unknown",t instanceof Error?t:new Error(String(t)));}}var J=1e5,Ie=["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"],Q={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ne(){return S().redaction??{}}function Ce(e){let t=e.toLowerCase();return xe.includes(t)?false:!!(Ie.some(r=>t.includes(r))||Se.some(r=>t.includes(r))||(ne().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Ee(e){let t=ne(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(Q.emails,"[EMAIL]")),t.phones&&(n=n.replace(Q.phones,"[PHONE]")),n}function $(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"){let n=Ee(e);return n.length>J&&(n=n.slice(0,J)+"...[truncated]"),n}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 j=Symbol.for("@lelemondev/sdk:traceStorage");function _e(){let e=globalThis;return e[j]||(e[j]=new AsyncLocalStorage),e[j]}var re=_e();function y(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function p(){return re.getStore()}function Me(e){let t=p();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Oe(e){let t=p();t&&t.pendingToolCalls.delete(e);}async function qe(e,t){let n=typeof e=="string"?{name:e}:e,r=p(),o=r?.traceId??y(),i=y(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return re.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{Pe(a,d?void 0:s,d);}})}var De=["text","content","message","output","response","result","answer"];function Ae(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 De)if(o in r&&typeof r[o]=="string")return r[o];return e}function Pe(e,t,n){let r=g();if(!r.isEnabled()){c("Transport disabled, skipping root span");return}let o=w(),i=Date.now()-e.startTime,a=n?null:Ae(t,e.outputKey,e.outputTransform),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:e.sessionId??o.sessionId,userId:e.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&&Oe(e.toolCallId);}var je="openrouter.ai",C="openrouter";function oe(e){if(!e||typeof e!="object")return false;let t=e;return t.chat?.completions?.create?(t.baseURL||"").includes(je):false}function se(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"?Le(i):i}})}function Le(e){return e&&new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="completions"&&o&&typeof o=="object"?Ke(o):o}})}function Ke(e){return new Proxy(e,{get(t,n,r){let o=Reflect.get(t,n,r);return n==="create"&&typeof o=="function"?Ne(o.bind(t)):o}})}function Ne(e){return async function(...n){let r=Date.now(),o=n[0]||{},i=o.stream===true;try{let a=await e(...n);if(i&&Ue(a))return ze(a,o,r);let s=Date.now()-r,d=a;return D({provider:C,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 A({provider:C,model:o.model||"unknown",input:o.messages,error:a instanceof Error?a:new Error(String(a)),durationMs:s,streaming:i}),a}}}function Ue(e){return e!=null&&typeof e[Symbol.asyncIterator]=="function"}async function*ze(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 h=d.choices?.[0]?.finish_reason;h&&(r.choices[0].finish_reason=h),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?A({provider:C,model:t.model||"unknown",input:t.messages,error:o,durationMs:s,streaming:true}):D({provider:C,model:t.model||"unknown",input:t.messages,rawResponse:r,durationMs:s,status:"success",streaming:true,firstTokenMs:i});}}function bt(e,t){return t&&te(t),S().disabled?(c("Tracing disabled, returning unwrapped client"),e):oe(e)?(U("openrouter"),se(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,Te as init,we as isEnabled,bt as observe,$e as span,qe 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.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Automatic LLM observability. Wrap your client, everything is traced.",
|
|
5
5
|
"author": "Lelemon <info@lelemon.dev>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,6 +57,11 @@
|
|
|
57
57
|
"import": "./dist/gemini.mjs",
|
|
58
58
|
"require": "./dist/gemini.js"
|
|
59
59
|
},
|
|
60
|
+
"./google-genai": {
|
|
61
|
+
"types": "./dist/google-genai.d.ts",
|
|
62
|
+
"import": "./dist/google-genai.mjs",
|
|
63
|
+
"require": "./dist/google-genai.js"
|
|
64
|
+
},
|
|
60
65
|
"./openrouter": {
|
|
61
66
|
"types": "./dist/openrouter.d.ts",
|
|
62
67
|
"import": "./dist/openrouter.mjs",
|
|
@@ -103,6 +108,9 @@
|
|
|
103
108
|
"gemini": [
|
|
104
109
|
"./dist/gemini.d.ts"
|
|
105
110
|
],
|
|
111
|
+
"google-genai": [
|
|
112
|
+
"./dist/google-genai.d.ts"
|
|
113
|
+
],
|
|
106
114
|
"openrouter": [
|
|
107
115
|
"./dist/openrouter.d.ts"
|
|
108
116
|
],
|
|
@@ -151,14 +159,17 @@
|
|
|
151
159
|
},
|
|
152
160
|
"devDependencies": {
|
|
153
161
|
"@aws-sdk/client-bedrock-runtime": "^3.962.0",
|
|
162
|
+
"@google/genai": "^1.0.0",
|
|
154
163
|
"@google/generative-ai": "^0.24.1",
|
|
155
|
-
"@
|
|
156
|
-
"@
|
|
164
|
+
"@anthropic-ai/sdk": "^0.82.0",
|
|
165
|
+
"@types/node": "^22.0.0",
|
|
166
|
+
"@vitest/coverage-v8": "^4.0.0",
|
|
157
167
|
"dotenv": "^17.2.3",
|
|
158
168
|
"openai": "^6.15.0",
|
|
159
169
|
"tsup": "^8.5.1",
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
170
|
+
"vite": "^6.0.0",
|
|
171
|
+
"typedoc": "^0.28.18",
|
|
172
|
+
"typescript": "^6.0.0",
|
|
173
|
+
"vitest": "^4.0.0"
|
|
163
174
|
}
|
|
164
175
|
}
|