@lelemondev/sdk 0.9.3 → 0.9.5
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 +148 -15
- package/dist/anthropic.d.mts +2 -2
- package/dist/anthropic.d.ts +2 -2
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.mjs +1 -1
- package/dist/bedrock.d.mts +2 -2
- package/dist/bedrock.d.ts +2 -2
- package/dist/bedrock.js +1 -1
- package/dist/bedrock.mjs +1 -1
- package/dist/capture-ChybLulj.d.mts +264 -0
- package/dist/capture-ChybLulj.d.ts +264 -0
- package/dist/gemini.d.mts +2 -2
- package/dist/gemini.d.ts +2 -2
- package/dist/gemini.js +1 -1
- package/dist/gemini.mjs +1 -1
- package/dist/index.d.mts +21 -245
- package/dist/index.d.ts +21 -245
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/integrations.js +1 -1
- package/dist/next.js +1 -1
- package/dist/openai.d.mts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +1 -1
- package/dist/openai.mjs +1 -1
- package/dist/openrouter.d.mts +2 -2
- package/dist/openrouter.d.ts +2 -2
- package/dist/openrouter.js +1 -1
- package/dist/openrouter.mjs +1 -1
- package/package.json +1 -1
package/dist/bedrock.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict';var async_hooks=require('async_hooks');/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var ce=Object.defineProperty;var le=(e,t,n)=>t in e?ce(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var K=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var pe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var S=(e,t,n)=>le(e,typeof t!="symbol"?t+"":t,n);var Y=pe((nt,ke)=>{ke.exports={name:"@lelemondev/sdk",version:"0.9.3",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var L=false;function z(e){L=e;}function k(){return L?true:me("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&$("debug",e,t);}function q(e,t){k()&&$("info",e,t);}function R(e,t){$("warn",e,t);}function P(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function D(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function V(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function G(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function J(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function H(e,t){k()&&console.log(`${m} 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(`${m} ${t}`,n):r(`${m} ${t}`);}function me(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,ge=1e3,ye=1e4,B=class{constructor(t){S(this,"config");S(this,"queue",[]);S(this,"flushPromise",null);S(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??fe,flushIntervalMs:t.flushIntervalMs??ge,requestTimeoutMs:t.requestTimeoutMs??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}),G(t.length,Date.now()-n);}catch(r){J(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;W(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),H(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 be="@lelemondev/sdk",we="nodejs";function he(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function 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 Te(){try{if(typeof K<"u")return Y().version??"unknown"}catch{}return "unknown"}var T=null;function Q(e){if(!T){let n=he(),r=ve();T={"telemetry.sdk.name":be,"telemetry.sdk.version":Te(),"telemetry.sdk.language":we},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 U={},w=null,A=null,Z="https://www.lelemon.dev";function Se(e={}){U=e,e.debug&&z(true),A=Q(e.service),q("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:A}),w=te(e),w.isEnabled()?q("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function ee(){return U}function _(){return A}function xe(){return h().isEnabled()}function h(){return w||(w=te(U)),w}async function Ce(){w&&await w.flush();}function te(e){let t=e.apiKey??Ee("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 B({apiKey:t??"",endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ee(e){if(typeof process<"u"&&process.env)return process.env[e]}var re={};function oe(e){re=e,l("Global context updated",e);}function C(){return re}function E(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=C(),r=f(),o=I(),i=_(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?x(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 P(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){D(e.provider,t instanceof Error?t:new Error(String(t)));return}}function v(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=C(),r=f(),o=_(),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:I(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};P(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){D(e.provider,t instanceof Error?t:new Error(String(t)));}}function O(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=C(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,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:x(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:I(),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){D("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Me=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],De=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Be(e){let t=e.toLowerCase();return De.includes(t)?false:!!(Me.some(n=>t.includes(n))||Re.some(n=>t.includes(n)))}function N(e){return x(e,0)}function x(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=>x(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Be(r)?n[r]="[REDACTED]":n[r]=x(o,t+1);return n}return String(e)}var se=new async_hooks.AsyncLocalStorage;function I(){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 j(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function qe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function 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??I(),i=I(),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 se.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{Ae(a,p?void 0:u,p);}})}function Ae(e,t,n){let r=h();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=C(),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 Ue(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=qe(e.toolCallId);O({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Pe(e.toolCallId);}var g="bedrock";function ie(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 ae(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"?Oe(i.bind(n)):i}})}function Oe(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Ne(e,n);case "ConverseStreamCommand":return je(e,n);case "InvokeModelCommand":return Le(e,n);case "InvokeModelWithResponseStreamCommand":return ze(e,n);default:return e(n)}}}async function Ne(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=E({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:ue(o),durationMs:i,status:"success",streaming:!1});if(a){let u=de(o);u.length>0&&j(u,a);}return o}catch(o){throw v({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:Ke(o.stream,r,n)}:o}catch(o){throw v({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*Ke(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)v({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=E({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:ue(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=de(r);y.length>0&&j(y,d);}}}}async function Le(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Ve(o.body);return E({provider:g,model:r.modelId||"unknown",input:M(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw v({provider:g,model:r.modelId||"unknown",input:M(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function ze(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:Fe(o.body,r,n)}:o}catch(o){throw v({provider:g,model:r.modelId||"unknown",input:M(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Fe(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Ge(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?v({provider:g,model:t.modelId||"unknown",input:M(t.body),error:o,durationMs:i,streaming:true}):E({provider:g,model:t.modelId||"unknown",input:M(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function ue(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function de(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 M(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Ve(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Ge(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Rt(e,t){return t&&oe(t),ee().disabled?(l("Tracing disabled, returning unwrapped client"),e):ie(e)?(F("bedrock"),ae(e)):(R("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
2
|
+
var ce=Object.defineProperty;var le=(e,t,n)=>t in e?ce(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var K=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var pe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var S=(e,t,n)=>le(e,typeof t!="symbol"?t+"":t,n);var Y=pe((nt,ke)=>{ke.exports={name:"@lelemondev/sdk",version:"0.9.5",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var L=false;function z(e){L=e;}function k(){return L?true:me("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&$("debug",e,t);}function q(e,t){k()&&$("info",e,t);}function R(e,t){$("warn",e,t);}function P(e,t,n,r){k()&&console.log(`${m} Captured trace: provider=${e} model=${t} duration=${n}ms status=${r}`);}function D(e,t){console.error(`${m} Failed to capture trace: provider=${e} error=${t.message}`);}function F(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function V(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function G(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function J(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function W(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function H(e,t){k()&&console.log(`${m} 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(`${m} ${t}`,n):r(`${m} ${t}`);}function me(e){if(typeof process<"u"&&process.env)return process.env[e]}var fe=10,ge=1e3,ye=1e4,B=class{constructor(t){S(this,"config");S(this,"queue",[]);S(this,"flushPromise",null);S(this,"flushTimer",null);this.config={apiKey:t.apiKey,endpoint:t.endpoint,debug:t.debug,disabled:t.disabled,batchSize:t.batchSize??fe,flushIntervalMs:t.flushIntervalMs??ge,requestTimeoutMs:t.requestTimeoutMs??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}),G(t.length,Date.now()-n);}catch(r){J(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;W(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),H(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 be="@lelemondev/sdk",we="nodejs";function he(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function 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 Te(){try{if(typeof K<"u")return Y().version??"unknown"}catch{}return "unknown"}var T=null;function Q(e){if(!T){let n=he(),r=ve();T={"telemetry.sdk.name":be,"telemetry.sdk.version":Te(),"telemetry.sdk.language":we},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 U={},w=null,A=null,Z="https://api.lelemon.dev";function Se(e={}){U=e,e.debug&&z(true),A=Q(e.service),q("Initializing SDK",{endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??false,telemetry:A}),w=te(e),w.isEnabled()?q("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function ee(){return U}function _(){return A}function xe(){return h().isEnabled()}function h(){return w||(w=te(U)),w}async function Ce(){w&&await w.flush();}function te(e){let t=e.apiKey??Ee("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 B({apiKey:t??"",endpoint:e.endpoint??Z,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ee(e){if(typeof process<"u"&&process.env)return process.env[e]}var re={};function oe(e){re=e,l("Global context updated",e);}function C(){return re}function E(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=C(),r=f(),o=I(),i=_(),a={provider:e.provider,model:e.model,input:N(e.input),rawResponse:e.rawResponse?x(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 P(e.provider,e.model,e.durationMs,e.status),t.enqueue(a),o}catch(t){D(e.provider,t instanceof Error?t:new Error(String(t)));return}}function v(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping error capture");return}let n=C(),r=f(),o=_(),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:I(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};P(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(i);}catch(t){D(e.provider,t instanceof Error?t:new Error(String(t)));}}function O(e){try{let t=h();if(!t.isEnabled()){l("Transport disabled, skipping span capture");return}let n=C(),r=f(),o=e.metadata?._traceId,i=e.metadata?._parentSpanId,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:x(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:I(),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){D("unknown",t instanceof Error?t:new Error(String(t)));}}var ne=1e5,Me=["api_key","apikey","password","secret","authorization"],Re=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],De=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function Be(e){let t=e.toLowerCase();return De.includes(t)?false:!!(Me.some(n=>t.includes(n))||Re.some(n=>t.includes(n)))}function N(e){return x(e,0)}function x(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=>x(n,t+1));if(typeof e=="object"){let n={};for(let[r,o]of Object.entries(e))Be(r)?n[r]="[REDACTED]":n[r]=x(o,t+1);return n}return String(e)}var se=new async_hooks.AsyncLocalStorage;function I(){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 j(e,t){let n=f();if(n)for(let r of e)n.pendingToolCalls.set(r,t),l(`Registered tool call ${r} \u2192 LLM span ${t}`);}function qe(e){let t=f();if(t)return e&&t.pendingToolCalls.has(e)?t.pendingToolCalls.get(e):t.currentSpanId}function 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??I(),i=I(),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 se.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{Ae(a,p?void 0:u,p);}})}function Ae(e,t,n){let r=h();if(!r.isEnabled()){l("Transport disabled, skipping root span");return}let o=C(),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 Ue(e){let t=f();if(!t){process.env.NODE_ENV!=="production"&&console.warn("[Lelemon] span() called outside of trace() - span will not be captured");return}let n=qe(e.toolCallId);O({type:e.type,name:e.name,input:e.input,output:e.output,durationMs:e.durationMs??0,status:e.status??"success",errorMessage:e.errorMessage,toolCallId:e.toolCallId,metadata:{...e.metadata,_traceId:t.traceId,_parentSpanId:n}}),e.toolCallId&&Pe(e.toolCallId);}var g="bedrock";function ie(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 ae(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"?Oe(i.bind(n)):i}})}function Oe(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Ne(e,n);case "ConverseStreamCommand":return je(e,n);case "InvokeModelCommand":return Le(e,n);case "InvokeModelWithResponseStreamCommand":return ze(e,n);default:return e(n)}}}async function Ne(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=E({provider:g,model:r.modelId||"unknown",input:{system:r.system,messages:r.messages},rawResponse:ue(o),durationMs:i,status:"success",streaming:!1});if(a){let u=de(o);u.length>0&&j(u,a);}return o}catch(o){throw v({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:Ke(o.stream,r,n)}:o}catch(o){throw v({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*Ke(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)v({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},error:o,durationMs:s,streaming:true});else {let d=E({provider:g,model:t.modelId||"unknown",input:{system:t.system,messages:t.messages},rawResponse:ue(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=de(r);y.length>0&&j(y,d);}}}}async function Le(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Ve(o.body);return E({provider:g,model:r.modelId||"unknown",input:M(r.body),rawResponse:a,durationMs:i,status:"success",streaming:!1}),o}catch(o){throw v({provider:g,model:r.modelId||"unknown",input:M(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:false}),o}}async function ze(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:Fe(o.body,r,n)}:o}catch(o){throw v({provider:g,model:r.modelId||"unknown",input:M(r.body),error:o instanceof Error?o:new Error(String(o)),durationMs:Date.now()-n,streaming:true}),o}}async function*Fe(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Ge(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?v({provider:g,model:t.modelId||"unknown",input:M(t.body),error:o,durationMs:i,streaming:true}):E({provider:g,model:t.modelId||"unknown",input:M(t.body),rawResponse:{streamEvents:r},durationMs:i,status:"success",streaming:true});}}function ue(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function de(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 M(e){try{let t=typeof e=="string"?e:new TextDecoder().decode(e);return JSON.parse(t)}catch{return e}}function Ve(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Ge(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Rt(e,t){return t&&oe(t),ee().disabled?(l("Tracing disabled, returning unwrapped client"),e):ie(e)?(F("bedrock"),ae(e)):(R("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
3
3
|
exports.captureSpan=O;exports.flush=Ce;exports.getTraceContext=f;exports.init=Se;exports.isEnabled=xe;exports.observe=Rt;exports.span=Ue;exports.trace=$e;//# sourceMappingURL=bedrock.js.map
|
|
4
4
|
//# sourceMappingURL=bedrock.js.map
|
package/dist/bedrock.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import {AsyncLocalStorage}from'async_hooks';/* @lelemondev/sdk - LLM Observability */
|
|
2
|
-
var de=Object.defineProperty;var ce=(e,t,n)=>t in e?de(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var j=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var le=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var I=(e,t,n)=>ce(e,typeof t!="symbol"?t+"":t,n);var H=le((Ze,ye)=>{ye.exports={name:"@lelemondev/sdk",version:"0.9.3",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var K=false;function L(e){K=e;}function k(){return K?true:pe("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&P("debug",e,t);}function _(e,t){k()&&P("info",e,t);}function M(e,t){P("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 z(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function F(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function G(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function J(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function W(e,t){k()&&console.log(`${m} Response: status=${e} duration=${t}ms`);}function P(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 pe(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,fe=1e3,ge=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??me,flushIntervalMs:t.flushIntervalMs??fe,requestTimeoutMs:t.requestTimeoutMs??ge};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();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){G(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;J(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),W(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 ke="@lelemondev/sdk",be="nodejs";function we(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function he(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function ve(){try{if(typeof j<"u")return H().version??"unknown"}catch{}return "unknown"}var v=null;function X(e){if(!v){let n=we(),r=he();v={"telemetry.sdk.name":ke,"telemetry.sdk.version":ve(),"telemetry.sdk.language":be},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};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={},b=null,$=null,Q="https://www.lelemon.dev";function Ie(e={}){A=e,e.debug&&L(true),$=X(e.service),_("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),b=ee(e),b.isEnabled()?_("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Z(){return A}function B(){return $}function Se(){return w().isEnabled()}function w(){return b||(b=ee(A)),b}async function xe(){b&&await b.flush();}function ee(e){let t=e.apiKey??Ce("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??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ce(e){if(typeof process<"u"&&process.env)return process.env[e]}var ne={};function re(e){ne=e,l("Global context updated",e);}function x(){return ne}function C(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=T(),i=B(),a={provider:e.provider,model:e.model,input:O(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:O(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:T(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(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:O(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: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 te=1e5,Ee=["api_key","apikey","password","secret","authorization"],Me=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Re=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function De(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Ee.some(n=>t.includes(n))||Me.some(n=>t.includes(n)))}function O(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>te?e.slice(0,te)+"...[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 oe=new AsyncLocalStorage;function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return oe.getStore()}function N(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 qe(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Pe(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),i=T(),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 oe.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{$e(a,p?void 0:u,p);}})}function $e(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 Ae(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);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&&qe(e.toolCallId);}var g="bedrock";function se(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 ie(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"?Ue(i.bind(n)):i}})}function Ue(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Oe(e,n);case "ConverseStreamCommand":return Ne(e,n);case "InvokeModelCommand":return Ke(e,n);case "InvokeModelWithResponseStreamCommand":return Le(e,n);default:return e(n)}}}async function Oe(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:ae(o),durationMs:i,status:"success",streaming:!1});if(a){let u=ue(o);u.length>0&&N(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 Ne(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:je(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*je(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:ae(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=ue(r);y.length>0&&N(y,d);}}}}async function Ke(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Fe(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 Le(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:ze(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*ze(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Ve(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 ae(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function ue(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 Fe(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Ve(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function vt(e,t){return t&&re(t),Z().disabled?(l("Tracing disabled, returning unwrapped client"),e):se(e)?(z("bedrock"),ie(e)):(M("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
2
|
+
var de=Object.defineProperty;var ce=(e,t,n)=>t in e?de(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n;var j=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var le=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var I=(e,t,n)=>ce(e,typeof t!="symbol"?t+"":t,n);var H=le((Ze,ye)=>{ye.exports={name:"@lelemondev/sdk",version:"0.9.5",description:"Automatic LLM observability. Wrap your client, everything is traced.",author:"Lelemon <info@lelemon.dev>",license:"MIT",repository:{type:"git",url:"git+https://github.com/lelemondev/lelemondev-sdk.git"},homepage:"https://lelemon.dev",bugs:{url:"https://github.com/lelemondev/lelemondev-sdk/issues"},keywords:["llm","observability","tracing","openai","anthropic","nextjs","lambda","express","hono","claude","gpt","ai","monitoring","serverless"],main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./openai":{types:"./dist/openai.d.ts",import:"./dist/openai.mjs",require:"./dist/openai.js"},"./anthropic":{types:"./dist/anthropic.d.ts",import:"./dist/anthropic.mjs",require:"./dist/anthropic.js"},"./bedrock":{types:"./dist/bedrock.d.ts",import:"./dist/bedrock.mjs",require:"./dist/bedrock.js"},"./gemini":{types:"./dist/gemini.d.ts",import:"./dist/gemini.mjs",require:"./dist/gemini.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.mjs",require:"./dist/openrouter.js"},"./next":{types:"./dist/next.d.ts",import:"./dist/next.mjs",require:"./dist/next.js"},"./lambda":{types:"./dist/lambda.d.ts",import:"./dist/lambda.mjs",require:"./dist/lambda.js"},"./express":{types:"./dist/express.d.ts",import:"./dist/express.mjs",require:"./dist/express.js"},"./hono":{types:"./dist/hono.d.ts",import:"./dist/hono.mjs",require:"./dist/hono.js"},"./integrations":{types:"./dist/integrations.d.ts",import:"./dist/integrations.mjs",require:"./dist/integrations.js"},"./package.json":"./package.json"},typesVersions:{"*":{openai:["./dist/openai.d.ts"],anthropic:["./dist/anthropic.d.ts"],bedrock:["./dist/bedrock.d.ts"],gemini:["./dist/gemini.d.ts"],openrouter:["./dist/openrouter.d.ts"],next:["./dist/next.d.ts"],lambda:["./dist/lambda.d.ts"],express:["./dist/express.d.ts"],hono:["./dist/hono.d.ts"],integrations:["./dist/integrations.d.ts"],"*":["./dist/index.d.ts"]}},files:["dist/**/*.js","dist/**/*.mjs","dist/**/*.d.ts","dist/**/*.d.mts","README.md"],sideEffects:false,engines:{node:">=18.0.0"},scripts:{build:"tsup",dev:"tsup --watch",docs:"typedoc && node scripts/generate-llms-txt.mjs",prepublishOnly:"npm run build",lint:"eslint src/",test:"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:e2e":"vitest run tests/e2e",typecheck:"tsc --noEmit"},devDependencies:{"@aws-sdk/client-bedrock-runtime":"^3.962.0","@google/generative-ai":"^0.24.1","@types/node":"^20.0.0","@vitest/coverage-v8":"^2.0.0",dotenv:"^17.2.3",openai:"^6.15.0",tsup:"^8.5.1",typedoc:"^0.28.15",typescript:"^5.9.3",vitest:"^2.0.0"}};});var K=false;function L(e){K=e;}function k(){return K?true:pe("LELEMON_DEBUG")==="true"}var m="[Lelemon]";function l(e,t){k()&&P("debug",e,t);}function _(e,t){k()&&P("info",e,t);}function M(e,t){P("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 z(e){k()&&console.log(`${m} Wrapped client: provider=${e}`);}function F(e,t){k()&&console.log(`${m} Sending batch: count=${e} endpoint=${t}`);}function V(e,t){k()&&console.log(`${m} Batch sent successfully: count=${e} duration=${t}ms`);}function G(e,t){let n=t instanceof Error?t.message:String(t);console.error(`${m} Batch send failed: count=${e} error=${n}`);}function J(e,t,n){k()&&console.log(`${m} Request: ${e} ${t} (${n} bytes)`);}function W(e,t){k()&&console.log(`${m} Response: status=${e} duration=${t}ms`);}function P(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 pe(e){if(typeof process<"u"&&process.env)return process.env[e]}var me=10,fe=1e3,ge=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??me,flushIntervalMs:t.flushIntervalMs??fe,requestTimeoutMs:t.requestTimeoutMs??ge};}isEnabled(){return !this.config.disabled&&!!this.config.apiKey}enqueue(t){this.config.disabled||(this.queue.push(t),this.queue.length>=this.config.batchSize?this.flush():this.scheduleFlush());}async flush(){if(this.flushPromise)return this.flushPromise;if(this.queue.length===0)return;this.cancelScheduledFlush();let t=this.queue;return this.queue=[],this.flushPromise=this.sendBatch(t).finally(()=>{this.flushPromise=null;}),this.flushPromise}getPendingCount(){return this.queue.length}scheduleFlush(){this.flushTimer===null&&(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}cancelScheduledFlush(){this.flushTimer!==null&&(clearTimeout(this.flushTimer),this.flushTimer=null);}async sendBatch(t){if(t.length===0)return;let n=Date.now();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){G(t.length,r);}}async request(t,n,r){let o=`${this.config.endpoint}${n}`,i=new AbortController,a=r?JSON.stringify(r):void 0;J(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),W(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 ke="@lelemondev/sdk",be="nodejs";function we(){return typeof process<"u"&&process.versions?.node?{name:"nodejs",version:process.versions.node}:typeof Deno<"u"?{name:"deno",version:Deno.version?.deno??"unknown"}:typeof Bun<"u"?{name:"bun",version:Bun.version??"unknown"}:typeof window<"u"&&typeof navigator<"u"?{name:"browser",version:navigator.userAgent}:null}function he(){if(typeof process<"u"&&process.platform){let e=process.platform;switch(e){case "darwin":return "darwin";case "win32":return "windows";case "linux":return "linux";default:return e}}if(typeof navigator<"u"){let e=navigator.userAgent.toLowerCase();if(e.includes("mac"))return "darwin";if(e.includes("win"))return "windows";if(e.includes("linux"))return "linux"}return null}function ve(){try{if(typeof j<"u")return H().version??"unknown"}catch{}return "unknown"}var v=null;function X(e){if(!v){let n=we(),r=he();v={"telemetry.sdk.name":ke,"telemetry.sdk.version":ve(),"telemetry.sdk.language":be},n&&(v["process.runtime.name"]=n.name,v["process.runtime.version"]=n.version),r&&(v["os.type"]=r);}let t={...v};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={},b=null,$=null,Q="https://api.lelemon.dev";function Ie(e={}){A=e,e.debug&&L(true),$=X(e.service),_("Initializing SDK",{endpoint:e.endpoint??Q,debug:e.debug??false,disabled:e.disabled??false,telemetry:$}),b=ee(e),b.isEnabled()?_("SDK initialized - tracing enabled"):l("SDK initialized - tracing disabled (no API key or explicitly disabled)");}function Z(){return A}function B(){return $}function Se(){return w().isEnabled()}function w(){return b||(b=ee(A)),b}async function xe(){b&&await b.flush();}function ee(e){let t=e.apiKey??Ce("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??Q,debug:e.debug??false,disabled:e.disabled??!t,batchSize:e.batchSize,flushIntervalMs:e.flushIntervalMs,requestTimeoutMs:e.requestTimeoutMs})}function Ce(e){if(typeof process<"u"&&process.env)return process.env[e]}var ne={};function re(e){ne=e,l("Global context updated",e);}function x(){return ne}function C(e){try{let t=w();if(!t.isEnabled()){l("Transport disabled, skipping trace capture");return}let n=x(),r=f(),o=T(),i=B(),a={provider:e.provider,model:e.model,input:O(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:O(e.input),durationMs:e.durationMs,status:"error",errorMessage:e.error.message,streaming:e.streaming,sessionId:n.sessionId,userId:n.userId,traceId:r?.traceId,spanId:T(),parentSpanId:r?.currentSpanId,metadata:{...n.metadata,...e.metadata,...r?{_traceName:r.name}:{},...o?{_telemetry:o}:{}},tags:n.tags};q(e.provider,e.model,e.durationMs,"error"),l("Error details",{message:e.error.message,stack:e.error.stack}),t.enqueue(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:O(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: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 te=1e5,Ee=["api_key","apikey","password","secret","authorization"],Me=["access_token","auth_token","bearer_token","refresh_token","id_token","session_token"],Re=["inputtokens","outputtokens","totaltokens","prompttokens","completiontokens","cachereadtokens","cachewritetokens","cachereadinputtokens","cachewriteinputtokens","reasoningtokens"];function De(e){let t=e.toLowerCase();return Re.includes(t)?false:!!(Ee.some(n=>t.includes(n))||Me.some(n=>t.includes(n)))}function O(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>te?e.slice(0,te)+"...[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 oe=new AsyncLocalStorage;function T(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function f(){return oe.getStore()}function N(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 qe(e){let t=f();t&&t.pendingToolCalls.delete(e);}async function Pe(e,t){let n=typeof e=="string"?{name:e}:e,r=f(),o=r?.traceId??T(),i=T(),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 oe.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{$e(a,p?void 0:u,p);}})}function $e(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 Ae(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);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&&qe(e.toolCallId);}var g="bedrock";function se(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 ie(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"?Ue(i.bind(n)):i}})}function Ue(e){return async function(n){switch(n.constructor?.name||""){case "ConverseCommand":return Oe(e,n);case "ConverseStreamCommand":return Ne(e,n);case "InvokeModelCommand":return Ke(e,n);case "InvokeModelWithResponseStreamCommand":return Le(e,n);default:return e(n)}}}async function Oe(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:ae(o),durationMs:i,status:"success",streaming:!1});if(a){let u=ue(o);u.length>0&&N(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 Ne(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.stream?{...o,stream:je(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*je(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:ae(r),durationMs:s,status:"success",streaming:true,firstTokenMs:i});if(d){let y=ue(r);y.length>0&&N(y,d);}}}}async function Ke(e,t){let n=Date.now(),r=t.input;try{let o=await e(t),i=Date.now()-n,a=Fe(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 Le(e,t){let n=Date.now(),r=t.input;try{let o=await e(t);return o.body?{...o,body:ze(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*ze(e,t,n){let r=[],o=null;try{for await(let i of e){if(i.chunk?.bytes){let a=Ve(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 ae(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function ue(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 Fe(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function Ve(e){try{let t=new TextDecoder().decode(e);return JSON.parse(t)}catch{return null}}function vt(e,t){return t&&re(t),Z().disabled?(l("Tracing disabled, returning unwrapped client"),e):se(e)?(z("bedrock"),ie(e)):(M("Client is not a Bedrock client. Use @lelemondev/sdk/bedrock only with AWS Bedrock SDK."),e)}
|
|
3
3
|
export{U as captureSpan,xe as flush,f as getTraceContext,Ie as init,Se as isEnabled,vt as observe,Ae as span,Pe as trace};//# sourceMappingURL=bedrock.mjs.map
|
|
4
4
|
//# sourceMappingURL=bedrock.mjs.map
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for Lelemon SDK
|
|
3
|
+
*/
|
|
4
|
+
interface ServiceConfig {
|
|
5
|
+
/** Service name (e.g., "my-ai-chatbot") */
|
|
6
|
+
name?: string;
|
|
7
|
+
/** Service version (e.g., "1.2.3") */
|
|
8
|
+
version?: string;
|
|
9
|
+
/** Deployment environment (e.g., "production", "staging", "development") */
|
|
10
|
+
environment?: string;
|
|
11
|
+
}
|
|
12
|
+
interface LelemonConfig {
|
|
13
|
+
/** API key (or set LELEMON_API_KEY env var) */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** API endpoint (default: https://api.lelemon.dev) */
|
|
16
|
+
endpoint?: string;
|
|
17
|
+
/** Enable debug logging */
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
/** Disable tracing */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** Batch size before flush (default: 10) */
|
|
22
|
+
batchSize?: number;
|
|
23
|
+
/** Auto-flush interval in ms (default: 1000) */
|
|
24
|
+
flushIntervalMs?: number;
|
|
25
|
+
/** Request timeout in ms (default: 10000) */
|
|
26
|
+
requestTimeoutMs?: number;
|
|
27
|
+
/** Service metadata for telemetry */
|
|
28
|
+
service?: ServiceConfig;
|
|
29
|
+
}
|
|
30
|
+
interface SDKTelemetry {
|
|
31
|
+
/** SDK name */
|
|
32
|
+
'telemetry.sdk.name': string;
|
|
33
|
+
/** SDK version */
|
|
34
|
+
'telemetry.sdk.version': string;
|
|
35
|
+
/** SDK language */
|
|
36
|
+
'telemetry.sdk.language': string;
|
|
37
|
+
/** Runtime name (nodejs, deno, bun, browser) */
|
|
38
|
+
'process.runtime.name'?: string;
|
|
39
|
+
/** Runtime version */
|
|
40
|
+
'process.runtime.version'?: string;
|
|
41
|
+
/** OS type (linux, darwin, windows) */
|
|
42
|
+
'os.type'?: string;
|
|
43
|
+
/** Service name */
|
|
44
|
+
'service.name'?: string;
|
|
45
|
+
/** Service version */
|
|
46
|
+
'service.version'?: string;
|
|
47
|
+
/** Deployment environment */
|
|
48
|
+
'deployment.environment'?: string;
|
|
49
|
+
}
|
|
50
|
+
type ProviderName = 'openai' | 'anthropic' | 'gemini' | 'bedrock' | 'openrouter' | 'agent' | 'unknown';
|
|
51
|
+
interface ObserveOptions {
|
|
52
|
+
/** Session ID to group related calls */
|
|
53
|
+
sessionId?: string;
|
|
54
|
+
/** User ID for the end user */
|
|
55
|
+
userId?: string;
|
|
56
|
+
/** Custom metadata added to all traces */
|
|
57
|
+
metadata?: Record<string, unknown>;
|
|
58
|
+
/** Tags for filtering */
|
|
59
|
+
tags?: string[];
|
|
60
|
+
}
|
|
61
|
+
type SpanType = 'llm' | 'agent' | 'tool' | 'retrieval' | 'embedding' | 'guardrail' | 'rerank' | 'custom';
|
|
62
|
+
interface CaptureSpanOptions {
|
|
63
|
+
/** Span type */
|
|
64
|
+
type: SpanType;
|
|
65
|
+
/** Span name (tool name, retrieval source, custom name) */
|
|
66
|
+
name: string;
|
|
67
|
+
/** Input data */
|
|
68
|
+
input: unknown;
|
|
69
|
+
/** Output data */
|
|
70
|
+
output: unknown;
|
|
71
|
+
/** Duration in milliseconds */
|
|
72
|
+
durationMs: number;
|
|
73
|
+
/** Status */
|
|
74
|
+
status?: 'success' | 'error';
|
|
75
|
+
/** Error message if status is 'error' */
|
|
76
|
+
errorMessage?: string;
|
|
77
|
+
/** Tool call ID (for linking tool results) */
|
|
78
|
+
toolCallId?: string;
|
|
79
|
+
/** Custom metadata */
|
|
80
|
+
metadata?: Record<string, unknown>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Global Configuration
|
|
85
|
+
*
|
|
86
|
+
* Manages SDK configuration and transport instance.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Initialize the SDK
|
|
91
|
+
* Call once at app startup
|
|
92
|
+
*/
|
|
93
|
+
declare function init(config?: LelemonConfig): void;
|
|
94
|
+
/**
|
|
95
|
+
* Check if SDK is enabled
|
|
96
|
+
*/
|
|
97
|
+
declare function isEnabled(): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Flush all pending traces
|
|
100
|
+
*/
|
|
101
|
+
declare function flush(): Promise<void>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Trace Context Module
|
|
105
|
+
*
|
|
106
|
+
* Provides AsyncLocalStorage-based context for grouping spans under a parent trace.
|
|
107
|
+
* Supports hierarchical tracing where:
|
|
108
|
+
* - trace() creates a root "agent" span
|
|
109
|
+
* - LLM calls become children of the root
|
|
110
|
+
* - Tool calls become children of the LLM that triggered them (via toolCallId linking)
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* import { trace, span } from '@lelemondev/sdk';
|
|
115
|
+
*
|
|
116
|
+
* await trace({ name: 'sales-agent', input: userMessage }, async () => {
|
|
117
|
+
* const response = await client.send(new ConverseCommand({...}));
|
|
118
|
+
* // Tools automatically linked to their parent LLM via toolCallId
|
|
119
|
+
* return response;
|
|
120
|
+
* });
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
interface TraceContext {
|
|
124
|
+
/** Unique trace ID (shared by all spans in this trace) */
|
|
125
|
+
traceId: string;
|
|
126
|
+
/** Root span ID (the agent/workflow span) */
|
|
127
|
+
rootSpanId: string;
|
|
128
|
+
/** Current span ID (for nesting - LLM calls become children of this) */
|
|
129
|
+
currentSpanId: string;
|
|
130
|
+
/** Parent span ID (for nested trace() calls) */
|
|
131
|
+
parentSpanId?: string;
|
|
132
|
+
/** Trace name */
|
|
133
|
+
name: string;
|
|
134
|
+
/** Start time in ms */
|
|
135
|
+
startTime: number;
|
|
136
|
+
/** Input data */
|
|
137
|
+
input?: unknown;
|
|
138
|
+
/** Trace metadata */
|
|
139
|
+
metadata?: Record<string, unknown>;
|
|
140
|
+
/** Trace tags */
|
|
141
|
+
tags?: string[];
|
|
142
|
+
/** Map of toolCallId → llmSpanId for linking tool spans to their parent LLM */
|
|
143
|
+
pendingToolCalls: Map<string, string>;
|
|
144
|
+
}
|
|
145
|
+
interface TraceOptions {
|
|
146
|
+
/** Name for the trace (e.g., 'sales-agent', 'rag-query') */
|
|
147
|
+
name: string;
|
|
148
|
+
/** Input data for the trace */
|
|
149
|
+
input?: unknown;
|
|
150
|
+
/** Custom metadata */
|
|
151
|
+
metadata?: Record<string, unknown>;
|
|
152
|
+
/** Tags for filtering */
|
|
153
|
+
tags?: string[];
|
|
154
|
+
}
|
|
155
|
+
interface SpanOptions {
|
|
156
|
+
/** Span type */
|
|
157
|
+
type: 'retrieval' | 'embedding' | 'tool' | 'guardrail' | 'rerank' | 'custom';
|
|
158
|
+
/** Span name (e.g., 'pinecone-search', 'cohere-rerank') */
|
|
159
|
+
name: string;
|
|
160
|
+
/** Input data */
|
|
161
|
+
input?: unknown;
|
|
162
|
+
/** Output data */
|
|
163
|
+
output?: unknown;
|
|
164
|
+
/** Duration in milliseconds (optional, will be set automatically if not provided) */
|
|
165
|
+
durationMs?: number;
|
|
166
|
+
/** Status */
|
|
167
|
+
status?: 'success' | 'error';
|
|
168
|
+
/** Error message if status is 'error' */
|
|
169
|
+
errorMessage?: string;
|
|
170
|
+
/** Tool call ID (links this tool span to the LLM that requested it) */
|
|
171
|
+
toolCallId?: string;
|
|
172
|
+
/** Custom metadata */
|
|
173
|
+
metadata?: Record<string, unknown>;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the current trace context, if any
|
|
177
|
+
*/
|
|
178
|
+
declare function getTraceContext(): TraceContext | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Execute a function within a trace context.
|
|
181
|
+
* 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
|
+
*
|
|
184
|
+
* @example Simple usage (just name)
|
|
185
|
+
* ```typescript
|
|
186
|
+
* await trace('sales-agent', async () => {
|
|
187
|
+
* await client.send(new ConverseCommand({...}));
|
|
188
|
+
* return finalResponse;
|
|
189
|
+
* });
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @example With options
|
|
193
|
+
* ```typescript
|
|
194
|
+
* await trace({ name: 'rag-query', input: question, tags: ['production'] }, async () => {
|
|
195
|
+
* const docs = await search(question);
|
|
196
|
+
* span({ type: 'retrieval', name: 'pinecone', output: { count: docs.length } });
|
|
197
|
+
* return client.send(new ConverseCommand({...}));
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
declare function trace<T>(nameOrOptions: string | TraceOptions, fn: () => Promise<T>): Promise<T>;
|
|
202
|
+
/**
|
|
203
|
+
* Manually capture a span for non-LLM operations (retrieval, embedding, tool, etc.)
|
|
204
|
+
* Must be called within a trace() block.
|
|
205
|
+
*
|
|
206
|
+
* @example Tool with toolCallId (links to parent LLM)
|
|
207
|
+
* ```typescript
|
|
208
|
+
* span({
|
|
209
|
+
* type: 'tool',
|
|
210
|
+
* name: 'query_database',
|
|
211
|
+
* toolCallId: 'tooluse_abc123', // Links to LLM that requested this
|
|
212
|
+
* input: { sql: 'SELECT ...' },
|
|
213
|
+
* output: { rows: [...] },
|
|
214
|
+
* durationMs: 15,
|
|
215
|
+
* });
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @example Retrieval without toolCallId
|
|
219
|
+
* ```typescript
|
|
220
|
+
* span({
|
|
221
|
+
* type: 'retrieval',
|
|
222
|
+
* name: 'pinecone-search',
|
|
223
|
+
* input: { topK: 5 },
|
|
224
|
+
* output: { count: 10 },
|
|
225
|
+
* durationMs: 50,
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
declare function span(options: SpanOptions): void;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Capture Module
|
|
233
|
+
*
|
|
234
|
+
* Handles trace capture and batching.
|
|
235
|
+
* Called by providers to record LLM calls.
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Manually capture a span (tool call, retrieval, custom)
|
|
240
|
+
* Use this when auto-detection doesn't cover your use case
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* // Capture a tool call
|
|
244
|
+
* captureSpan({
|
|
245
|
+
* type: 'tool',
|
|
246
|
+
* name: 'get_weather',
|
|
247
|
+
* input: { location: 'San Francisco' },
|
|
248
|
+
* output: { temperature: 72, conditions: 'sunny' },
|
|
249
|
+
* durationMs: 150,
|
|
250
|
+
* });
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* // Capture a retrieval/RAG operation
|
|
254
|
+
* captureSpan({
|
|
255
|
+
* type: 'retrieval',
|
|
256
|
+
* name: 'vector_search',
|
|
257
|
+
* input: { query: 'user question', k: 5 },
|
|
258
|
+
* output: { documents: [...] },
|
|
259
|
+
* durationMs: 50,
|
|
260
|
+
* });
|
|
261
|
+
*/
|
|
262
|
+
declare function captureSpan(options: CaptureSpanOptions): void;
|
|
263
|
+
|
|
264
|
+
export { type CaptureSpanOptions as C, type LelemonConfig as L, type ObserveOptions as O, type ProviderName as P, type ServiceConfig as S, type TraceContext as T, isEnabled as a, type SDKTelemetry as b, captureSpan as c, type SpanType as d, type TraceOptions as e, flush as f, getTraceContext as g, type SpanOptions as h, init as i, span as s, trace as t };
|