@lelemondev/sdk 0.9.6 → 0.9.8
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 +102 -1
- package/dist/anthropic.d.mts +2 -2
- package/dist/anthropic.d.ts +2 -2
- package/dist/anthropic.js +2 -2
- package/dist/anthropic.mjs +2 -2
- package/dist/bedrock.d.mts +2 -2
- package/dist/bedrock.d.ts +2 -2
- package/dist/bedrock.js +2 -2
- package/dist/bedrock.mjs +2 -2
- package/dist/{capture-ChybLulj.d.mts → capture-CiUL-4hv.d.mts} +82 -9
- package/dist/{capture-ChybLulj.d.ts → capture-CiUL-4hv.d.ts} +82 -9
- package/dist/gemini.d.mts +2 -2
- package/dist/gemini.d.ts +2 -2
- package/dist/gemini.js +2 -2
- package/dist/gemini.mjs +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/openai.d.mts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +2 -2
- package/dist/openai.mjs +2 -2
- package/dist/openrouter.d.mts +2 -2
- package/dist/openrouter.d.ts +2 -2
- package/dist/openrouter.js +2 -2
- package/dist/openrouter.mjs +2 -2
- package/package.json +1 -1
package/dist/bedrock.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var le=Object.defineProperty;var pe=(e,t,n)=>t in e?le(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var L=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var me=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var I=(e,t,n)=>pe(e,typeof t!="symbol"?t+"":t,n);var X=me((nt,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.9.6",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var z=false;function F(e){z=e;}function k(){return z?true:fe("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&O("debug",e,t);}function _(e,t){k()&&O("info",e,t);}function M(e,t){O("warn",e,t);}function q(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function R(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function G(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function V(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function J(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function W(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function H(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function Y(e,t){k()&&console.log(`${m} 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(`${m} ${t}`,n):r(`${m} ${t}`);}function fe(e){if(typeof process<"u"&&process.env)return process.env[e]}var ge=10,ye=1e3,ke=1e4,D=class{constructor(t){I(this,"config");I(this,"queue",[]);I(this,"flushPromise",null);I(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ge,flushIntervalMs:t.flushIntervalMs??ye,requestTimeoutMs:t.requestTimeoutMs??ke};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();V(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),J(t.length,Date.now()-n);}catch(r){W(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 u=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),p=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(u),Y(s.status,Date.now()-p),!s.ok){let d=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${d}`)}let c=await s.text();return c?JSON.parse(c):{}}catch(s){throw clearTimeout(u),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var we="@lelemondev/sdk",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 ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Ie(){try{if(typeof L<"u")return X().version??"unknown"}catch{}return "unknown"}var T=null;function Z(e){if(!T){let n=Te(),r=ve();T={"telemetry.sdk.name":we,"telemetry.sdk.version":Ie(),"telemetry.sdk.language":he},n&&(T["process.runtime.name"]=n.name,T["process.runtime.version"]=n.version),r&&(T["os.type"]=r);}let t={...T};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var P={},b=null,A=null,ee="https://api.lelemon.dev";function xe(e={}){P=e,e.debug&&F(true),A=Z(e.service),_("Initializing SDK",{endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??false,telemetry:A}),b=ne(e),b.isEnabled()?_("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function te(){return P}function B(){return A}function Ce(){return w().isEnabled()}function w(){return b||(b=ne(P)),b}async function Ee(){b&&await b.flush();}function ne(e){let t=e.apiKey??Me("LELEMON_API_KEY");return !t&&!e.disabled&&M("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new D({apiKey:t??"",endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Me(e){if(typeof process<"u"&&process.env)return process.env[e]}var $=Symbol.for("@lelemondev/sdk:globalContext");function oe(){let e=globalThis;return e[$]||(e[$]={context:{}}),e[$]}function se(e){oe().context=e,l("Global context updated",e);}function x(){return oe().context}function C(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=v(),i=B(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){R(e.provider,t instanceof Error?t:new Error(String(t)));return}}function h(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=B(),i={provider:e.provider,model:e.model,input:N(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:v(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){R(e.provider,t instanceof Error?t:new Error(String(t)));}}function U(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=B(),u={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete u._traceId,delete u._parentSpanId;let p={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:N(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:v(),parentSpanId:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:u,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(p);}catch(t){R("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,Re=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Be=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function _e(e){let t=e.toLowerCase();return Be.includes(t)?false:!!(Re.some(n=>t.includes(n))||De.some(n=>t.includes(n)))}function N(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string")return e.length>re?e.slice(0,re)+"...[truncated]":e;if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))_e(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var j=Symbol.for("@lelemondev/sdk:traceStorage");function Oe(){let e=globalThis;return e[j]||(e[j]=new AsyncLocalStorage),e[j]}var ie=Oe();function v(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ie.getStore()}function K(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function Ae(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Pe(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function $e(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??v(),i=v(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return ie.run(a,async()=>{let u,p;try{return u=await t(),u}catch(s){throw p=s instanceof Error?s:new Error(String(s)),s}finally{Ue(a,p?void 0:u,p);}})}function Ue(e,t,n){let r=w();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),i=Date.now()-e.startTime,a=n?null:t,u={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(u);}function Ne(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Ae(e.toolCallId);U({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 g="bedrock";function ae(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="BedrockRuntimeClient")return true;let n=e;return typeof n.send!="function"||!n.config||typeof n.config!="object"?false:"region"in n.config}function ue(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="send"&&typeof i=="function"?je(i.bind(n)):i}})}function je(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Ke(e,n);case "ConverseStreamCommand":return Le(e,n);case "InvokeModelCommand":return Fe(e,n);case "InvokeModelWithResponseStreamCommand":return Ge(e,n);default:return e(n)}}}async function Ke(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=C({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:de(o),durationMs:i,status:"success",streaming:!1});if(a){let u=ce(o);u.length>0&&K(u,a);}return o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Le(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:ze(o.stream,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*ze(e,t,n){let r={output:{message:{role:"assistant",content:[]}},usage:{inputTokens:0,outputTokens:0}},o=null,i,a=false,u=new Map,p=new Map;try{for await(let s of e){if(s.contentBlockStart){let c=s.contentBlockStart.contentBlockIndex;if(s.contentBlockStart.start?.toolUse){let d=s.contentBlockStart.start.toolUse;u.set(c,{toolUse:{toolUseId:d.toolUseId,name:d.name,input:{}}}),p.set(c,"");}else u.set(c,{text:""});}if(s.contentBlockDelta){let c=s.contentBlockDelta.contentBlockIndex,d=u.get(c);if(d&&s.contentBlockDelta.delta?.text&&(a||(a=!0,i=Date.now()-n),d.text=(d.text||"")+s.contentBlockDelta.delta.text),d?.toolUse&&s.contentBlockDelta.delta?.toolUse?.input){let y=p.get(c)||"";p.set(c,y+s.contentBlockDelta.delta.toolUse.input);}}if(s.contentBlockStop){let c=s.contentBlockStop.contentBlockIndex,d=u.get(c),y=p.get(c);if(d?.toolUse&&y)try{d.toolUse.input=JSON.parse(y);}catch{}}s.messageStop?.stopReason&&(r.stopReason=s.messageStop.stopReason),s.metadata?.usage&&(r.usage={inputTokens:s.metadata.usage.inputTokens||0,outputTokens:s.metadata.usage.outputTokens||0}),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n,c=Array.from(u.entries()).sort((d,y)=>d[0]-y[0]).map(([,d])=>d);if(r.output.message.content=c,o)h({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=C({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:de(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=ce(r);y.length>0&&K(y,d);}}}}async function Fe(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Je(o.body);return C({provider:g,model:r.modelId||"unknown",input:E(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Ge(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:Ve(o.body,r,n)}:o}catch(o){throw h({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Ve(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=We(i.chunk.bytes);a&&r.push(a);}yield i;}}catch(i){throw o=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-n;o?h({provider:g,model:t.modelId||"unknown",input:E(t.body),error:o,durationMs:i,streaming:true}):C({provider:g,model:t.modelId||"unknown",input:E(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function de(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function ce(e){let t=[],n=e.output?.message?.content;if(Array.isArray(n))for(let r of n)r.toolUse?.toolUseId&&t.push(r.toolUse.toolUseId);return t}function E(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Je(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function We(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function St(e,t){return t&&se(t),te().disabled?(l("Tracing disabled, returning unwrapped client"),e):ae(e)?(G("bedrock"),ue(e)):(M("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
3
|
-
export{
|
|
2
|
+
var me=Object.defineProperty;var fe=(e,t,n)=>t in e?me(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var z=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ge=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var I=(e,t,n)=>fe(e,typeof t!="symbol"?t+"":t,n);var Z=ge((at,Te)=>{Te.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 F=false;function G(e){F=e;}function k(){return F?true:ye("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&q("debug",e,t);}function B(e,t){k()&&q("info",e,t);}function R(e,t){q("warn",e,t);}function O(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function M(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function V(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function J(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function W(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){k()&&console.log(`${m} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${m} ${t}`,n):r(`${m} ${t}`);}function ye(e){if(typeof process<"u"&&process.env)return process.env[e]}var ke=10,be=1e3,we=1e4,D=class{constructor(t){I(this,"config");I(this,"queue",[]);I(this,"flushPromise",null);I(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ke,flushIntervalMs:t.flushIntervalMs??be,requestTimeoutMs:t.requestTimeoutMs??we};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();J(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),W(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;Y(t,o,a?.length??0);let u=setTimeout(()=>{i.abort();},this.config.requestTimeoutMs),p=Date.now();try{let s=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:a,signal:i.signal});if(clearTimeout(u),X(s.status,Date.now()-p),!s.ok){let d=await s.text().catch(()=>"Unknown error");throw new Error(`HTTP ${s.status}: ${d}`)}let c=await s.text();return c?JSON.parse(c):{}}catch(s){throw clearTimeout(u),s instanceof Error&&s.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):s}}};var he="@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 z<"u")return Z().version??"unknown"}catch{}return "unknown"}var h=null;function ee(e){if(!h){let n=Ie(),r=Se();h={"telemetry.sdk.name":he,"telemetry.sdk.version":xe(),"telemetry.sdk.language":ve},n&&(h["process.runtime.name"]=n.name,h["process.runtime.version"]=n.version),r&&(h["os.type"]=r);}let t={...h};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var U={},b=null,P=null,te="https://api.lelemon.dev";function Ee(e={}){U=e,e.debug&&G(true),P=ee(e.service),B("Initializing SDK",{endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??false,telemetry:P}),b=ne(e),b.isEnabled()?B("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function _(){return U}function A(){return P}function Re(){return w().isEnabled()}function w(){return b||(b=ne(U)),b}async function Me(){b&&await b.flush();}function ne(e){let t=e.apiKey??De("LELEMON_API_KEY");return !t&&!e.disabled&&R("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new D({apiKey:t??"",endpoint:e.endpoint??te,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function De(e){if(typeof process<"u"&&process.env)return process.env[e]}var $=Symbol.for("@lelemondev/sdk:globalContext");function se(){let e=globalThis;return e[$]||(e[$]={context:{}}),e[$]}function ie(e){se().context=e,l("Global context updated",e);}function x(){return se().context}function C(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=v(),i=A(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...i?{_telemetry:i}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return O(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));return}}function T(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=A(),i={provider:e.provider,model:e.model,input:N(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:v(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};O(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){M(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,a=A(),u={...n.metadata,...e.metadata,...a?{_telemetry:a}:{}};delete u._traceId,delete u._parentSpanId;let p={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:N(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:v(),parentSpanId:i??r?.currentSpanId,toolCallId:e.toolCallId,metadata:u,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(p);}catch(t){M("unknown",t instanceof Error?t:new Error(String(t)));}}var re=1e5,_e=["api_key","apikey","password","secret","authorization"],Ae=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Be=["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 Oe(e){let t=e.toLowerCase();return Be.includes(t)?false:!!(_e.some(r=>t.includes(r))||Ae.some(r=>t.includes(r))||(ae().keys??[]).some(r=>t.includes(r.toLowerCase())))}function qe(e){let t=ae(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(oe.emails,"[EMAIL]")),t.phones&&(n=n.replace(oe.phones,"[PHONE]")),n}function N(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=qe(e);return n.length>re&&(n=n.slice(0,re)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Oe(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function Ue(){let e=globalThis;return e[K]||(e[K]=new AsyncLocalStorage),e[K]}var ue=Ue();function v(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ue.getStore()}function L(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function $e(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function je(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Ne(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??v(),i=v(),a={traceId:o,rootSpanId:i,currentSpanId:i,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ue.run(a,async()=>{let u,p;try{return u=await t(),u}catch(s){throw p=s instanceof Error?s:new Error(String(s)),s}finally{ze(a,p?void 0:u,p);}})}var Ke=["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 Ke)if(o in r&&typeof r[o]=="string")return r[o];return e}function ze(e,t,n){let r=w();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),i=Date.now()-e.startTime,a=n?null:Le(t,e.outputKey,e.outputTransform),u={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:a,inputTokens:0,outputTokens:0,durationMs:i,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:i,hasError:!!n}),r.enqueue(u);}function Fe(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=$e(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&&je(e.toolCallId);}var g="bedrock";function de(e){if(!e||typeof e!="object")return false;if(e.constructor?.name==="BedrockRuntimeClient")return true;let n=e;return typeof n.send!="function"||!n.config||typeof n.config!="object"?false:"region"in n.config}function ce(e){let t=e;return new Proxy(t,{get(n,r,o){let i=Reflect.get(n,r,o);return r==="send"&&typeof i=="function"?Ge(i.bind(n)):i}})}function Ge(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Ve(e,n);case "ConverseStreamCommand":return Je(e,n);case "InvokeModelCommand":return He(e,n);case "InvokeModelWithResponseStreamCommand":return Ye(e,n);default:return e(n)}}}async function Ve(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=C({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:le(o),durationMs:i,status:"success",streaming:!1});if(a){let u=pe(o);u.length>0&&L(u,a);}return o}catch(o){throw T({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Je(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:We(o.stream,r,n)}:o}catch(o){throw T({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*We(e,t,n){let r={output:{message:{role:"assistant",content:[]}},usage:{inputTokens:0,outputTokens:0}},o=null,i,a=false,u=new Map,p=new Map;try{for await(let s of e){if(s.contentBlockStart){let c=s.contentBlockStart.contentBlockIndex;if(s.contentBlockStart.start?.toolUse){let d=s.contentBlockStart.start.toolUse;u.set(c,{toolUse:{toolUseId:d.toolUseId,name:d.name,input:{}}}),p.set(c,"");}else u.set(c,{text:""});}if(s.contentBlockDelta){let c=s.contentBlockDelta.contentBlockIndex,d=u.get(c);if(d&&s.contentBlockDelta.delta?.text&&(a||(a=!0,i=Date.now()-n),d.text=(d.text||"")+s.contentBlockDelta.delta.text),d?.toolUse&&s.contentBlockDelta.delta?.toolUse?.input){let y=p.get(c)||"";p.set(c,y+s.contentBlockDelta.delta.toolUse.input);}}if(s.contentBlockStop){let c=s.contentBlockStop.contentBlockIndex,d=u.get(c),y=p.get(c);if(d?.toolUse&&y)try{d.toolUse.input=JSON.parse(y);}catch{}}s.messageStop?.stopReason&&(r.stopReason=s.messageStop.stopReason),s.metadata?.usage&&(r.usage={inputTokens:s.metadata.usage.inputTokens||0,outputTokens:s.metadata.usage.outputTokens||0}),yield s;}}catch(s){throw o=s instanceof Error?s:new Error(String(s)),s}finally{let s=Date.now()-n,c=Array.from(u.entries()).sort((d,y)=>d[0]-y[0]).map(([,d])=>d);if(r.output.message.content=c,o)T({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=C({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:le(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=pe(r);y.length>0&&L(y,d);}}}}async function He(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Ze(o.body);return C({provider:g,model:r.modelId||"unknown",input:E(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw T({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function Ye(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:Xe(o.body,r,n)}:o}catch(o){throw T({provider:g,model:r.modelId||"unknown",input:E(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Xe(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Qe(i.chunk.bytes);a&&r.push(a);}yield i;}}catch(i){throw o=i instanceof Error?i:new Error(String(i)),i}finally{let i=Date.now()-n;o?T({provider:g,model:t.modelId||"unknown",input:E(t.body),error:o,durationMs:i,streaming:true}):C({provider:g,model:t.modelId||"unknown",input:E(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function le(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function pe(e){let t=[],n=e.output?.message?.content;if(Array.isArray(n))for(let r of n)r.toolUse?.toolUseId&&t.push(r.toolUse.toolUseId);return t}function E(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Ze(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Qe(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Mt(e,t){return t&&ie(t),_().disabled?(l("Tracing disabled, returning unwrapped client"),e):de(e)?(V("bedrock"),ce(e)):(R("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
3
|
+
export{j as captureSpan,Me as flush,f as getTraceContext,Ee as init,Re as isEnabled,Mt as observe,Fe as span,Ne as trace};//# sourceMappingURL=bedrock.mjs.map
|
|
4
4
|
//# sourceMappingURL=bedrock.mjs.map
|
|
@@ -9,6 +9,16 @@ interface ServiceConfig {
|
|
|
9
9
|
/** Deployment environment (e.g., "production", "staging", "development") */
|
|
10
10
|
environment?: string;
|
|
11
11
|
}
|
|
12
|
+
interface RedactionConfig {
|
|
13
|
+
/** Custom regex patterns to redact (replaced with [REDACTED]) */
|
|
14
|
+
patterns?: RegExp[];
|
|
15
|
+
/** Additional key names to redact (case-insensitive, partial match) */
|
|
16
|
+
keys?: string[];
|
|
17
|
+
/** Redact all email addresses (replaced with [EMAIL]) */
|
|
18
|
+
emails?: boolean;
|
|
19
|
+
/** Redact phone numbers with 9+ digits (replaced with [PHONE]) */
|
|
20
|
+
phones?: boolean;
|
|
21
|
+
}
|
|
12
22
|
interface LelemonConfig {
|
|
13
23
|
/** API key (or set LELEMON_API_KEY env var) */
|
|
14
24
|
apiKey?: string;
|
|
@@ -26,6 +36,8 @@ interface LelemonConfig {
|
|
|
26
36
|
requestTimeoutMs?: number;
|
|
27
37
|
/** Service metadata for telemetry */
|
|
28
38
|
service?: ServiceConfig;
|
|
39
|
+
/** Optional PII redaction configuration */
|
|
40
|
+
redaction?: RedactionConfig;
|
|
29
41
|
}
|
|
30
42
|
interface SDKTelemetry {
|
|
31
43
|
/** SDK name */
|
|
@@ -139,6 +151,14 @@ interface TraceContext {
|
|
|
139
151
|
metadata?: Record<string, unknown>;
|
|
140
152
|
/** Trace tags */
|
|
141
153
|
tags?: string[];
|
|
154
|
+
/** Output extraction config */
|
|
155
|
+
outputKey?: string | false;
|
|
156
|
+
/** Output transform function */
|
|
157
|
+
outputTransform?: (result: unknown) => unknown;
|
|
158
|
+
/** Session ID for grouping traces */
|
|
159
|
+
sessionId?: string;
|
|
160
|
+
/** User ID for filtering by user */
|
|
161
|
+
userId?: string;
|
|
142
162
|
/** Map of toolCallId → llmSpanId for linking tool spans to their parent LLM */
|
|
143
163
|
pendingToolCalls: Map<string, string>;
|
|
144
164
|
}
|
|
@@ -151,6 +171,48 @@ interface TraceOptions {
|
|
|
151
171
|
metadata?: Record<string, unknown>;
|
|
152
172
|
/** Tags for filtering */
|
|
153
173
|
tags?: string[];
|
|
174
|
+
/**
|
|
175
|
+
* Key to extract from result object for cleaner output display.
|
|
176
|
+
* If not specified, auto-detection tries: text, content, message, output, response, result, answer.
|
|
177
|
+
* Set to `false` to disable auto-extraction and show raw result.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* // Auto-extract 'text' field
|
|
181
|
+
* trace({ name: 'agent' }, async () => ({ text: 'hello', tokens: 100 }));
|
|
182
|
+
* // Output: "hello"
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* // Explicit key
|
|
186
|
+
* trace({ name: 'agent', outputKey: 'response' }, async () => ({ response: 'hello' }));
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* // Disable auto-extraction
|
|
190
|
+
* trace({ name: 'agent', outputKey: false }, async () => ({ a: 1, b: 2 }));
|
|
191
|
+
* // Output: { a: 1, b: 2 }
|
|
192
|
+
*/
|
|
193
|
+
outputKey?: string | false;
|
|
194
|
+
/**
|
|
195
|
+
* Transform function for custom output formatting.
|
|
196
|
+
* Takes precedence over outputKey.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* trace({
|
|
200
|
+
* name: 'agent',
|
|
201
|
+
* outputTransform: (r) => `Response: ${r.text} (${r.tokens} tokens)`
|
|
202
|
+
* }, async () => ({ text: 'hello', tokens: 100 }));
|
|
203
|
+
* // Output: "Response: hello (100 tokens)"
|
|
204
|
+
*/
|
|
205
|
+
outputTransform?: (result: unknown) => unknown;
|
|
206
|
+
/**
|
|
207
|
+
* Session ID for grouping related traces (e.g., conversation ID).
|
|
208
|
+
* Useful for multi-tenant servers where each request has different context.
|
|
209
|
+
*/
|
|
210
|
+
sessionId?: string;
|
|
211
|
+
/**
|
|
212
|
+
* User ID for filtering traces by user.
|
|
213
|
+
* Useful for multi-tenant servers where each request has different context.
|
|
214
|
+
*/
|
|
215
|
+
userId?: string;
|
|
154
216
|
}
|
|
155
217
|
interface SpanOptions {
|
|
156
218
|
/** Span type */
|
|
@@ -179,22 +241,33 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
179
241
|
/**
|
|
180
242
|
* Execute a function within a trace context.
|
|
181
243
|
* Creates a root "agent" span that contains all LLM calls and tool executions.
|
|
182
|
-
* The result of the function becomes the output of the root span.
|
|
183
244
|
*
|
|
184
|
-
*
|
|
245
|
+
* **Output Auto-Extraction:** If the function returns an object with common text fields
|
|
246
|
+
* (`text`, `content`, `message`, `output`, `response`, `result`, `answer`),
|
|
247
|
+
* the SDK automatically extracts that field for cleaner display.
|
|
248
|
+
* Use `outputKey` to specify a custom field, or `outputKey: false` to disable.
|
|
249
|
+
*
|
|
250
|
+
* @example Simple usage
|
|
185
251
|
* ```typescript
|
|
186
252
|
* await trace('sales-agent', async () => {
|
|
187
|
-
*
|
|
188
|
-
*
|
|
253
|
+
* return { text: 'Hello!', tokens: 100 };
|
|
254
|
+
* // Output shown: "Hello!" (auto-extracted from 'text')
|
|
255
|
+
* });
|
|
256
|
+
* ```
|
|
257
|
+
*
|
|
258
|
+
* @example With options and explicit outputKey
|
|
259
|
+
* ```typescript
|
|
260
|
+
* await trace({ name: 'agent', outputKey: 'reply' }, async () => {
|
|
261
|
+
* return { reply: 'Hello!', cost: 0.01 };
|
|
262
|
+
* // Output shown: "Hello!"
|
|
189
263
|
* });
|
|
190
264
|
* ```
|
|
191
265
|
*
|
|
192
|
-
* @example
|
|
266
|
+
* @example Disable auto-extraction
|
|
193
267
|
* ```typescript
|
|
194
|
-
* await trace({ name: '
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* return client.send(new ConverseCommand({...}));
|
|
268
|
+
* await trace({ name: 'agent', outputKey: false }, async () => {
|
|
269
|
+
* return { a: 1, b: 2 };
|
|
270
|
+
* // Output shown: { a: 1, b: 2 }
|
|
198
271
|
* });
|
|
199
272
|
* ```
|
|
200
273
|
*/
|
|
@@ -9,6 +9,16 @@ interface ServiceConfig {
|
|
|
9
9
|
/** Deployment environment (e.g., "production", "staging", "development") */
|
|
10
10
|
environment?: string;
|
|
11
11
|
}
|
|
12
|
+
interface RedactionConfig {
|
|
13
|
+
/** Custom regex patterns to redact (replaced with [REDACTED]) */
|
|
14
|
+
patterns?: RegExp[];
|
|
15
|
+
/** Additional key names to redact (case-insensitive, partial match) */
|
|
16
|
+
keys?: string[];
|
|
17
|
+
/** Redact all email addresses (replaced with [EMAIL]) */
|
|
18
|
+
emails?: boolean;
|
|
19
|
+
/** Redact phone numbers with 9+ digits (replaced with [PHONE]) */
|
|
20
|
+
phones?: boolean;
|
|
21
|
+
}
|
|
12
22
|
interface LelemonConfig {
|
|
13
23
|
/** API key (or set LELEMON_API_KEY env var) */
|
|
14
24
|
apiKey?: string;
|
|
@@ -26,6 +36,8 @@ interface LelemonConfig {
|
|
|
26
36
|
requestTimeoutMs?: number;
|
|
27
37
|
/** Service metadata for telemetry */
|
|
28
38
|
service?: ServiceConfig;
|
|
39
|
+
/** Optional PII redaction configuration */
|
|
40
|
+
redaction?: RedactionConfig;
|
|
29
41
|
}
|
|
30
42
|
interface SDKTelemetry {
|
|
31
43
|
/** SDK name */
|
|
@@ -139,6 +151,14 @@ interface TraceContext {
|
|
|
139
151
|
metadata?: Record<string, unknown>;
|
|
140
152
|
/** Trace tags */
|
|
141
153
|
tags?: string[];
|
|
154
|
+
/** Output extraction config */
|
|
155
|
+
outputKey?: string | false;
|
|
156
|
+
/** Output transform function */
|
|
157
|
+
outputTransform?: (result: unknown) => unknown;
|
|
158
|
+
/** Session ID for grouping traces */
|
|
159
|
+
sessionId?: string;
|
|
160
|
+
/** User ID for filtering by user */
|
|
161
|
+
userId?: string;
|
|
142
162
|
/** Map of toolCallId → llmSpanId for linking tool spans to their parent LLM */
|
|
143
163
|
pendingToolCalls: Map<string, string>;
|
|
144
164
|
}
|
|
@@ -151,6 +171,48 @@ interface TraceOptions {
|
|
|
151
171
|
metadata?: Record<string, unknown>;
|
|
152
172
|
/** Tags for filtering */
|
|
153
173
|
tags?: string[];
|
|
174
|
+
/**
|
|
175
|
+
* Key to extract from result object for cleaner output display.
|
|
176
|
+
* If not specified, auto-detection tries: text, content, message, output, response, result, answer.
|
|
177
|
+
* Set to `false` to disable auto-extraction and show raw result.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* // Auto-extract 'text' field
|
|
181
|
+
* trace({ name: 'agent' }, async () => ({ text: 'hello', tokens: 100 }));
|
|
182
|
+
* // Output: "hello"
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* // Explicit key
|
|
186
|
+
* trace({ name: 'agent', outputKey: 'response' }, async () => ({ response: 'hello' }));
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* // Disable auto-extraction
|
|
190
|
+
* trace({ name: 'agent', outputKey: false }, async () => ({ a: 1, b: 2 }));
|
|
191
|
+
* // Output: { a: 1, b: 2 }
|
|
192
|
+
*/
|
|
193
|
+
outputKey?: string | false;
|
|
194
|
+
/**
|
|
195
|
+
* Transform function for custom output formatting.
|
|
196
|
+
* Takes precedence over outputKey.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* trace({
|
|
200
|
+
* name: 'agent',
|
|
201
|
+
* outputTransform: (r) => `Response: ${r.text} (${r.tokens} tokens)`
|
|
202
|
+
* }, async () => ({ text: 'hello', tokens: 100 }));
|
|
203
|
+
* // Output: "Response: hello (100 tokens)"
|
|
204
|
+
*/
|
|
205
|
+
outputTransform?: (result: unknown) => unknown;
|
|
206
|
+
/**
|
|
207
|
+
* Session ID for grouping related traces (e.g., conversation ID).
|
|
208
|
+
* Useful for multi-tenant servers where each request has different context.
|
|
209
|
+
*/
|
|
210
|
+
sessionId?: string;
|
|
211
|
+
/**
|
|
212
|
+
* User ID for filtering traces by user.
|
|
213
|
+
* Useful for multi-tenant servers where each request has different context.
|
|
214
|
+
*/
|
|
215
|
+
userId?: string;
|
|
154
216
|
}
|
|
155
217
|
interface SpanOptions {
|
|
156
218
|
/** Span type */
|
|
@@ -179,22 +241,33 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
179
241
|
/**
|
|
180
242
|
* Execute a function within a trace context.
|
|
181
243
|
* Creates a root "agent" span that contains all LLM calls and tool executions.
|
|
182
|
-
* The result of the function becomes the output of the root span.
|
|
183
244
|
*
|
|
184
|
-
*
|
|
245
|
+
* **Output Auto-Extraction:** If the function returns an object with common text fields
|
|
246
|
+
* (`text`, `content`, `message`, `output`, `response`, `result`, `answer`),
|
|
247
|
+
* the SDK automatically extracts that field for cleaner display.
|
|
248
|
+
* Use `outputKey` to specify a custom field, or `outputKey: false` to disable.
|
|
249
|
+
*
|
|
250
|
+
* @example Simple usage
|
|
185
251
|
* ```typescript
|
|
186
252
|
* await trace('sales-agent', async () => {
|
|
187
|
-
*
|
|
188
|
-
*
|
|
253
|
+
* return { text: 'Hello!', tokens: 100 };
|
|
254
|
+
* // Output shown: "Hello!" (auto-extracted from 'text')
|
|
255
|
+
* });
|
|
256
|
+
* ```
|
|
257
|
+
*
|
|
258
|
+
* @example With options and explicit outputKey
|
|
259
|
+
* ```typescript
|
|
260
|
+
* await trace({ name: 'agent', outputKey: 'reply' }, async () => {
|
|
261
|
+
* return { reply: 'Hello!', cost: 0.01 };
|
|
262
|
+
* // Output shown: "Hello!"
|
|
189
263
|
* });
|
|
190
264
|
* ```
|
|
191
265
|
*
|
|
192
|
-
* @example
|
|
266
|
+
* @example Disable auto-extraction
|
|
193
267
|
* ```typescript
|
|
194
|
-
* await trace({ name: '
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* return client.send(new ConverseCommand({...}));
|
|
268
|
+
* await trace({ name: 'agent', outputKey: false }, async () => {
|
|
269
|
+
* return { a: 1, b: 2 };
|
|
270
|
+
* // Output shown: { a: 1, b: 2 }
|
|
198
271
|
* });
|
|
199
272
|
* ```
|
|
200
273
|
*/
|
package/dist/gemini.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-CiUL-4hv.mjs';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-CiUL-4hv.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Google Gemini Provider Entry Point
|
package/dist/gemini.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-CiUL-4hv.js';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-CiUL-4hv.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Google Gemini Provider Entry Point
|
package/dist/gemini.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('async_hooks');/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var pe=Object.defineProperty;var fe=(e,t,n)=>t in e?pe(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var N=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ge=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var v=(e,t,n)=>fe(e,typeof t!="symbol"?t+"":t,n);var X=ge((st,be)=>{be.exports={name:"@lelemondev/sdk",version:"0.9.6",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var U=false;function z(e){U=e;}function g(){return U?true:me("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&_("debug",e,t);}function q(e,t){g()&&_("info",e,t);}function I(e,t){_("warn",e,t);}function D(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function V(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function B(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function Y(e,t){g()&&console.log(`${p} Response: status=${e} duration=${t}ms`);}function _(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${p} ${t}`,n):r(`${p} ${t}`);}function me(e){if(typeof process<"u"&&process.env)return process.env[e]}var he=10,Ce=1e3,ye=1e4,M=class{constructor(t){v(this,"config");v(this,"queue",[]);v(this,"flushPromise",null);v(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??he,flushIntervalMs:t.flushIntervalMs??Ce,requestTimeoutMs:t.requestTimeoutMs??ye};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();V(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),B(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;W(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),Y(a.status,Date.now()-u),!a.ok){let k=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${k}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var we="@lelemondev/sdk",Te="nodejs";function ve(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function Se(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function xe(){try{if(typeof N<"u")return X().version??"unknown"}catch{}return "unknown"}var b=null;function Q(e){if(!b){let n=ve(),r=Se();b={"telemetry.sdk.name":we,"telemetry.sdk.version":xe(),"telemetry.sdk.language":Te},n&&(b["process.runtime.name"]=n.name,b["process.runtime.version"]=n.version),r&&(b["os.type"]=r);}let t={...b};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var O={},C=null,$=null,Z="https://api.lelemon.dev";function Ie(e={}){O=e,e.debug&&z(true),$=Q(e.service),q("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),C=te(e),C.isEnabled()?q("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function ee(){return O}function R(){return $}function Ee(){return y().isEnabled()}function y(){return C||(C=te(O)),C}async function Me(){C&&await C.flush();}function te(e){let t=e.apiKey??Re("LELEMON_API_KEY");return !t&&!e.disabled&&I("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Re(e){if(typeof process<"u"&&process.env)return process.env[e]}var A=Symbol.for("@lelemondev/sdk:globalContext");function re(){let e=globalThis;return e[A]||(e[A]={context:{}}),e[A]}function oe(e){re().context=e,l("Global context updated",e);}function x(){return re().context}function G(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=T(),s=R(),i={provider:e.provider,model:e.model,input:K(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return D(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function w(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=x(),r=f(),o=R(),s={provider:e.provider,model:e.model,input:K(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:T(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};D(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=x(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=R(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:K(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:T(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Ge=["api_key","apikey","password","secret","authorization"],Pe=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],qe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function De(e){let t=e.toLowerCase();return qe.includes(t)?false:!!(Ge.some(n=>t.includes(n))||Pe.some(n=>t.includes(n)))}function K(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string")return e.length>ne?e.slice(0,ne)+"...[truncated]":e;if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))De(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function $e(){let e=globalThis;return e[L]||(e[L]=new async_hooks.AsyncLocalStorage),e[L]}var se=$e();function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return se.getStore()}function P(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function Oe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ae(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function je(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),s=T(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return se.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{Ke(i,u?void 0:d,u);}})}function Ke(e,t,n){let r=y();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=x(),s=Date.now()-e.startTime,i=n?null:t,d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Le(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Oe(e.toolCallId);j({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Ae(e.toolCallId);}var m="gemini";function ie(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ae(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Ne(s.bind(n)):s}})}function Ne(e){return function(n){let r=e(n);return Ue(r,n.model)}}function Ue(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?ze(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Fe(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ve(s.bind(n),t):s}})}function ze(e,t){return async function(r){let o=Date.now(),s=de(r);try{let i=await e(r),d=Date.now()-o,u=ce(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=le(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Fe(e,t){return async function(r){let o=Date.now(),s=de(r);try{let i=await e(r),d=ue(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ue(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],k=c[c.length-1];k?.text!==void 0?k.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)w({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=G({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Ye(o.candidates);c.length>0&&P(c,a);}}}}function Ve(e,t){return function(r){let o=e(r);return Be(o,t)}}function Be(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?He(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?We(s.bind(n),t):s}})}function He(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=ce(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=le(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function We(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ue(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function de(e){return typeof e=="string"?e:e.contents?e.contents:e}function ce(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function le(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Ye(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function qt(e,t){return t&&oe(t),ee().disabled?(l("Tracing disabled, returning unwrapped client"),e):ie(e)?(F("gemini"),ae(e)):(I("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
-
exports.captureSpan=
|
|
2
|
+
var ge=Object.defineProperty;var me=(e,t,n)=>t in e?ge(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var U=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var he=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var v=(e,t,n)=>me(e,typeof t!="symbol"?t+"":t,n);var Z=he((ct,Te)=>{Te.exports={name:"@lelemondev/sdk",version:"0.9.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 z=false;function F(e){z=e;}function g(){return z?true:ye("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&$("debug",e,t);}function D(e,t){g()&&$("info",e,t);}function x(e,t){$("warn",e,t);}function q(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function E(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function B(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function V(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function H(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function W(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function Y(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function X(e,t){g()&&console.log(`${p} Response: status=${e} duration=${t}ms`);}function $(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${p} ${t}`,n):r(`${p} ${t}`);}function ye(e){if(typeof process<"u"&&process.env)return process.env[e]}var Ce=10,be=1e3,we=1e4,M=class{constructor(t){v(this,"config");v(this,"queue",[]);v(this,"flushPromise",null);v(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??Ce,flushIntervalMs:t.flushIntervalMs??be,requestTimeoutMs:t.requestTimeoutMs??we};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();V(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),H(t.length,Date.now()-n);}catch(r){W(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;Y(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),X(a.status,Date.now()-u),!a.ok){let I=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${I}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var ve="@lelemondev/sdk",Se="nodejs";function ke(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function Ie(){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 Z().version??"unknown"}catch{}return "unknown"}var b=null;function Q(e){if(!b){let n=ke(),r=Ie();b={"telemetry.sdk.name":ve,"telemetry.sdk.version":xe(),"telemetry.sdk.language":Se},n&&(b["process.runtime.name"]=n.name,b["process.runtime.version"]=n.version),r&&(b["os.type"]=r);}let t={...b};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var A={},y=null,O=null,ee="https://api.lelemon.dev";function Me(e={}){A=e,e.debug&&F(true),O=Q(e.service),D("Initializing SDK",{endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??false,telemetry:O}),y=te(e),y.isEnabled()?D("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function R(){return A}function G(){return O}function Re(){return C().isEnabled()}function C(){return y||(y=te(A)),y}async function Ge(){y&&await y.flush();}function te(e){let t=e.apiKey??_e("LELEMON_API_KEY");return !t&&!e.disabled&&x("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new M({apiKey:t??"",endpoint:e.endpoint??ee,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function _e(e){if(typeof process<"u"&&process.env)return process.env[e]}var j=Symbol.for("@lelemondev/sdk:globalContext");function oe(){let e=globalThis;return e[j]||(e[j]={context:{}}),e[j]}function se(e){oe().context=e,l("Global context updated",e);}function k(){return oe().context}function _(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=k(),r=f(),o=T(),s=G(),i={provider:e.provider,model:e.model,input:L(e.input),rawResponse:e.rawResponse?S(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId: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}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));return}}function w(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=k(),r=f(),o=G(),s={provider:e.provider,model:e.model,input:L(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:T(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){E(e.provider,t instanceof Error?t:new Error(String(t)));}}function K(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=k(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=G(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:L(e.input),output:S(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:T(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){E("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Pe=["api_key","apikey","password","secret","authorization"],De=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],qe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],re={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function ie(){return R().redaction??{}}function $e(e){let t=e.toLowerCase();return qe.includes(t)?false:!!(Pe.some(r=>t.includes(r))||De.some(r=>t.includes(r))||(ie().keys??[]).some(r=>t.includes(r.toLowerCase())))}function Oe(e){let t=ie(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(re.emails,"[EMAIL]")),t.phones&&(n=n.replace(re.phones,"[PHONE]")),n}function L(e){return S(e,0)}function S(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=Oe(e);return n.length>ne&&(n=n.slice(0,ne)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>S(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))$e(r)?n[r]="[REDACTED]":n[r]=S(o,t+1);return n}return String(e)}var N=Symbol.for("@lelemondev/sdk:traceStorage");function je(){let e=globalThis;return e[N]||(e[N]=new async_hooks.AsyncLocalStorage),e[N]}var ae=je();function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ae.getStore()}function P(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function Ke(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Le(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Ne(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),s=T(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ae.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{Fe(i,u?void 0:d,u);}})}var Ue=["text","content","message","output","response","result","answer"];function ze(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Ue)if(o in r&&typeof r[o]=="string")return r[o];return e}function Fe(e,t,n){let r=C();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=k(),s=Date.now()-e.startTime,i=n?null:ze(t,e.outputKey,e.outputTransform),d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Be(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=Ke(e.toolCallId);K({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Le(e.toolCallId);}var m="gemini";function ue(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function de(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Ve(s.bind(n)):s}})}function Ve(e){return function(n){let r=e(n);return He(r,n.model)}}function He(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?We(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?Ye(s.bind(n),t):r==="startChat"&&typeof s=="function"?Xe(s.bind(n),t):s}})}function We(e,t){return async function(r){let o=Date.now(),s=le(r);try{let i=await e(r),d=Date.now()-o,u=pe(i.response),a=_({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=fe(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Ye(e,t){return async function(r){let o=Date.now(),s=le(r);try{let i=await e(r),d=ce(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ce(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],I=c[c.length-1];I?.text!==void 0?I.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)w({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=_({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=et(o.candidates);c.length>0&&P(c,a);}}}}function Xe(e,t){return function(r){let o=e(r);return Ze(o,t)}}function Ze(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Je(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?Qe(s.bind(n),t):s}})}function Je(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=pe(i.response),a=_({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=fe(i.response);c.length>0&&P(c,a);}return i}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Qe(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ce(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw w({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function le(e){return typeof e=="string"?e:e.contents?e.contents:e}function pe(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function fe(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function et(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function At(e,t){return t&&se(t),R().disabled?(l("Tracing disabled, returning unwrapped client"),e):ue(e)?(B("gemini"),de(e)):(x("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
+
exports.captureSpan=K;exports.flush=Ge;exports.getTraceContext=f;exports.init=Me;exports.isEnabled=Re;exports.observe=At;exports.span=Be;exports.trace=Ne;//# sourceMappingURL=gemini.js.map
|
|
4
4
|
//# sourceMappingURL=gemini.js.map
|
package/dist/gemini.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var le=Object.defineProperty;var pe=(e,t,n)=>t in e?le(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var L=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var fe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>pe(e,typeof t!="symbol"?t+"":t,n);var Y=fe((nt,ye)=>{ye.exports={name:"@lelemondev/sdk",version:"0.9.6",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var N=false;function U(e){N=e;}function g(){return N?true:ge("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&D("debug",e,t);}function P(e,t){g()&&D("info",e,t);}function k(e,t){D("warn",e,t);}function q(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function I(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function z(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function F(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function B(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function H(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function W(e,t){g()&&console.log(`${p} Response: status=${e} duration=${t}ms`);}function D(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${p} ${t}`,n):r(`${p} ${t}`);}function ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,he=1e3,Ce=1e4,E=class{constructor(t){T(this,"config");T(this,"queue",[]);T(this,"flushPromise",null);T(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??me,flushIntervalMs:t.flushIntervalMs??he,requestTimeoutMs:t.requestTimeoutMs??Ce};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();F(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),V(t.length,Date.now()-n);}catch(r){B(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;H(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),W(a.status,Date.now()-u),!a.ok){let x=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${x}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var be="@lelemondev/sdk",we="nodejs";function Te(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ve(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Se(){try{if(typeof L<"u")return Y().version??"unknown"}catch{}return "unknown"}var y=null;function J(e){if(!y){let n=Te(),r=ve();y={"telemetry.sdk.name":be,"telemetry.sdk.version":Se(),"telemetry.sdk.language":we},n&&(y["process.runtime.name"]=n.name,y["process.runtime.version"]=n.version),r&&(y["os.type"]=r);}let t={...y};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var $={},h=null,_=null,Q="https://api.lelemon.dev";function ke(e={}){$=e,e.debug&&U(true),_=J(e.service),P("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:_}),h=ee(e),h.isEnabled()?P("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Z(){return $}function M(){return _}function Ie(){return C().isEnabled()}function C(){return h||(h=ee($)),h}async function Ee(){h&&await h.flush();}function ee(e){let t=e.apiKey??Me("LELEMON_API_KEY");return !t&&!e.disabled&&k("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new E({apiKey:t??"",endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Me(e){if(typeof process<"u"&&process.env)return process.env[e]}var O=Symbol.for("@lelemondev/sdk:globalContext");function ne(){let e=globalThis;return e[O]||(e[O]={context:{}}),e[O]}function re(e){ne().context=e,l("Global context updated",e);}function S(){return ne().context}function R(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=S(),r=f(),o=w(),s=M(),i={provider:e.provider,model:e.model,input:j(e.input),rawResponse:e.rawResponse?v(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:o,parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return q(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));return}}function b(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=S(),r=f(),o=M(),s={provider:e.provider,model:e.model,input:j(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:w(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){I(e.provider,t instanceof Error?t:new Error(String(t)));}}function A(e){try{let t=C();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=S(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=M(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:j(e.input),output:v(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:n.sessionId,userId:n.userId,traceId:o??r?.traceId,spanId:w(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){I("unknown",t instanceof Error?t:new Error(String(t)));}}var te=1e5,Re=["api_key","apikey","password","secret","authorization"],Ge=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Pe=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function qe(e){let t=e.toLowerCase();return Pe.includes(t)?false:!!(Re.some(n=>t.includes(n))||Ge.some(n=>t.includes(n)))}function j(e){return v(e,0)}function v(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string")return e.length>te?e.slice(0,te)+"...[truncated]":e;if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>v(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))qe(r)?n[r]="[REDACTED]":n[r]=v(o,t+1);return n}return String(e)}var K=Symbol.for("@lelemondev/sdk:traceStorage");function _e(){let e=globalThis;return e[K]||(e[K]=new AsyncLocalStorage),e[K]}var oe=_e();function w(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return oe.getStore()}function G(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function $e(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Oe(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Ae(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??w(),s=w(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,pendingToolCalls:new Map};return oe.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{je(i,u?void 0:d,u);}})}function je(e,t,n){let r=C();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=S(),s=Date.now()-e.startTime,i=n?null:t,d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:o.sessionId,userId:o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Ke(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=$e(e.toolCallId);A({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Oe(e.toolCallId);}var m="gemini";function se(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ie(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Le(s.bind(n)):s}})}function Le(e){return function(n){let r=e(n);return Ne(r,n.model)}}function Ne(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?Ue(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?ze(s.bind(n),t):r==="startChat"&&typeof s=="function"?Fe(s.bind(n),t):s}})}function Ue(e,t){return async function(r){let o=Date.now(),s=ue(r);try{let i=await e(r),d=Date.now()-o,u=de(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ce(i.response);c.length>0&&G(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function ze(e,t){return async function(r){let o=Date.now(),s=ue(r);try{let i=await e(r),d=ae(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*ae(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],x=c[c.length-1];x?.text!==void 0?x.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)b({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=R({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=We(o.candidates);c.length>0&&G(c,a);}}}}function Fe(e,t){return function(r){let o=e(r);return Ve(o,t)}}function Ve(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Be(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?He(s.bind(n),t):s}})}function Be(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=de(i.response),a=R({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=ce(i.response);c.length>0&&G(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function He(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=ae(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function ue(e){return typeof e=="string"?e:e.contents?e.contents:e}function de(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function ce(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function We(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function xt(e,t){return t&&re(t),Z().disabled?(l("Tracing disabled, returning unwrapped client"),e):se(e)?(z("gemini"),ie(e)):(k("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
-
export{
|
|
2
|
+
var fe=Object.defineProperty;var ge=(e,t,n)=>t in e?fe(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var N=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var me=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var T=(e,t,n)=>ge(e,typeof t!="symbol"?t+"":t,n);var X=me((at,we)=>{we.exports={name:"@lelemondev/sdk",version:"0.9.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 g(){return U?true:he("LELEMON_DEBUG")==="true"}var p="[Lelemon]";function l(e,t){g()&&q("debug",e,t);}function P(e,t){g()&&q("info",e,t);}function I(e,t){q("warn",e,t);}function D(e,t,n,r){g()&&console.log(`${p} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function x(e,t){console.error(`${p} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){g()&&console.log(`${p} Wrapped client: provider=${e}`);}function B(e,t){g()&&console.log(`${p} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){g()&&console.log(`${p} Batch sent successfully: count=${e} duration=${t}ms`);}function H(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${p} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){g()&&console.log(`${p} Request: ${e} ${t} (${n} bytes)`);}function Y(e,t){g()&&console.log(`${p} Response: status=${e} duration=${t}ms`);}function q(e,t,n){let r=e==="error"?console.error:e==="warn"?console.warn:console.log;n!==void 0?r(`${p} ${t}`,n):r(`${p} ${t}`);}function he(e){if(typeof process<"u"&&process.env)return process.env[e]}var ye=10,Ce=1e3,be=1e4,E=class{constructor(t){T(this,"config");T(this,"queue",[]);T(this,"flushPromise",null);T(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??ye,flushIntervalMs:t.flushIntervalMs??Ce,requestTimeoutMs:t.requestTimeoutMs??be};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();B(t.length,`${this.config.endpoint}/api/v1/ingest`);try{await this.request("POST","/api/v1/ingest",{events:t}),V(t.length,Date.now()-n);}catch(r){H(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,s=new AbortController,i=r?JSON.stringify(r):void 0;W(t,o,i?.length??0);let d=setTimeout(()=>{s.abort();},this.config.requestTimeoutMs),u=Date.now();try{let a=await fetch(o,{method:t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:i,signal:s.signal});if(clearTimeout(d),Y(a.status,Date.now()-u),!a.ok){let k=await a.text().catch(()=>"Unknown error");throw new Error(`HTTP ${a.status}: ${k}`)}let c=await a.text();return c?JSON.parse(c):{}}catch(a){throw clearTimeout(d),a instanceof Error&&a.name==="AbortError"?new Error(`Request timeout after ${this.config.requestTimeoutMs}ms`):a}}};var Te="@lelemondev/sdk",ve="nodejs";function Se(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function ke(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function Ie(){try{if(typeof N<"u")return X().version??"unknown"}catch{}return "unknown"}var C=null;function J(e){if(!C){let n=Se(),r=ke();C={"telemetry.sdk.name":Te,"telemetry.sdk.version":Ie(),"telemetry.sdk.language":ve},n&&(C["process.runtime.name"]=n.name,C["process.runtime.version"]=n.version),r&&(C["os.type"]=r);}let t={...C};return e?.name&&(t["service.name"]=e.name),e?.version&&(t["service.version"]=e.version),e?.environment&&(t["deployment.environment"]=e.environment),t}var O={},h=null,$=null,Q="https://api.lelemon.dev";function Ee(e={}){O=e,e.debug&&z(true),$=J(e.service),P("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),h=ee(e),h.isEnabled()?P("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function M(){return O}function R(){return $}function Me(){return y().isEnabled()}function y(){return h||(h=ee(O)),h}async function Re(){h&&await h.flush();}function ee(e){let t=e.apiKey??Ge("LELEMON_API_KEY");return !t&&!e.disabled&&I("No API key provided. Set apiKey in init() or LELEMON_API_KEY env var. Tracing disabled."),new E({apiKey:t??"",endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ge(e){if(typeof process<"u"&&process.env)return process.env[e]}var A=Symbol.for("@lelemondev/sdk:globalContext");function re(){let e=globalThis;return e[A]||(e[A]={context:{}}),e[A]}function oe(e){re().context=e,l("Global context updated",e);}function S(){return re().context}function G(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=S(),r=f(),o=w(),s=R(),i={provider:e.provider,model:e.model,input:K(e.input),rawResponse:e.rawResponse?v(e.rawResponse,0):void 0,durationMs:e.durationMs,status:e.status,streaming:e.streaming,firstTokenMs:e.firstTokenMs,sessionId: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}:{},...s?{_telemetry:s}:{}},tags:n.tags,spanType:e.spanType,name:e.name};return D(e.provider,e.model,e.durationMs,e.status),t.enqueue(i),o}catch(t){x(e.provider,t instanceof Error?t:new Error(String(t)));return}}function b(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=S(),r=f(),o=R(),s={provider:e.provider,model:e.model,input:K(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:r?.traceId,spanId:w(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};D(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(s);}catch(t){x(e.provider,t instanceof Error?t:new Error(String(t)));}}function j(e){try{let t=y();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=S(),r=f(),o=e.metadata?._traceId,s=e.metadata?._parentSpanId,i=R(),d={...n.metadata,...e.metadata,...i?{_telemetry:i}:{}};delete d._traceId,delete d._parentSpanId;let u={spanType:e.type,name:e.name,provider:"unknown",model:e.name,input:K(e.input),output:v(e.output,0),durationMs:e.durationMs,status:e.status||"success",errorMessage:e.errorMessage,streaming:!1,sessionId:r?.sessionId??n.sessionId,userId:r?.userId??n.userId,traceId:o??r?.traceId,spanId:w(),parentSpanId:s??r?.currentSpanId,toolCallId:e.toolCallId,metadata:d,tags:n.tags};l(`Span captured: ${e.type}/${e.name}`,{durationMs:e.durationMs}),t.enqueue(u);}catch(t){x("unknown",t instanceof Error?t:new Error(String(t)));}}var te=1e5,_e=["api_key","apikey","password","secret","authorization"],Pe=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],De=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"],ne={emails:/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,phones:/\b\d{9,}\b/g};function se(){return M().redaction??{}}function qe(e){let t=e.toLowerCase();return De.includes(t)?false:!!(_e.some(r=>t.includes(r))||Pe.some(r=>t.includes(r))||(se().keys??[]).some(r=>t.includes(r.toLowerCase())))}function $e(e){let t=se(),n=e;for(let r of t.patterns??[])r.lastIndex=0,n=n.replace(r,"[REDACTED]");return t.emails&&(n=n.replace(ne.emails,"[EMAIL]")),t.phones&&(n=n.replace(ne.phones,"[PHONE]")),n}function K(e){return v(e,0)}function v(e,t){if(t>10)return "[max depth exceeded]";if(e==null)return e;if(typeof e=="string"){let n=$e(e);return n.length>te&&(n=n.slice(0,te)+"...[truncated]"),n}if(typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>v(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))qe(r)?n[r]="[REDACTED]":n[r]=v(o,t+1);return n}return String(e)}var L=Symbol.for("@lelemondev/sdk:traceStorage");function Ae(){let e=globalThis;return e[L]||(e[L]=new AsyncLocalStorage),e[L]}var ie=Ae();function w(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return ie.getStore()}function _(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function je(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function Ke(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Le(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??w(),s=w(),i={traceId:o,rootSpanId:s,currentSpanId:s,parentSpanId:r?.currentSpanId,name:n.name,startTime:Date.now(),input:n.input,metadata:n.metadata,tags:n.tags,outputKey:n.outputKey,outputTransform:n.outputTransform,sessionId:n.sessionId,userId:n.userId,pendingToolCalls:new Map};return ie.run(i,async()=>{let d,u;try{return d=await t(),d}catch(a){throw u=a instanceof Error?a:new Error(String(a)),a}finally{ze(i,u?void 0:d,u);}})}var Ne=["text","content","message","output","response","result","answer"];function Ue(e,t,n){if(n)try{return n(e)}catch{return e}if(t===false)return e;if(typeof t=="string"&&e&&typeof e=="object"){let o=e;return t in o?o[t]:e}if(e==null||typeof e!="object"||Array.isArray(e))return e;let r=e;for(let o of Ne)if(o in r&&typeof r[o]=="string")return r[o];return e}function ze(e,t,n){let r=y();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=S(),s=Date.now()-e.startTime,i=n?null:Ue(t,e.outputKey,e.outputTransform),d={spanType:"agent",name:e.name,provider:"agent",model:e.name,traceId:e.traceId,spanId:e.rootSpanId,parentSpanId:e.parentSpanId,input:e.input,output:i,inputTokens:0,outputTokens:0,durationMs:s,status:n?"error":"success",errorMessage:n?.message,streaming:false,sessionId:e.sessionId??o.sessionId,userId:e.userId??o.userId,metadata:{...o.metadata,...e.metadata},tags:e.tags??o.tags};l(`Sending root span: ${e.name}`,{durationMs:s,hasError:!!n}),r.enqueue(d);}function Fe(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=je(e.toolCallId);j({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Ke(e.toolCallId);}var m="gemini";function ae(e){if(!e||typeof e!="object")return false;let t=e.constructor?.name;if(t==="GoogleGenerativeAI"||t==="GoogleGenAI")return true;let n=e;return !!(typeof n.getGenerativeModel=="function"||n.models&&typeof n.models.generate=="function")}function ue(e){let t=e;return new Proxy(t,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="getGenerativeModel"&&typeof s=="function"?Be(s.bind(n)):s}})}function Be(e){return function(n){let r=e(n);return Ve(r,n.model)}}function Ve(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="generateContent"&&typeof s=="function"?He(s.bind(n),t):r==="generateContentStream"&&typeof s=="function"?We(s.bind(n),t):r==="startChat"&&typeof s=="function"?Ye(s.bind(n),t):s}})}function He(e,t){return async function(r){let o=Date.now(),s=ce(r);try{let i=await e(r),d=Date.now()-o,u=le(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=pe(i.response);c.length>0&&_(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function We(e,t){return async function(r){let o=Date.now(),s=ce(r);try{let i=await e(r),d=de(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}async function*de(e,t,n,r){let o={candidates:[{content:{parts:[]}}]},s=null,i,d=false;try{for await(let u of e){try{let a=u.text();if(a){d||(d=!0,i=Date.now()-r);let c=o.candidates[0].content?.parts||[],k=c[c.length-1];k?.text!==void 0?k.text+=a:c.push({text:a});}}catch{}if(u.candidates?.[0]?.content?.parts)for(let a of u.candidates[0].content.parts)a.functionCall&&o.candidates[0].content?.parts?.push(a);u.usageMetadata&&(o.usageMetadata=u.usageMetadata),u.candidates?.[0]?.finishReason&&(o.candidates[0].finishReason=u.candidates[0].finishReason),yield u;}}catch(u){throw s=u instanceof Error?u:new Error(String(u)),u}finally{let u=Date.now()-r;if(s)b({provider:m,model:t,input:n,error:s,durationMs:u,streaming:true});else {let a=G({provider:m,model:t,input:n,rawResponse:o,durationMs:u,status:"success",streaming:true,firstTokenMs:i});if(a){let c=Qe(o.candidates);c.length>0&&_(c,a);}}}}function Ye(e,t){return function(r){let o=e(r);return Xe(o,t)}}function Xe(e,t){return new Proxy(e,{get(n,r,o){let s=Reflect.get(n,r,o);return r==="sendMessage"&&typeof s=="function"?Ze(s.bind(n),t):r==="sendMessageStream"&&typeof s=="function"?Je(s.bind(n),t):s}})}function Ze(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=Date.now()-o,u=le(i.response),a=G({provider:m,model:t,input:s,rawResponse:u,durationMs:d,status:"success",streaming:!1});if(a){let c=pe(i.response);c.length>0&&_(c,a);}return i}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:false}),i}}}function Je(e,t){return async function(r){let o=Date.now(),s=r;try{let i=await e(r),d=de(i.stream,t,s,o);return {...i,stream:d}}catch(i){throw b({provider:m,model:t,input:s,error:i instanceof Error?i:new Error(String(i)),durationMs:Date.now()-o,streaming:true}),i}}}function ce(e){return typeof e=="string"?e:e.contents?e.contents:e}function le(e){return {candidates:e.candidates,usageMetadata:e.usageMetadata}}function pe(e){let t=[],n=e.candidates?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Qe(e){let t=[],n=e?.[0]?.content?.parts;return n&&n.forEach((r,o)=>{r.functionCall?.name&&t.push(`gemini-fc-${r.functionCall.name}-${o}`);}),t}function Rt(e,t){return t&&oe(t),M().disabled?(l("Tracing disabled, returning unwrapped client"),e):ae(e)?(F("gemini"),ue(e)):(I("Client is not a Gemini model. Use @lelemondev/sdk/gemini only with Google Generative AI SDK."),e)}
|
|
3
|
+
export{j as captureSpan,Re as flush,f as getTraceContext,Ee as init,Me as isEnabled,Rt as observe,Fe as span,Le as trace};//# sourceMappingURL=gemini.mjs.map
|
|
4
4
|
//# sourceMappingURL=gemini.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as ObserveOptions } from './capture-
|
|
2
|
-
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-
|
|
1
|
+
import { O as ObserveOptions } from './capture-CiUL-4hv.mjs';
|
|
2
|
+
export { C as CaptureSpanOptions, L as LelemonConfig, P as ProviderName, b as SDKTelemetry, S as ServiceConfig, h as SpanOptions, d as SpanType, T as TraceContext, e as TraceOptions, c as captureSpan, f as flush, g as getTraceContext, i as init, a as isEnabled, s as span, t as trace } from './capture-CiUL-4hv.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Observe Function
|