@lunora/agent 1.0.0-alpha.90 → 1.0.0-alpha.91
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/dist/index.mjs +1 -1
- package/dist/packem_shared/{VoiceSessionDO-DJ0ka5vr.mjs → VoiceSessionDO-BdvnaLoO.mjs} +1 -1
- package/dist/packem_shared/agent-loop-B3KTMfqm.mjs +3 -0
- package/dist/packem_shared/braintrustTelemetry-Byne8uPK.mjs +1 -0
- package/dist/packem_shared/{compileAgentWorkflow-8pHFPjec.mjs → compileAgentWorkflow-DRkaF9sV.mjs} +1 -1
- package/dist/packem_shared/{createAgentContext-Ds2VaveB.mjs → createAgentContext-DPFZ88dr.mjs} +1 -1
- package/dist/packem_shared/createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs +1 -0
- package/dist/packem_shared/{defineAgent-DM0fNEY6.mjs → defineAgent-Q3MlQjYs.mjs} +1 -1
- package/dist/packem_shared/in-flight-calls-GH1A_1P3.mjs +1 -0
- package/dist/packem_shared/otlpTelemetry-ByqrB-72.mjs +1 -0
- package/dist/packem_shared/{runAgentLoop-Dmq-FWJk.mjs → runAgentLoop-DJvzWDgh.mjs} +1 -1
- package/dist/packem_shared/{runVoiceTurn-DGD90HuL.mjs → runVoiceTurn-D1WCjVPw.mjs} +1 -1
- package/dist/packem_shared/sentryTelemetry-BHeydiAB.mjs +1 -0
- package/dist/packem_shared/{voice-turn-B9dc3mvG.mjs → voice-turn-D1ZzTzcE.mjs} +1 -1
- package/dist/telemetry/index.d.mts +98 -33
- package/dist/telemetry/index.d.ts +98 -33
- package/dist/telemetry/index.mjs +1 -1
- package/package.json +7 -7
- package/dist/packem_shared/agent-loop-Cotwgugs.mjs +0 -3
- package/dist/packem_shared/braintrustTelemetry-CoYK-pq7.mjs +0 -1
- package/dist/packem_shared/createDispatchRunner-BrbbxS2q-DBBqImoR.mjs +0 -1
- package/dist/packem_shared/otlpTelemetry-CywiFp-X.mjs +0 -1
- package/dist/packem_shared/sentryTelemetry-CPqEbFPA.mjs +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,s as r}from"./packem_shared/agent-loop-
|
|
1
|
+
import{r as t,s as r}from"./packem_shared/agent-loop-B3KTMfqm.mjs";import{collectAgenticMemoryTools as a,toSearchResults as i}from"./packem_shared/collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as l}from"./packem_shared/agentAsTool-CgZb6ycK.mjs";import{codeTool as m}from"./packem_shared/codeTool-BQb-K3my.mjs";import{agentComponent as c,agentExtension as x}from"./component.mjs";import{default as A}from"./packem_shared/createAgentContext-DPFZ88dr.mjs";import{defineAgent as d,defineAgentTool as u,isAgentDefinition as N}from"./packem_shared/defineAgent-Q3MlQjYs.mjs";import{functionTool as D}from"./packem_shared/functionTool-D3CP4f8-.mjs";import{createAgentGenerate as M,createEpisodeExtract as O,createGraphExtract as _,createStreamGenerate as C,resolveAgentModel as G}from"./packem_shared/createAgentGenerate-BOILDUZj.mjs";import{adaptMcpResult as F,mcpTools as L}from"./packem_shared/adaptMcpResult-CVlq-_TO.mjs";import{buildModelMessages as k}from"./packem_shared/buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as R,agentClassName as V,agentDefaultName as b,voiceBindingName as h,voiceClassName as w}from"./naming.mjs";import{AGENT_MODULE as I,DEFAULT_AGENT_FUNCTION_PATHS as P,SANDBOX_INVOKE_PATH as X,SANDBOX_MODULE as y,toFunctionReference as K}from"./packem_shared/AGENT_MODULE-M4D1EejI.mjs";import{browserTool as j,containerTool as q,fsTool as z}from"./sandbox.mjs";import{defineSkill as Q,isSkillDefinition as Y}from"./packem_shared/defineSkill-DGGvDWNq.mjs";import{default as $}from"./packem_shared/VoiceSessionDO-BdvnaLoO.mjs";import{r as oe}from"./packem_shared/voice-turn-D1ZzTzcE.mjs";import{default as re}from"./packem_shared/compileAgentWorkflow-DRkaF9sV.mjs";export{I as AGENT_MODULE,P as DEFAULT_AGENT_FUNCTION_PATHS,X as SANDBOX_INVOKE_PATH,y as SANDBOX_MODULE,$ as VoiceSessionDO,F as adaptMcpResult,l as agentAsTool,R as agentBindingName,V as agentClassName,c as agentComponent,b as agentDefaultName,x as agentExtension,j as browserTool,k as buildModelMessages,m as codeTool,a as collectAgenticMemoryTools,re as compileAgentWorkflow,q as containerTool,A as createAgentContext,M as createAgentGenerate,O as createEpisodeExtract,_ as createGraphExtract,C as createStreamGenerate,d as defineAgent,u as defineAgentTool,Q as defineSkill,z as fsTool,D as functionTool,N as isAgentDefinition,Y as isSkillDefinition,L as mcpTools,G as resolveAgentModel,t as runAgentLoop,oe as runVoiceTurn,r as splitForCompaction,K as toFunctionReference,i as toSearchResults,h as voiceBindingName,w as voiceClassName};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createAi as A}from"@lunora/ai";import{
|
|
1
|
+
import{createAi as A}from"@lunora/ai";import{e as b}from"./createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs";import{t as x}from"./base64-5eyBfWO3.mjs";import{p as T,d as _,a as v,i as p,b as y,c as E,e as k,f as M,r as w,t as I}from"./voice-turn-D1ZzTzcE.mjs";import{createStreamGenerate as C,createCompact as R}from"./createAgentGenerate-BOILDUZj.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as L,toFunctionReference as m}from"./AGENT_MODULE-M4D1EejI.mjs";const N="@cf/openai/whisper-large-v3-turbo",O="@cf/deepgram/aura-1",U=8*1024*1024,B=100,f=4e3,g=f*4+1024,F=4002,D=4003,z=4004,W=256*1024,S=15,G=5e3,X=h=>{if(h===null||typeof h!="object")return!1;const{text:t,type:e}=h;return e==="commit"||e==="interrupt"||e==="text"&&typeof t=="string"};class Y{agent;ai;env;exportName;paths;streamGenerate;sttModel;ttsModel;maxSessionTurns;audioBuffers=new Map;bufferedBytes=new Map;controllers=new Map;state;constructor(t,e,r,s){this.state=t,this.env=e,this.agent=r,this.exportName=s,this.paths=L,this.ai=A({binding:e.AI,env:e}),this.streamGenerate=C(r,e),this.sttModel=r.voice?.stt??N,this.ttsModel=r.voice?.tts??O,this.maxSessionTurns=r.voice?.maxTurns??B}fetch(t){if(t.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{status:426});const r=new URL(t.url).searchParams.get("threadKey");if(!r)return new Response("Missing threadKey",{status:400});const s=globalThis.WebSocketPair,i=new s,n=i[0],o=i[1];this.state.acceptWebSocket(o);const c=crypto.randomUUID(),d=T(t.headers.get("x-lunora-identity")),a=_(t.headers.get("x-lunora-userid")),u=v(t.headers.get("x-lunora-identity-exp"));if(p(u))return y(o),new Response(null,{status:101,webSocket:n});o.serializeAttachment?.({connectionId:c,threadKey:r,turn:0,...u===void 0?{}:{expiresAt:u},...d===void 0?{}:{identity:d},...a===void 0?{}:{userId:a}}),this.send(o,{audioFormat:this.agent.voice?.audioFormat??"mp3",type:"ready"});const l=this.agent.voice?.greeting;return l&&l.length>0&&this.state.waitUntil?.(this.speakGreeting(o,c,r,a,d,l)),new Response(null,{status:101,webSocket:n})}async webSocketMessage(t,e){const r=t.deserializeAttachment?.();if(r){if(p(r.expiresAt)){y(t);return}try{if(typeof e=="string"){await this.handleControl(t,r,e);return}this.bufferAudio(r.connectionId,new Uint8Array(e),t)}catch(s){this.send(t,{message:s instanceof Error?s.message:String(s),type:"error"})}}}webSocketClose(t){this.cleanupSocket(t)}webSocketError(t){this.cleanupSocket(t)}resolveRun(t,e){const r=t===void 0&&e===void 0?void 0:{...e===void 0?{}:{claims:e},...t===void 0?{}:{userId:t}};return b({env:this.env,label:"@lunora/agent voice",...r===void 0?{}:{identity:r}})}async transcribe(t){const e=E(t);return k(await this.ai.run(this.sttModel,{audio:x(e)}))}async synthesize(t,e){const r=this.agent.voice?.speaker;return M(await this.ai.run(this.ttsModel,{text:t,...r===void 0?{}:{speaker:r}},e===void 0?void 0:{signal:e}))}async handleControl(t,e,r){if(r.length>g){this.send(t,{message:`control frame exceeds the maximum of ${String(g)} characters`,type:"error"}),this.closeSocket(t,z,"control_frame_limit");return}let s;try{s=JSON.parse(r)}catch{return}if(!X(s)){this.send(t,{message:'unsupported control frame — expected { type: "text", text }, { type: "commit" } or { type: "interrupt" }',type:"error"});return}const i=s;if(i.type==="interrupt"){this.controllers.get(e.connectionId)?.abort();return}if(i.type==="text"&&i.text.length>f){this.send(t,{message:`text frame exceeds the maximum of ${String(f)} characters`,type:"error"});return}if(e.turn>=this.maxSessionTurns){this.send(t,{message:`voice session reached its ${String(this.maxSessionTurns)}-turn limit — reconnect to continue`,type:"error"}),this.closeSocket(t,F,"turn_limit");return}if(this.controllers.has(e.connectionId)){i.type==="commit"&&this.drainAudio(e.connectionId),this.send(t,{message:"a turn is already in progress — send an interrupt before the next utterance",type:"error"});return}if(i.type==="commit"){const n=this.drainAudio(e.connectionId);await this.runTurn(t,e,{pcm:n});return}await this.runTurn(t,e,{text:i.text})}bufferAudio(t,e,r){const s=(this.bufferedBytes.get(t)??0)+e.byteLength;if(s>U){this.audioBuffers.delete(t),this.bufferedBytes.delete(t),this.send(r,{message:"utterance exceeded the maximum buffer — send a commit sooner",type:"error"}),this.closeSocket(r,D,"utterance_too_large");return}const i=this.audioBuffers.get(t)??[];i.push(e),this.audioBuffers.set(t,i),this.bufferedBytes.set(t,s)}drainAudio(t){const e=this.audioBuffers.get(t)??[];this.audioBuffers.delete(t),this.bufferedBytes.delete(t);const r=e.reduce((n,o)=>n+o.byteLength,0),s=new Uint8Array(r);let i=0;for(const n of e)s.set(n,i),i+=n.byteLength;return s}async runTurn(t,e,r){const s=new AbortController;this.controllers.set(e.connectionId,s);try{await w({agent:this.agent,compact:R(),connectionId:e.connectionId,env:this.env,exportName:this.exportName,paths:this.paths,run:this.resolveRun(e.userId,e.identity),send:i=>{this.send(t,i)},sendAudio:i=>{this.sendAudio(t,i)},signal:s.signal,streamGenerate:this.streamGenerate,synthesize:async(i,n)=>this.synthesizeWithSignal(i,n),threadKey:e.threadKey,transcribe:async i=>this.transcribe(i),turn:e.turn,waitForDrain:async()=>this.waitForSocketDrain(t),...e.userId===void 0?{}:{owner:e.userId},...r.pcm===void 0?{}:{pcm:r.pcm},...r.text===void 0?{}:{text:r.text}})}finally{this.controllers.get(e.connectionId)===s&&this.controllers.delete(e.connectionId),t.serializeAttachment?.({...e,turn:e.turn+1})}}async speakGreeting(t,e,r,s,i,n){const o=this.resolveRun(s,i),c=new AbortController,d=()=>c.signal.aborted;this.controllers.set(e,c);try{if((await o(m(this.paths.ensureThread),{agent:this.exportName,key:r,...this.agent.initialState===void 0?{}:{initialState:this.agent.initialState},...s===void 0?{}:{owner:s}}))?.outcome!=="created")return;for await(const u of I(await this.synthesizeWithSignal(n,c.signal))){if(d()||(await this.waitForSocketDrain(t),d()))break;this.sendAudio(t,u)}d()||(await o(m(this.paths.appendMessage),{content:n,messageKey:"voice:greeting:assistant",role:"assistant",threadKey:r}),this.send(t,{text:n,type:"assistant_done"}))}catch(a){this.send(t,{message:a instanceof Error?a.message:String(a),type:"error"})}finally{this.controllers.get(e)===c&&this.controllers.delete(e)}}async synthesizeWithSignal(t,e){return e.aborted?new Uint8Array(0):this.synthesize(t,e)}cleanupSocket(t){const e=t.deserializeAttachment?.();e&&(this.controllers.get(e.connectionId)?.abort(),this.controllers.delete(e.connectionId),this.audioBuffers.delete(e.connectionId),this.bufferedBytes.delete(e.connectionId))}closeSocket(t,e,r){try{t.close?.(e,r)}catch{}}send(t,e){try{t.send(JSON.stringify(e))}catch{}}sendAudio(t,e){try{t.send(e)}catch{}}async waitForSocketDrain(t){const e=t;let r=0;for(;typeof e.bufferedAmount=="number"&&e.bufferedAmount>W&&r<G;)await new Promise(s=>{setTimeout(s,S)}),r+=S}}export{Y as default};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{r as Z}from"./createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs";import{c as j,d as tt}from"./component-shared-G8ngerkU.mjs";import{resolveAgentModel as et}from"./createAgentGenerate-BOILDUZj.mjs";import{buildModelMessages as G}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as L}from"../naming.mjs";import{toFunctionReference as h}from"./AGENT_MODULE-M4D1EejI.mjs";import{i as ot}from"./positive-integer-ztHqqpBk.mjs";import{combineTelemetry as nt}from"./combineTelemetry-DgE9W9G8.mjs";import{c as q}from"./tool-output-Cmk3JWMG.mjs";const at=e=>e.kind==="graph"||e.kind==="episodic"||e.mode!=="agentic",P=e=>e.memorySources?e.memorySources:e.memory&&at(e.memory)?[{key:"default",...e.memory}]:[],st=e=>P(e).find(t=>t.kind==="graph"),rt=e=>P(e).find(t=>t.kind==="episodic"),S=(e,t)=>t==="default"?e:`${e}:${t}`,it=e=>{if(e===void 0||e.isEnabled===!1)return;const{integrations:t}=e;if(t===void 0)return;const n=Array.isArray(t)?t:[t];return n.length===0?void 0:nt(...n)},ct=async(e,t,n)=>{const o=it(e);if(o===void 0)return n();const a={dynamic:!0,input:t.input,toolCallId:t.id,toolName:t.name,type:"tool-call"},s={callId:t.id,messages:[],toolCall:a,toolContext:void 0},u=Date.now();await o.onToolExecutionStart?.(s);let d;const c=()=>(d??=n(),d);try{if(o.executeTool===void 0)await c();else try{await o.executeTool({...s,execute:c,toolCallId:t.id})}catch{}const i=await c();return await o.onToolExecutionEnd?.({...s,toolExecutionMs:Date.now()-u,toolOutput:{dynamic:!0,input:t.input,output:i,toolCallId:t.id,toolName:t.name,type:"tool-result"}}),i}catch(i){throw await o.onToolExecutionEnd?.({...s,toolExecutionMs:Date.now()-u,toolOutput:{dynamic:!0,error:i,input:t.input,toolCallId:t.id,toolName:t.name,type:"tool-error"}}),i}},ut=8,dt=e=>ot(e)?e:0,W=e=>e===void 0?"null":JSON.stringify(e),lt=async(e,t,n)=>{try{await e({error:t instanceof Error?t.message:String(t),status:"error",...n===void 0?{}:{usage:n}})}catch(o){t instanceof Error&&t.cause===void 0&&(t.cause=o)}},pt=e=>e===void 0?[]:[e].flat(),mt=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),yt=(e,t)=>{if(t===void 0)return e;if(e===void 0)return{...t};const n={};for(const o of["inputTokens","outputTokens","totalTokens"])(e[o]!==void 0||t[o]!==void 0)&&(n[o]=(e[o]??0)+(t[o]??0));return n},ft=async(e,t,n,o,a)=>{const{needsApproval:s}=e;return s===void 0||s===!1?!1:s===!0?!0:n.do(o,async()=>s(t,a))},vt="WorkflowTimeoutError",ht=e=>e instanceof Error&&e.name===vt,b=4320*60*1e3,gt={day:864e5,hour:36e5,minute:6e4,month:30*864e5,second:1e3,week:7*864e5,year:365*864e5},wt=/^(\d+(?:\.\d+)?) (day|hour|minute|month|second|week|year)s?$/u,Tt=e=>{if(e===void 0)return b;if(typeof e=="number")return Math.min(e,j);const t=wt.exec(e);return t===null?b:Math.min(Number(t[1])*gt[t[2]],j)},xt=async(e,t)=>{const{agent:n,deleteMessage:o,instanceId:a,patchThread:s,persist:u,step:d}=e;await u({content:`Awaiting approval to run tool "${t.name}".`,messageKey:`${a}:approval:${t.id}`,role:"tool",status:"awaiting_approval",toolCallId:t.id,toolName:t.name}),await s({status:"awaiting_input"});const c=await d.waitForEvent(`approval:${t.id}`,{timeout:Tt(n.approvalTimeout),type:`agent-approval:${t.id}`}).then(i=>({decision:i.payload.decision,...i.payload.note===void 0?{}:{note:i.payload.note}})).catch(i=>{if(!ht(i))throw i;return{decision:"reject",note:"approval timed out"}});return await o(`${a}:approval:${t.id}`),await s({status:"running"}),c},A="lunoraToolOutcome",Ct=e=>typeof e=="object"&&e!==null&&A in e?e[A]:{ok:e},St=async(e,t)=>{const{agent:n,depth:o,env:a,getState:s,instanceId:u,onTokenDelta:d,owner:c,persist:i,run:r,setState:l,step:p,threadKey:m,tools:w}=e,v=`tool:${t.name}:${t.id}`,T=w[t.name],y=`${u}:tool:${t.id}`;if(!T){await i({content:`Error: unknown tool "${t.name}"`,messageKey:y,role:"tool",stepName:v,toolCallId:t.id,toolName:t.name});return}if(t.invalid!==void 0){await i({content:`Error: invalid input for tool "${t.name}" — it was not run. ${t.invalid}`,messageKey:y,role:"tool",stepName:v,toolCallId:t.id,toolName:t.name});return}const M={depth:o,env:a,getState:s,idempotencyKey:v,owner:c,reportProgress:g=>{d?.({data:g,kind:"progress",threadKey:m,toolCallId:t.id})},run:r,setState:l,step:p,threadKey:m,toolCallId:t.id},O={depth:o,env:a,getState:s,idempotencyKey:v,run:r,threadKey:m,toolCallId:t.id},_=`tool:approval-gate:${t.id}`;let x;if(await ft(T,t.input,p,_,O)){const{decision:g,note:E}=await xt(e,t);if(g==="reject"){const U=E===void 0?"":` Reason: ${E}`;await i({content:`Tool "${t.name}" was rejected by the user and not run.${U}`,messageKey:y,role:"tool",status:"rejected",stepName:v,toolCallId:t.id,toolName:t.name});return}x="approved"}const $=Ct(await p.do(v,async()=>{try{const g=()=>Promise.resolve(T.execute(t.input,M)),E=await ct(n.telemetry,{id:t.id,input:t.input,name:t.name},g);return{[A]:{ok:E}}}catch(g){if(Z(g))return{[A]:{failed:g.message}};throw g}}));if("failed"in $){await i({content:q(`Error: tool "${t.name}" failed and will not be retried. ${$.failed}`),messageKey:y,role:"tool",stepName:v,...x===void 0?{}:{status:x},toolCallId:t.id,toolName:t.name});return}const R=$.ok;await i({content:q(typeof R=="string"?R:W(R)),messageKey:y,role:"tool",stepName:v,...x===void 0?{}:{status:x},toolCallId:t.id,toolName:t.name})},Et=(e,t,n)=>{if(!t)return e;let{messages:o}=e;return t.messages!==void 0&&(o=t.messages),t.system!==void 0&&(o=[{content:t.system,role:"system"},...o]),{activeTools:t.activeTools??e.activeTools,messages:o,model:t.model===void 0?e.model:et(t.model,n),toolChoice:t.toolChoice??e.toolChoice}},kt=(e,t)=>{if(t===void 0||e.length<=t.maxMessages)return;const n=Math.max(1,t.keepRecent??Math.ceil(t.maxMessages/2));if(e.length<=n)return;let o=e.length-n;for(;o>0&&e[o]?.role==="tool";)o-=1;if(!(o<=0))return{older:e.slice(0,o),recent:e.slice(o)}},Mt=async(e,t)=>{const{agent:n,compact:o,env:a}=e,s=kt(t,n.compaction);if(s===void 0||o===void 0)return{history:t,summary:void 0};try{const u=await o({env:a,messages:G({history:s.older}),model:n.compaction?.model??n.model});return u.length>0?{history:s.recent,summary:u}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},$t=async(e,t,n)=>{const{agent:o,env:a,generate:s,instructions:u,listMessages:d,memoryContext:c,onTokenDelta:i,run:r,step:l,streamGenerate:p,threadKey:m}=e;return l.do(`llm:turn:${String(t)}`,async()=>{const w=await r(d,{key:m}),{history:v,summary:T}=await Mt(e,w);let y={activeTools:o.activeTools,messages:G({history:v,instructions:u,memoryContext:c,summary:T}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(y=Et(y,await o.prepareStep({messages:y.messages,stepNumber:t,steps:n}),a));const k={messages:y.messages,...y.activeTools===void 0?{}:{activeTools:y.activeTools},...y.model===void 0?{}:{model:y.model},...y.toolChoice===void 0?{}:{toolChoice:y.toolChoice}};return p&&i?p(k,M=>{i({text:M,threadKey:m,turn:t})}):s(k)})},B=async(e,t)=>{const{agent:n,step:o}=e;n.onStepFinish&&await o.do(`agent:step-finish:${String(t.turn)}`,async()=>(await n.onStepFinish?.(t),!0))},Rt=e=>({text:e.text,toolCalls:e.toolCalls.map(t=>({input:t.input,toolCallId:t.id,toolName:t.name})),...e.usage===void 0?{}:{usage:e.usage}}),F=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},It=e=>tt({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),Kt=async(e,t,n,o)=>{if(e.source===void 0)return;const a=h(e.source),{topK:s}=e,u=S("memory:retrieve",e.key),d=await n.do(u,async()=>o(a,{query:t,...s===void 0?{}:{topK:s}}));return F(d)},Nt=async(e,t,n,o,a,s)=>{if(n===void 0)return;const u=S("memory:traverse",e.key),d=await a.do(u,async()=>s(o,{owner:n,query:t,...It(e.graph)}));return F(d)},At=async(e,t,n,o,a)=>{if(t===void 0)return;const s=S("memory:recall",e.key),u={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},d=await o.do(s,async()=>a(n,u));return F(d)},Ot=async(e,t)=>e.kind==="episodic"?At(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?Nt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):Kt(e,t.input,t.step,t.run),_t=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},Ut=async(e,t,n,o,a,s)=>{const u=_t(P(e));if(u.length===0)return;const d=h(o.graphTraverse),c=h(o.episodeRecall),i=[];for(const r of u){const l=await Ot(r,{episodeRecall:c,graphTraverse:d,input:t,owner:n,run:s,step:a});l!==void 0&&i.push(l)}return i.length>0?i.join(`
|
|
2
|
+
|
|
3
|
+
`):void 0},Dt=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:s,instanceId:u,owner:d,paths:c,run:i,step:r}=e;if(o===void 0||d===void 0||a===void 0||a.length===0)return;const l=st(t);if(l!==void 0)try{const p={assistantText:a,env:n,model:l.graph?.extractionModel??t.model,userInput:s},m=await r.do(S("memory:extract",l.key),async()=>o(p));await i(h(c.graphUpsert),{...m,messageKey:`${u}:${S("extract",l.key)}`,owner:d})}catch{}},Pt=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:s,instanceId:u,owner:d,paths:c,run:i,step:r,threadKey:l}=e;if(o===void 0||d===void 0||a===void 0||a.length===0)return;const p=rt(t);if(p!==void 0)try{const m={assistantText:a,env:n,model:p.episodic?.extractionModel??t.model,userInput:s},{summary:w}=await r.do(S("memory:episode",p.key),async()=>o(m));await i(h(c.episodeUpsert),{messageKey:`${u}:${S("episode",p.key)}`,owner:d,summary:w,threadKey:l})}catch{}},Ft=async(e,t,n)=>{const o=e[L(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},jt="12 hours",qt=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:jt,type:`agent-dequeue:${t}:${n}`})},bt=async(e,t,n)=>{const o=e.env[L(e.exportName)];if(!o||typeof o.get!="function")return;const a=o.get.bind(o);try{await e.step.do(`dequeue-wake:${n}`,async()=>(await(await a(n)).sendEvent({payload:{threadKey:t},type:`agent-dequeue:${t}:${n}`}),n))}catch{}},Bt=async(e,t,n)=>{const{onReply:o}=e,{replyRef:a}=t.params;if(!(o===void 0||a===void 0))try{await t.step.do("agent:reply",async()=>(await o({env:t.env,replyRef:a,result:n,threadKey:t.params.threadKey}),a.channel))}catch{}},Gt=async(e,t,n,o,a)=>{const{instanceId:s,persist:u}=e,d=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const c=n.output!==void 0&&n.text.length===0?W(n.output):n.text;return await u({content:c,messageKey:`${s}:assistant:${String(t)}`,role:"assistant"}),await B(e,{text:n.text,toolCalls:[],turn:t,...d}),{final:{stopped:"final",text:n.text,turns:t+1,...n.output===void 0?{}:{output:n.output}}}}await u({content:n.text,messageKey:`${s}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const c of n.toolCalls)await St(e,c);if(await B(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...d}),o.push(Rt(n)),a.length>0&&await mt(a,o))return"stopCondition"},Lt=async(e,t,n,o)=>{const a=[];let s,u=!1,d=0;for(let c=0;c<t;c+=1){const i=await $t(e,c,a);o.value=yt(o.value,i.usage),d=c+1;const r=await Gt(e,c,i,a,n);if(r==="stopCondition"){u=!0;break}if(r!==void 0){s=r.final;break}}return{final:s,stoppedByCondition:u,turnsRun:d}},te=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:s,extractGraph:u,generate:d,instanceId:c,onTokenDelta:i,params:r,paths:l,run:p,step:m,streamGenerate:w}=e,v=t.maxTurns??ut,T=pt(t.stopWhen),y=h(l.appendMessage),k=h(l.completeRun),M=h(l.ensureThread),O=h(l.listMessages),_=h(l.deleteMessage),x=h(l.patchThread),$=h(l.setState),R=h(l.state),g=async f=>{await p(y,{threadKey:r.threadKey,...f})},E=async f=>{await p(x,{key:r.threadKey,...f})},U=async f=>{await p(_,{messageKey:f,threadKey:r.threadKey})},z=async()=>{await g({content:r.input,messageKey:`${c}:user`,role:"user"})},I=async f=>{const N=await p(k,{instanceId:c,key:r.threadKey,...f});N?.dequeued!==void 0&&await bt({env:o,exportName:a,step:m},r.threadKey,N.dequeued)},H=async()=>await p(R,{key:r.threadKey}),V=async f=>{await p($,{key:r.threadKey,state:f})},D=await p(M,{agent:a,instanceId:c,key:r.threadKey,...t.initialState===void 0?{}:{initialState:t.initialState},...t.onConcurrentRun===void 0?{}:{onConcurrentRun:t.onConcurrentRun},...r.owner===void 0?{}:{owner:r.owner},...r.title===void 0?{}:{title:r.title}});D?.outcome==="replaced"&&await Ft(o,a,D.priorInstanceId);const X=await Ut(t,r.input,r.owner,l,m,p),J=typeof t.instructions=="function"?t.instructions({env:o,input:r.input,threadKey:r.threadKey}):t.instructions,Q={agent:t,compact:n,depth:dt(r.depth),env:o,generate:d,getState:H,instanceId:c,instructions:J,listMessages:O,memoryContext:X,onTokenDelta:i,owner:r.owner,deleteMessage:U,patchThread:E,persist:g,run:p,setState:V,step:m,streamGenerate:w,threadKey:r.threadKey,tools:t.tools??{}},K={value:void 0};try{D?.outcome==="queued"&&await qt(m,r.threadKey,c),await z();const{final:f,stoppedByCondition:N,turnsRun:Y}=await Lt(Q,v,T,K),C=K.value===void 0?{}:{usage:K.value};return await Dt({agent:t,env:o,extractGraph:u,finalText:f?.text,input:r.input,instanceId:c,owner:r.owner,paths:l,run:p,step:m}),await Pt({agent:t,env:o,extractEpisode:s,finalText:f?.text,input:r.input,instanceId:c,owner:r.owner,paths:l,run:p,step:m,threadKey:r.threadKey}),f?(await Bt(t,{env:o,params:r,step:m},{...f,...C}),await I({status:"idle",...C}),{...f,...C}):N?(await I({status:"idle",...C}),{stopped:"stopCondition",turns:Y,...C}):(await I({error:`agent stopped: maxTurns (${String(v)}) reached`,status:"error",...C}),{stopped:"maxTurns",turns:v,...C})}catch(f){throw await lt(I,f,K.value),f}};export{Tt as a,Mt as c,at as i,te as r,kt as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as o,d as E,t as C,s as T,c as b}from"./common-CJSjtsfv.mjs";import{c as v}from"./in-flight-calls-GH1A_1P3.mjs";const k=(i,g)=>typeof i=="string"&&i.length>0?i:g,P=i=>{const{functionId:g,logger:m,recordInputs:p=!1,recordOutputs:y=!1}=i,n=v((e,t,s,r)=>{const l={},c=T(o(r,"usage")??o(e.result,"usage"));if(c&&(l.metrics={completion_tokens:c.outputTokens,prompt_tokens:c.inputTokens,tokens:c.totalTokens}),t||(l.error=s??"the model call failed"),y){const d=b(o(r,"content")??o(e.result,"content"));d!==void 0&&(l.output=d)}Object.keys(l).length>0&&e.span.log(l),e.finish()},e=>{e.finish()}),h=(e,t,s)=>{const r=o(e,"callId");if(typeof r!="string")return;let l=s;t instanceof Error?l=t.message:typeof t=="string"&&t.length>0&&(l=t),n.close(r,!1,l,void 0)};return{executeLanguageModelCall:e=>{const{callId:t,execute:s}=e;let r,l;const c=new Promise((a,f)=>{r=a,l=f});let d;const x=new Promise(a=>{d=a});return Promise.resolve(m.traced(async a=>{n.open(t,()=>({finish:d,result:void 0,span:a})),p&&a.log({input:o(e,"messages"),model:o(e,"modelId")});let f;try{f=await s()}catch(u){n.close(t,!1,u instanceof Error?u.message:String(u),void 0),l(u);return}const I=n.get(t);I!==void 0&&(I.result=f),r(f),await x},{name:k(g,"language_model_call"),type:"llm"})).catch(()=>{}),c},executeTool:e=>{const t=o(o(e,"toolCall"),"toolName");return m.traced(async s=>{p&&s.log({input:C(e),tool:t});const r=await e.execute();return y&&s.log({output:r}),r},{name:k(t,"execute_tool"),type:"tool"})},onAbort:e=>{h(e,o(e,"reason"),"aborted")},onEnd:e=>{n.fromLifecycle(e)},onError:e=>{m.traced(t=>{t.log({error:E(o(e,"error")??e)})},{name:"error",type:"error"}),h(e,o(e,"error"),"the model call failed")},onLanguageModelCallEnd:e=>{const t=o(e,"callId");typeof t=="string"&&n.close(t,!0,void 0,e)},onStepEnd:e=>{n.fromLifecycle(e)}}};export{P as braintrustTelemetry};
|
package/dist/packem_shared/{compileAgentWorkflow-8pHFPjec.mjs → compileAgentWorkflow-DRkaF9sV.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as s}from"@lunora/workflow";import{r as m}from"./agent-loop-
|
|
1
|
+
import{defineWorkflow as s}from"@lunora/workflow";import{r as m}from"./agent-loop-B3KTMfqm.mjs";import{createStreamGenerate as p,createAgentGenerate as l,createEpisodeExtract as f,createGraphExtract as d,createCompact as u}from"./createAgentGenerate-BOILDUZj.mjs";import{agentDefaultName as c}from"../naming.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as A}from"./AGENT_MODULE-M4D1EejI.mjs";import{e as T}from"./createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs";import{otlpTelemetry as y}from"./otlpTelemetry-ByqrB-72.mjs";const E=(r,t,a)=>t===void 0?r:T({env:a,identity:{userId:t},label:"@lunora/agent"}),O=(r,t,a)=>{const e=t.LUNORA_OTLP_ENDPOINT;if(typeof e!="string"||e===""||r.telemetry?.isEnabled===!1)return r;const n=typeof t.LUNORA_OTLP_TOKEN=="string"?t.LUNORA_OTLP_TOKEN:void 0,i=[r.telemetry?.integrations].flat().filter(o=>o!==void 0);return{...r,telemetry:{...r.telemetry,integrations:[...i,y({conversationId:a,endpoint:e,token:n})],isEnabled:!0}}},I=(r,t,a)=>s({handler:async e=>{const n=O(r,e.env,e.params.threadKey);return m({agent:n,compact:u(),env:e.env,exportName:t,extractGraph:d(),extractEpisode:f(),generate:l(n,e.env),instanceId:e.event.instanceId,params:e.params,paths:a?.paths??A,run:E(e.run,e.params.owner,e.env),step:e.step,streamGenerate:p(n,e.env)})},name:r.name??c(t)});export{I as default};
|
package/dist/packem_shared/{createAgentContext-Ds2VaveB.mjs → createAgentContext-DPFZ88dr.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{e as g}from"./createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs";import{LunoraError as o}from"@lunora/errors";import{h as l,B as p}from"./branch-marker-boZ00zmk.mjs";import{toFunctionReference as w,DEFAULT_AGENT_FUNCTION_PATHS as m}from"./AGENT_MODULE-M4D1EejI.mjs";const T=(r,s,i)=>{const c={},u=w(m.patchThread),d=()=>i??g({env:r,label:"@lunora/agent"});for(const e of s){const a=()=>{const n=r[e.binding];if(!n||typeof n.create!="function"||typeof n.get!="function")throw new o("INTERNAL",`@lunora/agent: no Workflow binding "${e.binding}" on env for agent "${e.exportName}" — run codegen/dev so wrangler.jsonc declares it`);return n};c[e.exportName]={cancel:async n=>{await(await a().get(n)).terminate();try{await d()(u,{instanceId:n,status:"cancelled"})}catch{}},publicRun:e.publicRun===!0,run:async(n,t)=>{if(l(n))throw new o("BAD_REQUEST",`@lunora/agent: run input ${p}`);return{id:(await a().create({...t?.id===void 0?{}:{id:t.id},params:n})).id}},sendEvent:async(n,t)=>{await(await a().get(n)).sendEvent(t)},status:async n=>(await a().get(n)).status()}}return c};export{T as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as b,isLunoraError as P}from"@lunora/errors";const D=(e,t,o)=>{if(t===void 0)return{dispose:()=>{},signal:e};const a=new AbortController,n=setTimeout(()=>{a.abort(o())},t);return{dispose:()=>{clearTimeout(n)},signal:a.signal}},A=e=>{let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)},k=e=>{const t=atob(e),o=new Uint8Array(t.length);for(let a=0;a<t.length;a+=1)o[a]=t.codePointAt(a)??0;return o},p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",j=e=>{let t="",o=0;const a=e.length-2;for(;o<a;o+=3){const r=e[o]<<16|e[o+1]<<8|e[o+2];t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)+p.charAt(r>>6&63)+p.charAt(r&63)}const n=e.length-o;if(n===1){const r=e[o]<<16;t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)}else if(n===2){const r=e[o]<<16|e[o+1]<<8;t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)+p.charAt(r>>6&63)}return t};new TextDecoder;const L=new TextEncoder,$="=",B=e=>{for(let t=0;t<e.length;t+=1)if(e.charCodeAt(t)>255)return!1;return!0},M=e=>j(L.encode(JSON.stringify(e))),C=e=>!e.startsWith($)&&B(e)?e:`${$}${j(L.encode(e))}`,u="$lunora.wire$",E=64,I=1024,v="__proto__",R={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},S={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},J=e=>{if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype},h=(e,t=0)=>{if(t>E)throw new RangeError(`wire-codec: value nesting exceeds the ${E}-level limit`);if(e===void 0)return[u,"undefined"];if(e===null)return null;const o=typeof e;if(o==="bigint")return[u,"bigint",e.toString()];if(o==="number"){const r=e;return Number.isNaN(r)?[u,"nan"]:r===1/0?[u,"inf"]:r===-1/0?[u,"-inf"]:r}if(o!=="object")return e;if(e instanceof Date)return[u,"date",h(e.getTime(),t+1)];if(e instanceof Error){const r=e,s={};for(const c of Object.keys(r)){if(r[c]===void 0)continue;const l=h(r[c],t+1);c===v?Object.defineProperty(s,c,{configurable:!0,enumerable:!0,value:l,writable:!0}):s[c]=l}const i=[u,"error",String(r.name),String(r.message),s];return r.cause!==void 0&&i.push(h(r.cause,t+1)),i}if(e instanceof URL)return[u,"url",e.href];if(e instanceof Map)return[u,"map",[...e.entries()].map(([r,s])=>[h(r,t+1),h(s,t+1)])];if(e instanceof Set)return[u,"set",[...e].map(r=>h(r,t+1))];if(e instanceof ArrayBuffer)return[u,"bytes",A(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const r=e,s=r.constructor.name,i=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return s==="Uint8Array"?[u,"bytes",A(i)]:[u,"bytes",A(i),s]}if(Array.isArray(e)){const r=e.map(s=>h(s,t+1));return r.length>0&&r[0]===u?[u,"arr",r]:r}if(!J(e)){const r=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${r} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const a=e,n={};for(const r of Object.keys(a)){const s=a[r];if(s===void 0)continue;const i=h(s,t+1);r===v?Object.defineProperty(n,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):n[r]=i}return n},f=(e,t=0)=>{if(t>E)throw new RangeError(`wire-codec: value nesting exceeds the ${E}-level limit`);if(e===null||typeof e!="object")return e;if(Array.isArray(e)){if(e[0]===u)switch(e[1]){case"-inf":return-1/0;case"arr":return e[2].map(n=>f(n,t+1));case"bigint":{const n=e[2];if(typeof n!="string"||n.length>I||!/^-?\d+$/.test(n))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${I} digits)`);return BigInt(n)}case"date":{const n=f(e[2],t+1);if(typeof n!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(n)}case"map":{const n=e[2];return new Map(n.map(r=>{if(!Array.isArray(r)||r.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[f(r[0],t+1),f(r[1],t+1)]}))}case"set":return new Set(e[2].map(n=>f(n,t+1)));case"url":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(n)}case"error":{const n=e[2],r=e[3];if(typeof n!="string"||typeof r!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const s=(Object.hasOwn(S,n)?S[n]:void 0)??Error,i=new s(r);i.name!==n&&Object.defineProperty(i,"name",{configurable:!0,value:n,writable:!0});const c=f(e[4],t+1);if(c===null||typeof c!="object"||Array.isArray(c))throw new TypeError("wire-codec: malformed error — props must be an object");for(const l of Object.keys(c))l===v?Object.defineProperty(i,l,{configurable:!0,enumerable:!0,value:c[l],writable:!0}):i[l]=c[l];return e.length>5&&Object.defineProperty(i,"cause",{configurable:!0,value:f(e[5],t+1),writable:!0}),i}case"bytes":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const r=k(n);if(A(r)!==n)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const s=e[3]??"Uint8Array";if(s==="ArrayBuffer")return r.buffer.byteLength===r.byteLength?r.buffer:r.slice().buffer;const i=Object.hasOwn(R,s)?R[s]:void 0;return i?new i(r.slice().buffer):r}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return e.map(n=>f(n,t+1))}return e.map(n=>f(n,t+1))}const o=e,a={};for(const n of Object.keys(o)){const r=f(o[n],t+1);n===v?Object.defineProperty(a,n,{configurable:!0,enumerable:!0,value:r,writable:!0}):a[n]=r}return a},K=(e,t,o)=>{try{return h(o)}catch(a){throw new TypeError(`${e}: cannot encode args for '${t}' — ${a instanceof Error?a.message:String(a)}`,a instanceof Error?{cause:a}:void 0)}},F="/_lunora/scheduler/dispatch",W=3e4,G=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},U=Symbol("lunoraDispatchFailure"),H=Symbol("lunoraDispatchMessageId"),_=(e,t)=>(t!==void 0&&Object.defineProperty(e,H,{value:t}),e),z=(e,t)=>(Object.defineProperty(e,U,{value:!0}),_(e,t)),V=(e,t,o,a)=>{try{const n=JSON.parse(o)?.error;if(typeof n=="object"&&n!==null&&typeof n.code=="string"){const{code:r,data:s,message:i}=n;return z(new b(r,typeof i=="string"?i:void 0,{data:s,status:t}),a)}}catch{}return _(new b("INTERNAL",`${e}: function dispatch failed (${String(t)}): ${o}`,{status:t}),a)},q=new Set([400,403,404,422]),Q=new Set(["DISPATCH_UNAUTHENTICATED"]),Z=e=>P(e)&&e[U]===!0&&q.has(e.status)&&!Q.has(e.code),X=(e,t,o)=>new b("INTERNAL",`${e}: function dispatch to "${t}" timed out after ${String(o)}ms`,{status:503}),ee=e=>{const{label:t}=e,o=globalThis.fetch,a=e.fetchImpl??(typeof o=="function"?o.bind(globalThis):void 0);return async(n,r,s={})=>{if(typeof a!="function")throw new TypeError(`${t}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const i=e.env.LUNORA_ORIGIN_URL;if(typeof i!="string"||i.length===0)throw new b("INTERNAL",`${t}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const c=e.env.LUNORA_ADMIN_TOKEN;if(typeof c!="string"||c.length===0)throw new b("INTERNAL",`${t}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const l=`${G(i)}${F}`,m={authorization:`Bearer ${c}`,"content-type":"application/json"};e.traceparent!==void 0&&e.traceparent.length>0&&(m.traceparent=e.traceparent),e.identity?.userId!==void 0&&(m["x-lunora-userid"]=C(e.identity.userId)),e.identity?.claims!==void 0&&(m["x-lunora-identity"]=M(e.identity.claims));const N=s.timeoutMs??W,T=D(void 0,N,()=>new DOMException(`dispatch timed out after ${String(N)}ms`,"TimeoutError")),O=y=>{throw y instanceof Error&&y.name==="TimeoutError"?X(t,n.__lunoraRef,N):y};let d;try{try{d=await a(l,{body:JSON.stringify({args:K(t,n.__lunoraRef,r??{}),functionPath:n.__lunoraRef,id:s.dedupId,shardKey:s.shardKey}),headers:m,method:"POST",signal:T.signal})}catch(g){return O(g)}if(!d.ok){let g;try{g=await d.text()}catch(x){return O(x)}throw V(t,d.status,g,s.messageId)}let y;try{y=await d.text()}catch(g){return O(g)}if(y.length===0)return;let w;try{w=JSON.parse(y)}catch{throw new b("INTERNAL",`${t}: function dispatch returned a non-JSON body (${String(d.status)}): ${y}`,{status:d.status})}if(w===null||typeof w!="object"||Array.isArray(w)||!("result"in w))throw new b("INTERNAL",`${t}: function dispatch returned a JSON body that is not a { result } envelope (${String(d.status)}): ${y}`,{status:d.status});return f(w.result)}finally{T.dispose()}}};export{ee as e,Z as r};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{LunoraError as r}from"@lunora/errors";import{a as f,i as m}from"./agent-loop-
|
|
1
|
+
import{LunoraError as r}from"@lunora/errors";import{a as f,i as m}from"./agent-loop-B3KTMfqm.mjs";import{collectAgenticMemoryTools as g}from"./collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as p}from"./agentAsTool-CgZb6ycK.mjs";import{i as u}from"./positive-integer-ztHqqpBk.mjs";import{SKILL_NAME_PATTERN as w,RESERVED_SKILL_NAME as c}from"./defineSkill-DGGvDWNq.mjs";const T=/^[a-zA-Z][\w-]*$/u,N=(e,n)=>{const o={...e.tools};for(const t of n)for(const[s,a]of Object.entries(t.tools??{})){if(Object.hasOwn(o,s))throw new r("INTERNAL",`@lunora/agent: skill "${t.name}" tool "${s}" collides with an existing tool — rename one (the agent's tool namespace is flat)`);o[s]=a}return o},A=(e,n)=>{const o=[];for(const t of[e.instructions,...n.map(s=>s.instructions)])t&&o.push(t);return o.length<=1?o[0]:t=>o.map(s=>typeof s=="function"?s(t):s).filter(s=>s.length>0).join(`
|
|
2
2
|
|
|
3
3
|
`)},k=(e,n)=>{const o=[];e.memory&&m(e.memory)&&o.push({key:"default",...e.memory});for(const t of n)t.knowledge&&m(t.knowledge)&&o.push({key:t.name,...t.knowledge});return o},y=e=>{const n=new Set;for(const o of e){if(typeof o.name!="string"||!w.test(o.name))throw new r("INTERNAL",`@lunora/agent: skill \`name\` must be a valid identifier (letters, digits, _ or -, starting with a letter), got ${JSON.stringify(o.name)}`);if(o.name===c)throw new r("INTERNAL",`@lunora/agent: skill name "${c}" is reserved (it keys the agent's own \`memory\` source / the \`memory:retrieve\` step) — choose another name`);if(n.has(o.name))throw new r("INTERNAL",`@lunora/agent: skill name "${o.name}" is used by more than one skill — rename one (a skill name keys its knowledge memory source, which must be unique)`);n.add(o.name)}},v=(e,n)=>{if(e===void 0)return;const o=Object.keys(n).filter(t=>!e.includes(t));if(o.length>0)throw new r("INTERNAL",`@lunora/agent: \`activeTools\` omits the agentic-memory tool(s) ${o.map(t=>`"${t}"`).join(", ")} — the model could never call them; add them to \`activeTools\` (or drop \`activeTools\` to expose every tool)`)},E=(e,n)=>{const o=(t,s)=>{if(t&&t.kind!=="graph"&&t.kind!=="episodic"&&t.source===void 0)throw new r("INTERNAL",`@lunora/agent: ${s} requires a \`source\` action unless \`kind: "graph"\` or \`kind: "episodic"\``)};o(e.memory,"`memory`");for(const t of n)o(t.knowledge,`skill "${t.name}" \`knowledge\``)},L=e=>{if(e===void 0)return;const n=f(e);if(!Number.isFinite(n)||n<=0)throw new r("INTERNAL","@lunora/agent: `approvalTimeout` must resolve to a positive duration")},$=e=>{const n=e.model;if(n==null||typeof n=="string"&&n.length===0)throw new r("INTERNAL","@lunora/agent: defineAgent requires a `model` (a Workers AI id, an AI SDK LanguageModel, or an (env) => model thunk)");if(e.maxTurns!==void 0&&!u(e.maxTurns))throw new r("INTERNAL","@lunora/agent: `maxTurns` must be a positive integer");if(e.voice?.maxTurns!==void 0&&!u(e.voice.maxTurns))throw new r("INTERNAL","@lunora/agent: `voice.maxTurns` must be a positive integer");L(e.approvalTimeout);const o=e.skills??[];y(o),E(e,o);const t=N(e,o),s=g(e,o);for(const[i,h]of Object.entries(s)){if(Object.hasOwn(t,i))throw new r("INTERNAL",`@lunora/agent: agentic-memory tool "${i}" collides with an existing tool — rename one (the agent's tool namespace is flat)`);t[i]=h}const a=Object.keys(s).length>0;v(e.activeTools,s);for(const i of Object.keys(t))if(!T.test(i))throw new r("INTERNAL",`@lunora/agent: tool name "${i}" is not a valid identifier (letters, digits, _ or -, starting with a letter)`);const l=k(e,o),d=A(e,o);return{...e,asTool:p,isLunoraAgent:!0,...o.some(i=>!!i.instructions)?{instructions:d}:{},...l.length>0?{memorySources:l}:{},...o.length>0||a?{tools:t}:{}}},j=e=>typeof e=="object"&&e!==null&&e.isLunoraAgent===!0,M=e=>{if(typeof e.execute!="function")throw new r("INTERNAL","@lunora/agent: defineAgentTool requires an `execute` function");if(typeof e.description!="string"||e.description.length===0)throw new r("INTERNAL","@lunora/agent: defineAgentTool requires a non-empty `description` (the model decides from it)");return{...e,isLunoraAgentTool:!0}};export{$ as defineAgent,M as defineAgentTool,j as isAgentDefinition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as s}from"./common-CJSjtsfv.mjs";const f=600*1e3,h=(i,a)=>{const t=new Map,c=(e,o,n,r)=>{const l=t.get(e);l!==void 0&&(t.delete(e),i(l.call,o,n,r))};return{close:c,fromLifecycle:e=>{const o=s(e,"callId");if(typeof o!="string"||!t.has(o))return;const n=s(e,"finishReason"),r=n==="error"||s(n,"unified")==="error";c(o,!r,r?"the model call ended with an error":void 0,e)},get:e=>t.get(e)?.call,open:(e,o)=>{const n=Date.now()-f;for(const[r,l]of t)l.openedAt<n&&(t.delete(r),a?.(l.call));t.has(e)||t.set(e,{call:o(),openedAt:Date.now()})}}};export{h as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{estimateModelCost as z}from"@lunora/ai";import{a as D,r as d,s as F,e as V,c as P,t as J}from"./common-CJSjtsfv.mjs";import{c as Y}from"./in-flight-calls-GH1A_1P3.mjs";const k=e=>`${String(Math.round(e))}000000`,q=Array.from({length:256},(e,o)=>o.toString(16).padStart(2,"0")),v=512,M=new Uint8Array(v);let w=v;const j=(e,o,n)=>{let c="";for(let s=0;s<n;s+=1)c+=q[e[o+s]];return c},R=e=>{if(e>v){const n=new Uint8Array(e);return crypto.getRandomValues(n),j(n,0,e)}w+e>v&&(crypto.getRandomValues(M),w=0);const o=j(M,w,e);return w+=e,o},A=(e,o)=>typeof o=="boolean"?{key:e,value:{boolValue:o}}:typeof o=="number"?Number.isFinite(o)?Number.isSafeInteger(o)?{key:e,value:{intValue:String(o)}}:{key:e,value:{doubleValue:o}}:{key:e,value:{stringValue:String(o)}}:{key:e,value:{stringValue:o}},G=(e,o,n)=>{const c={},s=new Map,_=(g,m)=>{const x=g.toLowerCase(),T=s.get(x);T===void 0?(s.set(x,g),c[g]=m):c[T]=m};for(const[g,m]of Object.entries(e))_(g,m);for(const[g,m]of Object.entries(o??{}))_(g,m);return n!==void 0&&n.length>0&&_("authorization",`Bearer ${n}`),c},W=e=>Array.isArray(e)?e:[e],X=(e,o)=>{const n={"service.name":e};for(const[c,s]of Object.entries({}))n[c]=s;return Object.entries(n).map(([c,s])=>A(c,s))},K=(e,o,n,c)=>({resourceSpans:[{resource:{attributes:X(n)},scopeSpans:[{scope:{name:o},spans:W(e)}]}]}),i=(e,o,n)=>{if(n!=null){if(typeof n=="boolean"||typeof n=="number"||typeof n=="string"){e.push(A(o,n));return}e.push(A(o,JSON.stringify(n)))}},Q=(e,o)=>{(async()=>{let c;try{c=await e}catch(s){o(!1,s instanceof Error?s.message:String(s),void 0);return}o(!0,void 0,c)})().catch(()=>{})},oe=e=>{const{conversationId:o,endpoint:n,headers:c,recordInputs:s=!1,recordOutputs:_=!1,token:g,traceId:m,waitUntil:x}=e,T=e.serviceName??"lunora";let S=n;for(;S.endsWith("/");)S=S.slice(0,-1);const $=`${S}/v1/traces`,B=G({"content-type":"application/json"},c,g),N=(t,r,a,l,y)=>{const f={attributes:y,endTimeUnixNano:k(Date.now()),kind:1,name:t,spanId:R(8),startTimeUnixNano:k(r),status:a?{code:1}:{code:2,message:l??""},traceId:m??R(16)};try{const b=fetch($,{body:JSON.stringify(K(f,"@lunora/agent",T)),headers:B,method:"POST"}).catch(()=>{});x?.(b)}catch{}},h=Y((t,r,a,l)=>{const{messages:y,modelId:f,provider:b,result:p,startTs:H}=t,u=[];i(u,"gen_ai.operation.name","chat"),i(u,"gen_ai.request.model",f),i(u,"gen_ai.system",b),i(u,"gen_ai.conversation.id",o);const I=F(d(l,"usage")??d(p,"usage"));I&&(i(u,"gen_ai.usage.input_tokens",I.inputTokens),i(u,"gen_ai.usage.output_tokens",I.outputTokens),i(u,"gen_ai.usage.total_tokens",I.totalTokens));const O=V(l)??V(p);O&&(i(u,"gen_ai.response.cached",O.cached),i(u,"cf.aig.log_id",O.logId));const U=O?.cost,L=U??(typeof f=="string"?z(f,{inputTokens:I?.inputTokens,outputTokens:I?.outputTokens}):void 0);L!==void 0&&(i(u,"gen_ai.usage.cost",L),i(u,"lunora.usage.cost.source",U===void 0?"estimated":"provider")),s&&i(u,"gen_ai.prompt",y),_&&i(u,"gen_ai.completion",P(d(l,"content")??d(p,"content"))),N(typeof f=="string"?`chat ${f}`:"language_model_call",H,r,a,u)}),C=(t,r,a)=>{const l=d(t,"callId");if(typeof l!="string")return;let y=a;r instanceof Error?y=r.message:typeof r=="string"&&r.length>0&&(y=r),h.close(l,!1,y,void 0)},E=t=>({messages:d(t,"messages"),modelId:d(t,"modelId"),provider:d(t,"provider"),result:void 0,startTs:Date.now()});return{executeLanguageModelCall:async t=>{const{callId:r}=t;h.open(r,()=>E(t));try{const a=await t.execute(),l=h.get(r);return l!==void 0&&(l.result=a),a}catch(a){throw h.close(r,!1,a instanceof Error?a.message:String(a),void 0),a}},onAbort:t=>{C(t,d(t,"reason"),"aborted")},onEnd:t=>{h.fromLifecycle(t)},onError:t=>{C(t,d(t,"error"),"the model call failed")},onLanguageModelCallEnd:t=>{const r=d(t,"callId");typeof r=="string"&&h.close(r,!0,void 0,t)},onLanguageModelCallStart:t=>{const r=d(t,"callId");typeof r=="string"&&h.open(r,()=>E(t))},onStepEnd:t=>{h.fromLifecycle(t)},executeTool:t=>{const r=Date.now(),a=D(t),l=t.execute();return Q(l,(f,b)=>{const p=[];i(p,"gen_ai.operation.name","execute_tool"),i(p,"gen_ai.tool.name",a),i(p,"gen_ai.tool.call.id",d(t,"toolCallId")),s&&i(p,"gen_ai.tool.input",J(t)),N(typeof a=="string"?`execute_tool ${a}`:"execute_tool",r,f,b,p)}),l}}};export{oe as otlpTelemetry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./createDispatchRunner-
|
|
1
|
+
import"./createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs";import"./component-shared-G8ngerkU.mjs";import"./createAgentGenerate-BOILDUZj.mjs";import{a as n,c as l,r as u,s as f}from"./agent-loop-B3KTMfqm.mjs";import"./buildModelMessages-Y4tGo1T9.mjs";import"../naming.mjs";import"./AGENT_MODULE-M4D1EejI.mjs";import"./positive-integer-ztHqqpBk.mjs";import"./tool-output-Cmk3JWMG.mjs";export{n as approvalTimeoutMs,l as compactHistory,u as runAgentLoop,f as splitForCompaction};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./base64-5eyBfWO3.mjs";import{p as s,c as p,f as m,e as n,r as c,t as d}from"./voice-turn-
|
|
1
|
+
import"./base64-5eyBfWO3.mjs";import{p as s,c as p,f as m,e as n,r as c,t as d}from"./voice-turn-D1ZzTzcE.mjs";import"./agent-loop-B3KTMfqm.mjs";import"./buildModelMessages-Y4tGo1T9.mjs";import"./AGENT_MODULE-M4D1EejI.mjs";export{s as parseIdentity,p as pcmToWav,m as readSynthesisAudio,n as readTranscriptionText,c as runVoiceTurn,d as toByteIterable};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as n,t as _,s as y,c as I}from"./common-CJSjtsfv.mjs";import{c as x}from"./in-flight-calls-GH1A_1P3.mjs";const g=(c,i)=>typeof c=="string"&&c.length>0?c:i,k=c=>{const{functionId:i,recordInputs:d=!1,recordOutputs:p=!1,Sentry:u}=c,s=x((e,o,a,r)=>{const t={},l=y(n(r,"usage")??n(e.result,"usage"));if(l&&(t["gen_ai.usage.input_tokens"]=l.inputTokens,t["gen_ai.usage.output_tokens"]=l.outputTokens,t["gen_ai.usage.total_tokens"]=l.totalTokens),p){const m=I(n(r,"content")??n(e.result,"content"));m!==void 0&&(t["gen_ai.completion"]=m)}Object.keys(t).length>0&&e.span.setAttributes?.(t),e.span.setStatus?.(o?{code:1}:{code:2,message:a??""}),e.span.end()},e=>{e.span.end()}),f=(e,o,a)=>{const r=n(e,"callId");if(typeof r!="string")return;let t=a;o instanceof Error?t=o.message:typeof o=="string"&&o.length>0&&(t=o),s.close(r,!1,t,void 0)};return{executeLanguageModelCall:e=>{const{callId:o}=e,a={"gen_ai.operation.name":g(i,"language_model_call"),"gen_ai.request.model":n(e,"modelId"),"gen_ai.system":n(e,"provider")};return d&&(a["gen_ai.prompt"]=n(e,"messages")),u.startSpanManual({attributes:a,name:g(i,"language_model_call"),op:"gen_ai.generate"},async r=>{s.open(o,()=>({result:void 0,span:r}));try{const t=await e.execute(),l=s.get(o);return l!==void 0&&(l.result=t),t}catch(t){throw s.close(o,!1,t instanceof Error?t.message:String(t),void 0),t}})},executeTool:e=>{const o=n(n(e,"toolCall"),"toolName"),a={"gen_ai.operation.name":"execute_tool","gen_ai.tool.call.id":n(e,"toolCallId"),"gen_ai.tool.name":o};return d&&(a["gen_ai.tool.input"]=_(e)),u.startSpan({attributes:a,name:`execute_tool ${g(o,"tool")}`,op:"gen_ai.execute_tool"},()=>e.execute())},onAbort:e=>{f(e,n(e,"reason"),"aborted")},onEnd:e=>{s.fromLifecycle(e)},onError:e=>{u.captureException(n(e,"error")??e),f(e,n(e,"error"),"the model call failed")},onLanguageModelCallEnd:e=>{const o=n(e,"callId");typeof o=="string"&&s.close(o,!0,void 0,e)},onStepEnd:e=>{s.fromLifecycle(e)}}};export{k as sentryTelemetry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as P,a as q}from"./base64-5eyBfWO3.mjs";import{c as z}from"./agent-loop-
|
|
1
|
+
import{f as P,a as q}from"./base64-5eyBfWO3.mjs";import{c as z}from"./agent-loop-B3KTMfqm.mjs";import{buildModelMessages as G}from"./buildModelMessages-Y4tGo1T9.mjs";import{toFunctionReference as T}from"./AGENT_MODULE-M4D1EejI.mjs";const D=new TextDecoder;new TextEncoder;const N="=",Q=t=>{if(t)try{const e=t[0]==="{"?t:D.decode(P(t)),n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}},ct=t=>{if(t){if(!t.startsWith(N))return t;try{return D.decode(P(t.slice(N.length)))}catch{return}}},dt=t=>{const e=Number(t);return Number.isFinite(e)&&e>0?e:void 0},ut=t=>typeof t=="number"&&Date.now()>=t,ft=t=>{try{t.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},message:"authentication token expired",type:"error"})),t.close?.(4001,"token_expired")}catch{}},Y=16e3,Z=1,tt=16,M=/[.!?]\s/u,et=/\s/u,nt=async function*(t){if(t instanceof Uint8Array){yield t;return}if(t instanceof ReadableStream){const e=t.getReader();try{for(;;){const{done:n,value:r}=await e.read();if(n)break;yield r}}finally{e.releaseLock()}return}yield*t},yt=(t,e=Y,n=Z,r=tt)=>{const i=n*r/8,p=e*i,m=new ArrayBuffer(44+t.byteLength),s=new DataView(m),u=(l,E)=>{for(let d=0;d<E.length;d+=1)s.setUint8(l+d,E.codePointAt(d)??0)};u(0,"RIFF"),s.setUint32(4,36+t.byteLength,!0),u(8,"WAVE"),u(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,n,!0),s.setUint32(24,e,!0),s.setUint32(28,p,!0),s.setUint16(32,i,!0),s.setUint16(34,r,!0),u(36,"data"),s.setUint32(40,t.byteLength,!0);const a=new Uint8Array(m);return a.set(t,44),a},st=t=>{const e=[];let n=t,r=M.exec(n);for(;r;){let i=r.index+1;for(;i<n.length&&et.test(n[i]??"");)i+=1;const p=n.slice(0,i).trim();p.length>0&&e.push(p),n=n.slice(i),r=M.exec(n)}return{rest:n,sentences:e}},pt=async t=>{const{agent:e,compact:n,connectionId:r,env:i,exportName:p,owner:m,paths:s,pcm:u,run:a,send:l,sendAudio:E,signal:d,streamGenerate:C,synthesize:H,text:L,threadKey:o,transcribe:F,turn:U,waitForDrain:O}=t,h=()=>d.aborted,v=T(s.appendMessage),$=T(s.ensureThread),B=T(s.listMessages),b=T(s.patchThread);await a($,{agent:p,key:o,...e.initialState===void 0?{}:{initialState:e.initialState},...m===void 0?{}:{owner:m}});try{const f=(L??(u?await F(u):"")).trim();if(f.length===0)return await a(b,{key:o,status:"idle"}),{assistantText:"",interrupted:!1,userText:""};l({text:f,type:"user_transcript"}),await a(v,{content:f,messageKey:`voice:${r}:${String(U)}:user`,role:"user",threadKey:o}),await a(b,{key:o,status:"running"});const I=typeof e.instructions=="function"?e.instructions({env:i,input:f,threadKey:o}):e.instructions,K=await a(B,{key:o}),{history:j,summary:R}=await z({agent:e,compact:n,env:i},K),W=G({history:j,...I===void 0?{}:{instructions:I},...R===void 0?{}:{summary:R}});let g="",w="",S=Promise.resolve();const V=async c=>{if(h()||c.length===0)return;let x=!1;try{for await(const y of nt(await H(c,d))){if(h()||(await O?.(),h()))break;E(y),x=!0}}catch(y){l({message:y instanceof Error?y.message:String(y),type:"error"})}x&&(w=w.length>0?`${w} ${c}`:c)},_=c=>{S=S.then(async()=>V(c))},X=await C({messages:W,signal:d},c=>{if(h())return;l({text:c,type:"assistant_delta"}),g+=c;const{rest:x,sentences:y}=st(g);g=x;for(const J of y)_(J)});!h()&&g.trim().length>0&&_(g.trim()),g="",await S;const k=h(),A=k?w:X.text;return await a(v,{content:A,messageKey:`voice:${r}:${String(U)}:assistant`,role:"assistant",threadKey:o}),await a(b,{key:o,status:"idle"}),l(k?{type:"interrupted"}:{text:A,type:"assistant_done"}),{assistantText:A,interrupted:k,userText:f}}catch(f){throw await a(b,{key:o,status:"idle"}),f}},lt=t=>Q(t),ht=t=>{if(typeof t=="object"&&t!==null&&"text"in t){const{text:e}=t;return typeof e=="string"?e:""}return""},gt=t=>{if(t instanceof Uint8Array||t instanceof ReadableStream)return t;if(t instanceof Response&&t.body)return t.body;if(typeof t=="object"&&t!==null&&"audio"in t){const{audio:e}=t;if(typeof e=="string")return q(e);if(e instanceof ReadableStream||e instanceof Uint8Array)return e}return new Uint8Array(0)};export{dt as a,ft as b,yt as c,ct as d,ht as e,gt as f,ut as i,lt as p,pt as r,nt as t};
|
|
@@ -60,9 +60,24 @@ interface BraintrustTelemetryOptions extends CommonOptions {
|
|
|
60
60
|
* A dependency-injected Braintrust bridge for the ai@7 telemetry surface.
|
|
61
61
|
*
|
|
62
62
|
* It wraps model calls (`type: "llm"`) and tool executions (`type: "tool"`) in
|
|
63
|
-
* `logger.traced` spans and logs structural metadata
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* `logger.traced` spans and logs structural metadata, including the call's token
|
|
64
|
+
* usage as Braintrust `metrics`. Prompts / tool arguments are logged only when
|
|
65
|
+
* `recordInputs` is set; generated text / tool results only when `recordOutputs`
|
|
66
|
+
* is set. `onError` opens a span and logs the error.
|
|
67
|
+
*
|
|
68
|
+
* The tool span is driven by the agent LOOP, not by `ai`: Lunora exposes tools
|
|
69
|
+
* schema-only so the SDK never executes one (see `telemetry/tool-execution.ts`).
|
|
70
|
+
*
|
|
71
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
72
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
73
|
+
* stream — before a token, before any usage — so a span that simply awaited it
|
|
74
|
+
* measured time-to-first-byte and logged the stream handle instead of the
|
|
75
|
+
* generation. `execute()` still runs INSIDE the traced callback, which is what
|
|
76
|
+
* parents the provider's own work under the span; the callback then parks until
|
|
77
|
+
* the SDK's terminal event for that `callId` arrives, so `traced` finishes the
|
|
78
|
+
* span at the real end of the call, with the real usage. The caller gets
|
|
79
|
+
* `execute()`'s value the moment it resolves, exactly as before — the span's
|
|
80
|
+
* lifetime and the caller's are deliberately separate.
|
|
66
81
|
*
|
|
67
82
|
* The app owns Braintrust initialization; pass the logger in as `logger`.
|
|
68
83
|
* @experimental
|
|
@@ -173,36 +188,72 @@ interface OtlpTelemetryOptions extends CommonOptions {
|
|
|
173
188
|
* An OTLP-over-HTTP telemetry integration for `@lunora/agent`.
|
|
174
189
|
*
|
|
175
190
|
* The OTLP counterpart to the `sentryTelemetry` / `braintrustTelemetry` bridges:
|
|
176
|
-
* it
|
|
191
|
+
* it records each language-model call and each tool execution as an OTLP **span**
|
|
177
192
|
* (`gen_ai.*` semantic-convention attributes — model, provider, token usage,
|
|
178
193
|
* tool name) and ships it to a collector, so agent generations land in the same
|
|
179
194
|
* trace store as the rest of an app's telemetry (the Lunora Cloud, or any OTel
|
|
180
195
|
* collector). Plug it into `defineAgent({ telemetry: { isEnabled: true,
|
|
181
196
|
* integrations: [otlpTelemetry({ endpoint, token })] } })`.
|
|
182
197
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
198
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
199
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
200
|
+
* stream — before a single token, before any usage, and before any mid-stream
|
|
201
|
+
* failure. Closing the span there reported every voice and workflow-streamed turn
|
|
202
|
+
* as a ~1 ms, zero-token, always-OK call. So the span opens in
|
|
203
|
+
* `executeLanguageModelCall` (which also owns the failure path, since a rejected
|
|
204
|
+
* provider call produces no end event) and closes on `onLanguageModelCallEnd`,
|
|
205
|
+
* which the SDK fires once the response is normalized — after the stream's
|
|
206
|
+
* `finish` part, where the duration and the token usage actually live.
|
|
207
|
+
* `onError` / `onAbort` close whatever is still open, so a stream that dies or is
|
|
208
|
+
* barged in on reports a failure instead of a phantom success.
|
|
209
|
+
*
|
|
210
|
+
* **Tool spans come from the agent loop.** Lunora exposes tools to the model
|
|
211
|
+
* schema-only, so `ai` never runs one and never fires its tool telemetry; the
|
|
212
|
+
* loop calls `executeTool` itself from the durable step where the tool really
|
|
213
|
+
* runs (see `telemetry/tool-execution.ts`).
|
|
214
|
+
*
|
|
215
|
+
* One span per REAL execution: the agent loop memoizes each `step.do(...)`, so a
|
|
216
|
+
* Workflow replay returns the cached result without re-invoking the wrapped work
|
|
217
|
+
* and no duplicate span is emitted. Privacy-safe by default —
|
|
218
|
+
* `recordInputs`/`recordOutputs` both default `false`, so no prompt or generated
|
|
219
|
+
* text leaves the worker without an explicit opt-in; only structural metadata +
|
|
220
|
+
* token counts are recorded.
|
|
189
221
|
*
|
|
190
222
|
* Each export is fire-and-forget (registered with `waitUntil` when supplied);
|
|
191
223
|
* every rejection is swallowed so a flaky collector never surfaces to the run.
|
|
192
224
|
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* `traceId` is set) but no `parentSpanId`, so model-call and tool spans are
|
|
198
|
-
* siblings under the run rather than a tree — OTLP has no ambient span context to
|
|
199
|
-
* parent to here.
|
|
225
|
+
* One deliberate difference from the SDK-backed bridges, which delegate to a host
|
|
226
|
+
* tracer: flat, not nested. Every span gets `traceId` (shared when `traceId` is
|
|
227
|
+
* set) but no `parentSpanId`, so model-call and tool spans are siblings under the
|
|
228
|
+
* run rather than a tree — OTLP has no ambient span context to parent to here.
|
|
200
229
|
* @param options `endpoint` (+ optional `token`/`headers`/`serviceName`),
|
|
201
230
|
* `traceId` to group a run's spans, `waitUntil`, and the `recordInputs`/
|
|
202
231
|
* `recordOutputs` privacy flags.
|
|
203
232
|
* @experimental
|
|
204
233
|
*/
|
|
205
234
|
declare const otlpTelemetry: (options: OtlpTelemetryOptions) => Telemetry;
|
|
235
|
+
/** The span context both `startSpan` and `startSpanManual` are called with. */
|
|
236
|
+
interface SentrySpanContext {
|
|
237
|
+
attributes?: Record<string, unknown>;
|
|
238
|
+
name: string;
|
|
239
|
+
op?: string;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* The subset of a Sentry `Span` this bridge drives. Structural, like
|
|
243
|
+
* {@link SentryLike} itself — a real `@sentry/*` span satisfies it.
|
|
244
|
+
* @experimental
|
|
245
|
+
*/
|
|
246
|
+
interface SentrySpan {
|
|
247
|
+
/** Finish the span. Called once, from whichever terminal event closes the call. */
|
|
248
|
+
end: () => void;
|
|
249
|
+
/** Attach attributes discovered after the span started (token usage). */
|
|
250
|
+
setAttributes?: (attributes: Record<string, unknown>) => unknown;
|
|
251
|
+
/** `1` = OK, `2` = ERROR (Sentry's `SPAN_STATUS_OK` / `SPAN_STATUS_ERROR`). */
|
|
252
|
+
setStatus?: (status: {
|
|
253
|
+
code: 0 | 1 | 2;
|
|
254
|
+
message?: string;
|
|
255
|
+
}) => unknown;
|
|
256
|
+
}
|
|
206
257
|
/**
|
|
207
258
|
* The minimal, **structural** slice of `@sentry/cloudflare` (equivalently
|
|
208
259
|
* `@sentry/node`/`@sentry/browser`) this bridge needs. `@sentry/cloudflare` is
|
|
@@ -214,16 +265,16 @@ declare const otlpTelemetry: (options: OtlpTelemetryOptions) => Telemetry;
|
|
|
214
265
|
interface SentryLike {
|
|
215
266
|
/** Capture a thrown value / exception. */
|
|
216
267
|
captureException: (exception: unknown) => unknown;
|
|
217
|
-
/** Run `callback` inside a new span
|
|
218
|
-
startSpan: <T>(context:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
/** Run `callback` inside a new span, finished when the callback settles. */
|
|
269
|
+
startSpan: <T>(context: SentrySpanContext, callback: (span: SentrySpan) => T) => T;
|
|
270
|
+
/**
|
|
271
|
+
* Run `callback` inside a new span that is **not** finished automatically —
|
|
272
|
+
* the caller owns its lifetime through `span.end()`. Present on every Sentry
|
|
273
|
+
* SDK built on `@sentry/core` (verified against `@sentry/core@10.55.0`); it is
|
|
274
|
+
* what lets a streamed model call be measured to the end of the stream while
|
|
275
|
+
* still nesting the provider's own work under it.
|
|
276
|
+
*/
|
|
277
|
+
startSpanManual: <T>(context: SentrySpanContext, callback: (span: SentrySpan) => T) => T;
|
|
227
278
|
}
|
|
228
279
|
/**
|
|
229
280
|
* Options for {@link sentryTelemetry}.
|
|
@@ -241,11 +292,25 @@ interface SentryTelemetryOptions extends CommonOptions {
|
|
|
241
292
|
/**
|
|
242
293
|
* A dependency-injected Sentry bridge for the ai@7 telemetry surface.
|
|
243
294
|
*
|
|
244
|
-
* It wraps model calls and tool executions in Sentry spans
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* set, in which case prompts
|
|
295
|
+
* It wraps model calls and tool executions in Sentry spans so nested
|
|
296
|
+
* provider/tool work is correctly parented, and routes `onError` to
|
|
297
|
+
* `Sentry.captureException`. Span attributes carry only structural metadata
|
|
298
|
+
* (model, provider, tool name, token usage) unless `recordInputs` /
|
|
299
|
+
* `recordOutputs` are set, in which case prompts, tool arguments and generated
|
|
300
|
+
* text are attached too.
|
|
301
|
+
*
|
|
302
|
+
* The tool span is driven by the agent LOOP, not by `ai`: Lunora exposes tools
|
|
303
|
+
* schema-only so the SDK never executes one (see `telemetry/tool-execution.ts`).
|
|
304
|
+
*
|
|
305
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
306
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
307
|
+
* stream — before a token, before any usage. The span still OPENS around
|
|
308
|
+
* `execute()`, because that is what makes it the active span nested provider work
|
|
309
|
+
* parents to, but it is opened with `startSpanManual` and so is not finished
|
|
310
|
+
* there: `onLanguageModelCallEnd` ends it, once the response is normalized and
|
|
311
|
+
* the real duration and token usage are both known. `onAbort` / `onError` end the
|
|
312
|
+
* call they name as a failure, so a stream that dies or is barged in on reports
|
|
313
|
+
* one instead of a phantom success.
|
|
249
314
|
*
|
|
250
315
|
* The app owns Sentry initialization; pass the namespace in as `Sentry`.
|
|
251
316
|
* @experimental
|
|
@@ -305,4 +370,4 @@ type BraintrustSpan,
|
|
|
305
370
|
* All integrations are privacy-safe by default (`recordInputs` / `recordOutputs`
|
|
306
371
|
* both default `false`), so nothing sensitive is recorded without opt-in.
|
|
307
372
|
*/
|
|
308
|
-
type BraintrustTelemetryOptions, type CommonOptions, type ConsoleLogLevel, type ConsoleLogger, type ConsoleTelemetryOptions, type OtlpTelemetryOptions, type SentryLike, type SentryTelemetryOptions, braintrustTelemetry, combineTelemetry, consoleTelemetry, otlpTelemetry, sentryTelemetry };
|
|
373
|
+
type BraintrustTelemetryOptions, type CommonOptions, type ConsoleLogLevel, type ConsoleLogger, type ConsoleTelemetryOptions, type OtlpTelemetryOptions, type SentryLike, type SentrySpan, type SentryTelemetryOptions, braintrustTelemetry, combineTelemetry, consoleTelemetry, otlpTelemetry, sentryTelemetry };
|
|
@@ -60,9 +60,24 @@ interface BraintrustTelemetryOptions extends CommonOptions {
|
|
|
60
60
|
* A dependency-injected Braintrust bridge for the ai@7 telemetry surface.
|
|
61
61
|
*
|
|
62
62
|
* It wraps model calls (`type: "llm"`) and tool executions (`type: "tool"`) in
|
|
63
|
-
* `logger.traced` spans and logs structural metadata
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* `logger.traced` spans and logs structural metadata, including the call's token
|
|
64
|
+
* usage as Braintrust `metrics`. Prompts / tool arguments are logged only when
|
|
65
|
+
* `recordInputs` is set; generated text / tool results only when `recordOutputs`
|
|
66
|
+
* is set. `onError` opens a span and logs the error.
|
|
67
|
+
*
|
|
68
|
+
* The tool span is driven by the agent LOOP, not by `ai`: Lunora exposes tools
|
|
69
|
+
* schema-only so the SDK never executes one (see `telemetry/tool-execution.ts`).
|
|
70
|
+
*
|
|
71
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
72
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
73
|
+
* stream — before a token, before any usage — so a span that simply awaited it
|
|
74
|
+
* measured time-to-first-byte and logged the stream handle instead of the
|
|
75
|
+
* generation. `execute()` still runs INSIDE the traced callback, which is what
|
|
76
|
+
* parents the provider's own work under the span; the callback then parks until
|
|
77
|
+
* the SDK's terminal event for that `callId` arrives, so `traced` finishes the
|
|
78
|
+
* span at the real end of the call, with the real usage. The caller gets
|
|
79
|
+
* `execute()`'s value the moment it resolves, exactly as before — the span's
|
|
80
|
+
* lifetime and the caller's are deliberately separate.
|
|
66
81
|
*
|
|
67
82
|
* The app owns Braintrust initialization; pass the logger in as `logger`.
|
|
68
83
|
* @experimental
|
|
@@ -173,36 +188,72 @@ interface OtlpTelemetryOptions extends CommonOptions {
|
|
|
173
188
|
* An OTLP-over-HTTP telemetry integration for `@lunora/agent`.
|
|
174
189
|
*
|
|
175
190
|
* The OTLP counterpart to the `sentryTelemetry` / `braintrustTelemetry` bridges:
|
|
176
|
-
* it
|
|
191
|
+
* it records each language-model call and each tool execution as an OTLP **span**
|
|
177
192
|
* (`gen_ai.*` semantic-convention attributes — model, provider, token usage,
|
|
178
193
|
* tool name) and ships it to a collector, so agent generations land in the same
|
|
179
194
|
* trace store as the rest of an app's telemetry (the Lunora Cloud, or any OTel
|
|
180
195
|
* collector). Plug it into `defineAgent({ telemetry: { isEnabled: true,
|
|
181
196
|
* integrations: [otlpTelemetry({ endpoint, token })] } })`.
|
|
182
197
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
198
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
199
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
200
|
+
* stream — before a single token, before any usage, and before any mid-stream
|
|
201
|
+
* failure. Closing the span there reported every voice and workflow-streamed turn
|
|
202
|
+
* as a ~1 ms, zero-token, always-OK call. So the span opens in
|
|
203
|
+
* `executeLanguageModelCall` (which also owns the failure path, since a rejected
|
|
204
|
+
* provider call produces no end event) and closes on `onLanguageModelCallEnd`,
|
|
205
|
+
* which the SDK fires once the response is normalized — after the stream's
|
|
206
|
+
* `finish` part, where the duration and the token usage actually live.
|
|
207
|
+
* `onError` / `onAbort` close whatever is still open, so a stream that dies or is
|
|
208
|
+
* barged in on reports a failure instead of a phantom success.
|
|
209
|
+
*
|
|
210
|
+
* **Tool spans come from the agent loop.** Lunora exposes tools to the model
|
|
211
|
+
* schema-only, so `ai` never runs one and never fires its tool telemetry; the
|
|
212
|
+
* loop calls `executeTool` itself from the durable step where the tool really
|
|
213
|
+
* runs (see `telemetry/tool-execution.ts`).
|
|
214
|
+
*
|
|
215
|
+
* One span per REAL execution: the agent loop memoizes each `step.do(...)`, so a
|
|
216
|
+
* Workflow replay returns the cached result without re-invoking the wrapped work
|
|
217
|
+
* and no duplicate span is emitted. Privacy-safe by default —
|
|
218
|
+
* `recordInputs`/`recordOutputs` both default `false`, so no prompt or generated
|
|
219
|
+
* text leaves the worker without an explicit opt-in; only structural metadata +
|
|
220
|
+
* token counts are recorded.
|
|
189
221
|
*
|
|
190
222
|
* Each export is fire-and-forget (registered with `waitUntil` when supplied);
|
|
191
223
|
* every rejection is swallowed so a flaky collector never surfaces to the run.
|
|
192
224
|
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* `traceId` is set) but no `parentSpanId`, so model-call and tool spans are
|
|
198
|
-
* siblings under the run rather than a tree — OTLP has no ambient span context to
|
|
199
|
-
* parent to here.
|
|
225
|
+
* One deliberate difference from the SDK-backed bridges, which delegate to a host
|
|
226
|
+
* tracer: flat, not nested. Every span gets `traceId` (shared when `traceId` is
|
|
227
|
+
* set) but no `parentSpanId`, so model-call and tool spans are siblings under the
|
|
228
|
+
* run rather than a tree — OTLP has no ambient span context to parent to here.
|
|
200
229
|
* @param options `endpoint` (+ optional `token`/`headers`/`serviceName`),
|
|
201
230
|
* `traceId` to group a run's spans, `waitUntil`, and the `recordInputs`/
|
|
202
231
|
* `recordOutputs` privacy flags.
|
|
203
232
|
* @experimental
|
|
204
233
|
*/
|
|
205
234
|
declare const otlpTelemetry: (options: OtlpTelemetryOptions) => Telemetry;
|
|
235
|
+
/** The span context both `startSpan` and `startSpanManual` are called with. */
|
|
236
|
+
interface SentrySpanContext {
|
|
237
|
+
attributes?: Record<string, unknown>;
|
|
238
|
+
name: string;
|
|
239
|
+
op?: string;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* The subset of a Sentry `Span` this bridge drives. Structural, like
|
|
243
|
+
* {@link SentryLike} itself — a real `@sentry/*` span satisfies it.
|
|
244
|
+
* @experimental
|
|
245
|
+
*/
|
|
246
|
+
interface SentrySpan {
|
|
247
|
+
/** Finish the span. Called once, from whichever terminal event closes the call. */
|
|
248
|
+
end: () => void;
|
|
249
|
+
/** Attach attributes discovered after the span started (token usage). */
|
|
250
|
+
setAttributes?: (attributes: Record<string, unknown>) => unknown;
|
|
251
|
+
/** `1` = OK, `2` = ERROR (Sentry's `SPAN_STATUS_OK` / `SPAN_STATUS_ERROR`). */
|
|
252
|
+
setStatus?: (status: {
|
|
253
|
+
code: 0 | 1 | 2;
|
|
254
|
+
message?: string;
|
|
255
|
+
}) => unknown;
|
|
256
|
+
}
|
|
206
257
|
/**
|
|
207
258
|
* The minimal, **structural** slice of `@sentry/cloudflare` (equivalently
|
|
208
259
|
* `@sentry/node`/`@sentry/browser`) this bridge needs. `@sentry/cloudflare` is
|
|
@@ -214,16 +265,16 @@ declare const otlpTelemetry: (options: OtlpTelemetryOptions) => Telemetry;
|
|
|
214
265
|
interface SentryLike {
|
|
215
266
|
/** Capture a thrown value / exception. */
|
|
216
267
|
captureException: (exception: unknown) => unknown;
|
|
217
|
-
/** Run `callback` inside a new span
|
|
218
|
-
startSpan: <T>(context:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
/** Run `callback` inside a new span, finished when the callback settles. */
|
|
269
|
+
startSpan: <T>(context: SentrySpanContext, callback: (span: SentrySpan) => T) => T;
|
|
270
|
+
/**
|
|
271
|
+
* Run `callback` inside a new span that is **not** finished automatically —
|
|
272
|
+
* the caller owns its lifetime through `span.end()`. Present on every Sentry
|
|
273
|
+
* SDK built on `@sentry/core` (verified against `@sentry/core@10.55.0`); it is
|
|
274
|
+
* what lets a streamed model call be measured to the end of the stream while
|
|
275
|
+
* still nesting the provider's own work under it.
|
|
276
|
+
*/
|
|
277
|
+
startSpanManual: <T>(context: SentrySpanContext, callback: (span: SentrySpan) => T) => T;
|
|
227
278
|
}
|
|
228
279
|
/**
|
|
229
280
|
* Options for {@link sentryTelemetry}.
|
|
@@ -241,11 +292,25 @@ interface SentryTelemetryOptions extends CommonOptions {
|
|
|
241
292
|
/**
|
|
242
293
|
* A dependency-injected Sentry bridge for the ai@7 telemetry surface.
|
|
243
294
|
*
|
|
244
|
-
* It wraps model calls and tool executions in Sentry spans
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* set, in which case prompts
|
|
295
|
+
* It wraps model calls and tool executions in Sentry spans so nested
|
|
296
|
+
* provider/tool work is correctly parented, and routes `onError` to
|
|
297
|
+
* `Sentry.captureException`. Span attributes carry only structural metadata
|
|
298
|
+
* (model, provider, tool name, token usage) unless `recordInputs` /
|
|
299
|
+
* `recordOutputs` are set, in which case prompts, tool arguments and generated
|
|
300
|
+
* text are attached too.
|
|
301
|
+
*
|
|
302
|
+
* The tool span is driven by the agent LOOP, not by `ai`: Lunora exposes tools
|
|
303
|
+
* schema-only so the SDK never executes one (see `telemetry/tool-execution.ts`).
|
|
304
|
+
*
|
|
305
|
+
* **A model-call span closes when the CALL ends, not when `execute()` resolves.**
|
|
306
|
+
* On a streamed turn `execute()` resolves the instant `doStream` hands back the
|
|
307
|
+
* stream — before a token, before any usage. The span still OPENS around
|
|
308
|
+
* `execute()`, because that is what makes it the active span nested provider work
|
|
309
|
+
* parents to, but it is opened with `startSpanManual` and so is not finished
|
|
310
|
+
* there: `onLanguageModelCallEnd` ends it, once the response is normalized and
|
|
311
|
+
* the real duration and token usage are both known. `onAbort` / `onError` end the
|
|
312
|
+
* call they name as a failure, so a stream that dies or is barged in on reports
|
|
313
|
+
* one instead of a phantom success.
|
|
249
314
|
*
|
|
250
315
|
* The app owns Sentry initialization; pass the namespace in as `Sentry`.
|
|
251
316
|
* @experimental
|
|
@@ -305,4 +370,4 @@ type BraintrustSpan,
|
|
|
305
370
|
* All integrations are privacy-safe by default (`recordInputs` / `recordOutputs`
|
|
306
371
|
* both default `false`), so nothing sensitive is recorded without opt-in.
|
|
307
372
|
*/
|
|
308
|
-
type BraintrustTelemetryOptions, type CommonOptions, type ConsoleLogLevel, type ConsoleLogger, type ConsoleTelemetryOptions, type OtlpTelemetryOptions, type SentryLike, type SentryTelemetryOptions, braintrustTelemetry, combineTelemetry, consoleTelemetry, otlpTelemetry, sentryTelemetry };
|
|
373
|
+
type BraintrustTelemetryOptions, type CommonOptions, type ConsoleLogLevel, type ConsoleLogger, type ConsoleTelemetryOptions, type OtlpTelemetryOptions, type SentryLike, type SentrySpan, type SentryTelemetryOptions, braintrustTelemetry, combineTelemetry, consoleTelemetry, otlpTelemetry, sentryTelemetry };
|
package/dist/telemetry/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{braintrustTelemetry as o}from"../packem_shared/braintrustTelemetry-
|
|
1
|
+
import{braintrustTelemetry as o}from"../packem_shared/braintrustTelemetry-Byne8uPK.mjs";import{combineTelemetry as m}from"../packem_shared/combineTelemetry-DgE9W9G8.mjs";import{consoleTelemetry as p}from"../packem_shared/consoleTelemetry-BZY3Y-Ly.mjs";import{otlpTelemetry as f}from"../packem_shared/otlpTelemetry-ByqrB-72.mjs";import{sentryTelemetry as T}from"../packem_shared/sentryTelemetry-BHeydiAB.mjs";export{o as braintrustTelemetry,m as combineTelemetry,p as consoleTelemetry,f as otlpTelemetry,T as sentryTelemetry};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/agent",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.91",
|
|
4
4
|
"description": "Durable AI agents for Lunora: defineAgent compiles a replay-safe tool-loop onto Cloudflare Workflows, with DO SQLite threads and live message subscriptions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -84,12 +84,12 @@
|
|
|
84
84
|
"access": "public"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@lunora/ai": "1.0.0-alpha.
|
|
88
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
89
|
-
"@lunora/mail": "1.0.0-alpha.
|
|
90
|
-
"@lunora/server": "1.0.0-alpha.
|
|
91
|
-
"@lunora/values": "1.0.0-alpha.
|
|
92
|
-
"@lunora/workflow": "1.0.0-alpha.
|
|
87
|
+
"@lunora/ai": "1.0.0-alpha.74",
|
|
88
|
+
"@lunora/errors": "1.0.0-alpha.33",
|
|
89
|
+
"@lunora/mail": "1.0.0-alpha.65",
|
|
90
|
+
"@lunora/server": "1.0.0-alpha.105",
|
|
91
|
+
"@lunora/values": "1.0.0-alpha.41",
|
|
92
|
+
"@lunora/workflow": "1.0.0-alpha.47",
|
|
93
93
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
94
94
|
"ai": "7.0.59",
|
|
95
95
|
"yaml": "^2.9.0"
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{k as Z}from"./createDispatchRunner-BrbbxS2q-DBBqImoR.mjs";import{c as F,d as tt}from"./component-shared-G8ngerkU.mjs";import{resolveAgentModel as et}from"./createAgentGenerate-BOILDUZj.mjs";import{buildModelMessages as G}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as L}from"../naming.mjs";import{toFunctionReference as h}from"./AGENT_MODULE-M4D1EejI.mjs";import{i as ot}from"./positive-integer-ztHqqpBk.mjs";import{c as j}from"./tool-output-Cmk3JWMG.mjs";const nt=e=>e.kind==="graph"||e.kind==="episodic"||e.mode!=="agentic",P=e=>e.memorySources?e.memorySources:e.memory&&nt(e.memory)?[{key:"default",...e.memory}]:[],at=e=>P(e).find(t=>t.kind==="graph"),st=e=>P(e).find(t=>t.kind==="episodic"),S=(e,t)=>t==="default"?e:`${e}:${t}`,rt=8,it=e=>ot(e)?e:0,b=e=>e===void 0?"null":JSON.stringify(e),ct=async(e,t,n)=>{try{await e({error:t instanceof Error?t.message:String(t),status:"error",...n===void 0?{}:{usage:n}})}catch(o){t instanceof Error&&t.cause===void 0&&(t.cause=o)}},ut=e=>e===void 0?[]:[e].flat(),dt=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),pt=(e,t)=>{if(t===void 0)return e;if(e===void 0)return{...t};const n={};for(const o of["inputTokens","outputTokens","totalTokens"])(e[o]!==void 0||t[o]!==void 0)&&(n[o]=(e[o]??0)+(t[o]??0));return n},lt=async(e,t,n,o,a)=>{const{needsApproval:r}=e;return r===void 0||r===!1?!1:r===!0?!0:n.do(o,async()=>r(t,a))},mt="WorkflowTimeoutError",yt=e=>e instanceof Error&&e.name===mt,q=4320*60*1e3,ft={day:864e5,hour:36e5,minute:6e4,month:30*864e5,second:1e3,week:7*864e5,year:365*864e5},vt=/^(\d+(?:\.\d+)?) (day|hour|minute|month|second|week|year)s?$/u,ht=e=>{if(e===void 0)return q;if(typeof e=="number")return Math.min(e,F);const t=vt.exec(e);return t===null?q:Math.min(Number(t[1])*ft[t[2]],F)},gt=async(e,t)=>{const{agent:n,deleteMessage:o,instanceId:a,patchThread:r,persist:c,step:u}=e;await c({content:`Awaiting approval to run tool "${t.name}".`,messageKey:`${a}:approval:${t.id}`,role:"tool",status:"awaiting_approval",toolCallId:t.id,toolName:t.name}),await r({status:"awaiting_input"});const i=await u.waitForEvent(`approval:${t.id}`,{timeout:ht(n.approvalTimeout),type:`agent-approval:${t.id}`}).then(p=>({decision:p.payload.decision,...p.payload.note===void 0?{}:{note:p.payload.note}})).catch(p=>{if(!yt(p))throw p;return{decision:"reject",note:"approval timed out"}});return await o(`${a}:approval:${t.id}`),await r({status:"running"}),i},O="lunoraToolOutcome",wt=e=>typeof e=="object"&&e!==null&&O in e?e[O]:{ok:e},Tt=async(e,t)=>{const{depth:n,env:o,getState:a,instanceId:r,onTokenDelta:c,owner:u,persist:i,run:p,setState:s,step:d,threadKey:l,tools:y}=e,f=`tool:${t.name}:${t.id}`,g=y[t.name],w=`${r}:tool:${t.id}`;if(!g){await i({content:`Error: unknown tool "${t.name}"`,messageKey:w,role:"tool",stepName:f,toolCallId:t.id,toolName:t.name});return}if(t.invalid!==void 0){await i({content:`Error: invalid input for tool "${t.name}" — it was not run. ${t.invalid}`,messageKey:w,role:"tool",stepName:f,toolCallId:t.id,toolName:t.name});return}const C={depth:n,env:o,getState:a,idempotencyKey:f,owner:u,reportProgress:T=>{c?.({data:T,kind:"progress",threadKey:l,toolCallId:t.id})},run:p,setState:s,step:d,threadKey:l,toolCallId:t.id},$={depth:n,env:o,getState:a,idempotencyKey:f,run:p,threadKey:l,toolCallId:t.id},A=`tool:approval-gate:${t.id}`;let x;if(await lt(g,t.input,d,A,$)){const{decision:T,note:K}=await gt(e,t);if(T==="reject"){const _=K===void 0?"":` Reason: ${K}`;await i({content:`Tool "${t.name}" was rejected by the user and not run.${_}`,messageKey:w,role:"tool",status:"rejected",stepName:f,toolCallId:t.id,toolName:t.name});return}x="approved"}const M=wt(await d.do(f,async()=>{try{return{[O]:{ok:await g.execute(t.input,C)}}}catch(T){if(Z(T))return{[O]:{failed:T.message}};throw T}}));if("failed"in M){await i({content:j(`Error: tool "${t.name}" failed and will not be retried. ${M.failed}`),messageKey:w,role:"tool",stepName:f,...x===void 0?{}:{status:x},toolCallId:t.id,toolName:t.name});return}const R=M.ok;await i({content:j(typeof R=="string"?R:b(R)),messageKey:w,role:"tool",stepName:f,...x===void 0?{}:{status:x},toolCallId:t.id,toolName:t.name})},xt=(e,t,n)=>{if(!t)return e;let{messages:o}=e;return t.messages!==void 0&&(o=t.messages),t.system!==void 0&&(o=[{content:t.system,role:"system"},...o]),{activeTools:t.activeTools??e.activeTools,messages:o,model:t.model===void 0?e.model:et(t.model,n),toolChoice:t.toolChoice??e.toolChoice}},kt=(e,t)=>{if(t===void 0||e.length<=t.maxMessages)return;const n=Math.max(1,t.keepRecent??Math.ceil(t.maxMessages/2));if(e.length<=n)return;let o=e.length-n;for(;o>0&&e[o]?.role==="tool";)o-=1;if(!(o<=0))return{older:e.slice(0,o),recent:e.slice(o)}},St=async(e,t)=>{const{agent:n,compact:o,env:a}=e,r=kt(t,n.compaction);if(r===void 0||o===void 0)return{history:t,summary:void 0};try{const c=await o({env:a,messages:G({history:r.older}),model:n.compaction?.model??n.model});return c.length>0?{history:r.recent,summary:c}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},Ct=async(e,t,n)=>{const{agent:o,env:a,generate:r,instructions:c,listMessages:u,memoryContext:i,onTokenDelta:p,run:s,step:d,streamGenerate:l,threadKey:y}=e;return d.do(`llm:turn:${String(t)}`,async()=>{const f=await s(u,{key:y}),{history:g,summary:w}=await St(e,f);let v={activeTools:o.activeTools,messages:G({history:g,instructions:c,memoryContext:i,summary:w}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(v=xt(v,await o.prepareStep({messages:v.messages,stepNumber:t,steps:n}),a));const C={messages:v.messages,...v.activeTools===void 0?{}:{activeTools:v.activeTools},...v.model===void 0?{}:{model:v.model},...v.toolChoice===void 0?{}:{toolChoice:v.toolChoice}};return l&&p?l(C,$=>{p({text:$,threadKey:y,turn:t})}):r(C)})},B=async(e,t)=>{const{agent:n,step:o}=e;n.onStepFinish&&await o.do(`agent:step-finish:${String(t.turn)}`,async()=>(await n.onStepFinish?.(t),!0))},$t=e=>({text:e.text,toolCalls:e.toolCalls.map(t=>({input:t.input,toolCallId:t.id,toolName:t.name})),...e.usage===void 0?{}:{usage:e.usage}}),D=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},Mt=e=>tt({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),Rt=async(e,t,n,o)=>{if(e.source===void 0)return;const a=h(e.source),{topK:r}=e,c=S("memory:retrieve",e.key),u=await n.do(c,async()=>o(a,{query:t,...r===void 0?{}:{topK:r}}));return D(u)},Kt=async(e,t,n,o,a,r)=>{if(n===void 0)return;const c=S("memory:traverse",e.key),u=await a.do(c,async()=>r(o,{owner:n,query:t,...Mt(e.graph)}));return D(u)},Et=async(e,t,n,o,a)=>{if(t===void 0)return;const r=S("memory:recall",e.key),c={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},u=await o.do(r,async()=>a(n,c));return D(u)},It=async(e,t)=>e.kind==="episodic"?Et(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?Kt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):Rt(e,t.input,t.step,t.run),Nt=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},Ot=async(e,t,n,o,a,r)=>{const c=Nt(P(e));if(c.length===0)return;const u=h(o.graphTraverse),i=h(o.episodeRecall),p=[];for(const s of c){const d=await It(s,{episodeRecall:i,graphTraverse:u,input:t,owner:n,run:r,step:a});d!==void 0&&p.push(d)}return p.length>0?p.join(`
|
|
2
|
-
|
|
3
|
-
`):void 0},At=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const d=at(t);if(d!==void 0)try{const l={assistantText:a,env:n,model:d.graph?.extractionModel??t.model,userInput:r},y=await s.do(S("memory:extract",d.key),async()=>o(l));await p(h(i.graphUpsert),{...y,messageKey:`${c}:${S("extract",d.key)}`,owner:u})}catch{}},_t=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s,threadKey:d}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const l=st(t);if(l!==void 0)try{const y={assistantText:a,env:n,model:l.episodic?.extractionModel??t.model,userInput:r},{summary:f}=await s.do(S("memory:episode",l.key),async()=>o(y));await p(h(i.episodeUpsert),{messageKey:`${c}:${S("episode",l.key)}`,owner:u,summary:f,threadKey:d})}catch{}},Ut=async(e,t,n)=>{const o=e[L(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},Pt="12 hours",Dt=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:Pt,type:`agent-dequeue:${t}:${n}`})},Ft=async(e,t,n)=>{const o=e.env[L(e.exportName)];if(!o||typeof o.get!="function")return;const a=o.get.bind(o);try{await e.step.do(`dequeue-wake:${n}`,async()=>(await(await a(n)).sendEvent({payload:{threadKey:t},type:`agent-dequeue:${t}:${n}`}),n))}catch{}},jt=async(e,t,n)=>{const{onReply:o}=e,{replyRef:a}=t.params;if(!(o===void 0||a===void 0))try{await t.step.do("agent:reply",async()=>(await o({env:t.env,replyRef:a,result:n,threadKey:t.params.threadKey}),a.channel))}catch{}},qt=async(e,t,n,o,a)=>{const{instanceId:r,persist:c}=e,u=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const i=n.output!==void 0&&n.text.length===0?b(n.output):n.text;return await c({content:i,messageKey:`${r}:assistant:${String(t)}`,role:"assistant"}),await B(e,{text:n.text,toolCalls:[],turn:t,...u}),{final:{stopped:"final",text:n.text,turns:t+1,...n.output===void 0?{}:{output:n.output}}}}await c({content:n.text,messageKey:`${r}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const i of n.toolCalls)await Tt(e,i);if(await B(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...u}),o.push($t(n)),a.length>0&&await dt(a,o))return"stopCondition"},Bt=async(e,t,n,o)=>{const a=[];let r,c=!1,u=0;for(let i=0;i<t;i+=1){const p=await Ct(e,i,a);o.value=pt(o.value,p.usage),u=i+1;const s=await qt(e,i,p,a,n);if(s==="stopCondition"){c=!0;break}if(s!==void 0){r=s.final;break}}return{final:r,stoppedByCondition:c,turnsRun:u}},Jt=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:r,extractGraph:c,generate:u,instanceId:i,onTokenDelta:p,params:s,paths:d,run:l,step:y,streamGenerate:f}=e,g=t.maxTurns??rt,w=ut(t.stopWhen),v=h(d.appendMessage),C=h(d.completeRun),$=h(d.ensureThread),A=h(d.listMessages),x=h(d.deleteMessage),M=h(d.patchThread),R=h(d.setState),T=h(d.state),K=async m=>{await l(v,{threadKey:s.threadKey,...m})},_=async m=>{await l(M,{key:s.threadKey,...m})},W=async m=>{await l(x,{messageKey:m,threadKey:s.threadKey})},z=async()=>{await K({content:s.input,messageKey:`${i}:user`,role:"user"})},E=async m=>{const N=await l(C,{instanceId:i,key:s.threadKey,...m});N?.dequeued!==void 0&&await Ft({env:o,exportName:a,step:y},s.threadKey,N.dequeued)},H=async()=>await l(T,{key:s.threadKey}),V=async m=>{await l(R,{key:s.threadKey,state:m})},U=await l($,{agent:a,instanceId:i,key:s.threadKey,...t.initialState===void 0?{}:{initialState:t.initialState},...t.onConcurrentRun===void 0?{}:{onConcurrentRun:t.onConcurrentRun},...s.owner===void 0?{}:{owner:s.owner},...s.title===void 0?{}:{title:s.title}});U?.outcome==="replaced"&&await Ut(o,a,U.priorInstanceId);const X=await Ot(t,s.input,s.owner,d,y,l),J=typeof t.instructions=="function"?t.instructions({env:o,input:s.input,threadKey:s.threadKey}):t.instructions,Q={agent:t,compact:n,depth:it(s.depth),env:o,generate:u,getState:H,instanceId:i,instructions:J,listMessages:A,memoryContext:X,onTokenDelta:p,owner:s.owner,deleteMessage:W,patchThread:_,persist:K,run:l,setState:V,step:y,streamGenerate:f,threadKey:s.threadKey,tools:t.tools??{}},I={value:void 0};try{U?.outcome==="queued"&&await Dt(y,s.threadKey,i),await z();const{final:m,stoppedByCondition:N,turnsRun:Y}=await Bt(Q,g,w,I),k=I.value===void 0?{}:{usage:I.value};return await At({agent:t,env:o,extractGraph:c,finalText:m?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:y}),await _t({agent:t,env:o,extractEpisode:r,finalText:m?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:y,threadKey:s.threadKey}),m?(await jt(t,{env:o,params:s,step:y},{...m,...k}),await E({status:"idle",...k}),{...m,...k}):N?(await E({status:"idle",...k}),{stopped:"stopCondition",turns:Y,...k}):(await E({error:`agent stopped: maxTurns (${String(g)}) reached`,status:"error",...k}),{stopped:"maxTurns",turns:g,...k})}catch(m){throw await ct(E,m,I.value),m}};export{ht as a,St as c,nt as i,Jt as r,kt as s};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as g,r as l,t as m}from"./common-CJSjtsfv.mjs";const d=(r,a)=>typeof r=="string"&&r.length>0?r:a,f=r=>{const{functionId:a,logger:n,recordInputs:c=!1,recordOutputs:u=!1}=r;return{executeLanguageModelCall:e=>n.traced(async t=>{c&&t.log({input:l(e,"messages"),model:l(e,"modelId")});const o=await e.execute();return u&&t.log({output:o}),o},{name:d(a,"language_model_call"),type:"llm"}),executeTool:e=>{const t=l(l(e,"toolCall"),"toolName");return n.traced(async o=>{c&&o.log({input:m(e),tool:t});const s=await e.execute();return u&&o.log({output:s}),s},{name:d(t,"execute_tool"),type:"tool"})},onError:e=>{n.traced(t=>{t.log({error:g(e)})},{name:"error",type:"error"})}}};export{f as braintrustTelemetry};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as d,isLunoraError as O}from"@lunora/errors";const $=(t,e,n)=>{if(e===void 0)return{dispose:()=>{},signal:t};const s=new AbortController,r=setTimeout(()=>{s.abort(n())},e);return{dispose:()=>{clearTimeout(r)},signal:s.signal}},a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",A=t=>{let e="",n=0;const s=t.length-2;for(;n<s;n+=3){const o=t[n]<<16|t[n+1]<<8|t[n+2];e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)+a.charAt(o>>6&63)+a.charAt(o&63)}const r=t.length-n;if(r===1){const o=t[n]<<16;e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)}else if(r===2){const o=t[n]<<16|t[n+1]<<8;e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)+a.charAt(o>>6&63)}return e};new TextDecoder;const w=new TextEncoder,m="=",R=t=>{for(let e=0;e<t.length;e+=1)if(t.charCodeAt(e)>255)return!1;return!0},S=t=>A(w.encode(JSON.stringify(t))),v=t=>!t.startsWith(m)&&R(t)?t:`${m}${A(w.encode(t))}`,L="/_lunora/scheduler/dispatch",_=3e4,x=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},T=Symbol("lunoraDispatchFailure"),D=Symbol("lunoraDispatchMessageId"),I=(t,e)=>(e!==void 0&&Object.defineProperty(t,D,{value:e}),t),U=(t,e)=>(Object.defineProperty(t,T,{value:!0}),I(t,e)),J=(t,e,n,s)=>{try{const r=JSON.parse(n)?.error;if(typeof r=="object"&&r!==null&&typeof r.code=="string"){const{code:o,data:u,message:h}=r;return U(new d(o,typeof h=="string"?h:void 0,{data:u,status:e}),s)}}catch{}return I(new d("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${n}`,{status:e}),s)},M=new Set([400,403,404,422]),P=new Set(["DISPATCH_UNAUTHENTICATED"]),j=t=>O(t)&&t[T]===!0&&M.has(t.status)&&!P.has(t.code),k=(t,e,n)=>new d("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(n)}ms`,{status:503}),K=t=>{const{label:e}=t,n=globalThis.fetch,s=t.fetchImpl??(typeof n=="function"?n.bind(globalThis):void 0);return async(r,o,u={})=>{if(typeof s!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const h=t.env.LUNORA_ORIGIN_URL;if(typeof h!="string"||h.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const f=t.env.LUNORA_ADMIN_TOKEN;if(typeof f!="string"||f.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const b=`${x(h)}${L}`,p={authorization:`Bearer ${f}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(p["x-lunora-userid"]=v(t.identity.userId)),t.identity?.claims!==void 0&&(p["x-lunora-identity"]=S(t.identity.claims));const y=u.timeoutMs??_,N=$(void 0,y,()=>new DOMException(`dispatch timed out after ${String(y)}ms`,"TimeoutError")),g=i=>{throw i instanceof Error&&i.name==="TimeoutError"?k(e,r.__lunoraRef,y):i};let c;try{try{c=await s(b,{body:JSON.stringify({args:o??{},functionPath:r.__lunoraRef,id:u.dedupId,shardKey:u.shardKey}),headers:p,method:"POST",signal:N.signal})}catch(l){return g(l)}if(!c.ok){let l;try{l=await c.text()}catch(E){return g(E)}throw J(e,c.status,l,u.messageId)}let i;try{i=await c.text()}catch(l){return g(l)}if(i.length===0)return;try{return JSON.parse(i)}catch{throw new d("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(c.status)}): ${i}`,{status:c.status})}}finally{N.dispose()}}};export{K as J,j as k};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{estimateModelCost as H}from"@lunora/ai";import{a as M,r as p,t as z,s as B,e as D,c as L}from"./common-CJSjtsfv.mjs";const V=e=>`${String(Math.round(e))}000000`,P=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0")),O=512,k=new Uint8Array(O);let w=O;const j=(e,t,o)=>{let s="";for(let n=0;n<o;n+=1)s+=P[e[t+n]];return s},C=e=>{if(e>O){const o=new Uint8Array(e);return crypto.getRandomValues(o),j(o,0,e)}w+e>O&&(crypto.getRandomValues(k),w=0);const t=j(k,w,e);return w+=e,t},N=(e,t)=>typeof t=="boolean"?{key:e,value:{boolValue:t}}:typeof t=="number"?Number.isFinite(t)?Number.isSafeInteger(t)?{key:e,value:{intValue:String(t)}}:{key:e,value:{doubleValue:t}}:{key:e,value:{stringValue:String(t)}}:{key:e,value:{stringValue:t}},F=(e,t,o)=>{const s={},n=new Map,f=(u,d)=>{const y=u.toLowerCase(),T=n.get(y);T===void 0?(n.set(y,u),s[u]=d):s[T]=d};for(const[u,d]of Object.entries(e))f(u,d);for(const[u,d]of Object.entries(t??{}))f(u,d);return o!==void 0&&o.length>0&&f("authorization",`Bearer ${o}`),s},J=e=>Array.isArray(e)?e:[e],Y=(e,t)=>{const o={"service.name":e};for(const[s,n]of Object.entries({}))o[s]=n;return Object.entries(o).map(([s,n])=>N(s,n))},q=(e,t,o,s)=>({resourceSpans:[{resource:{attributes:Y(o)},scopeSpans:[{scope:{name:t},spans:J(e)}]}]}),r=(e,t,o)=>{if(o!=null){if(typeof o=="boolean"||typeof o=="number"||typeof o=="string"){e.push(N(t,o));return}e.push(N(t,JSON.stringify(o)))}},R=(e,t)=>{(async()=>{let s;try{s=await e}catch(n){t(!1,n instanceof Error?n.message:String(n),void 0);return}t(!0,void 0,s)})().catch(()=>{})},X=e=>{const{conversationId:t,endpoint:o,headers:s,recordInputs:n=!1,recordOutputs:f=!1,token:u,traceId:d,waitUntil:y}=e,T=e.serviceName??"lunora";let b=o;for(;b.endsWith("/");)b=b.slice(0,-1);const $=`${b}/v1/traces`,E=F({"content-type":"application/json"},s,u),v=(i,h,c,g,I)=>{const _={attributes:I,endTimeUnixNano:V(Date.now()),kind:1,name:i,spanId:C(8),startTimeUnixNano:V(h),status:c?{code:1}:{code:2,message:g??""},traceId:d??C(16)};try{const x=fetch($,{body:JSON.stringify(q(_,"@lunora/agent",T)),headers:E,method:"POST"}).catch(()=>{});y?.(x)}catch{}};return{executeLanguageModelCall:i=>{const h=Date.now(),c=p(i,"modelId"),g=i.execute();return R(g,(_,x,l)=>{const a=[];r(a,"gen_ai.operation.name","chat"),r(a,"gen_ai.request.model",c),r(a,"gen_ai.system",p(i,"provider")),r(a,"gen_ai.conversation.id",t);const m=B(p(l,"usage"));m&&(r(a,"gen_ai.usage.input_tokens",m.inputTokens),r(a,"gen_ai.usage.output_tokens",m.outputTokens),r(a,"gen_ai.usage.total_tokens",m.totalTokens));const S=D(l);S&&(r(a,"gen_ai.response.cached",S.cached),r(a,"cf.aig.log_id",S.logId));const A=S?.cost,U=A??(typeof c=="string"?H(c,{inputTokens:m?.inputTokens,outputTokens:m?.outputTokens}):void 0);U!==void 0&&(r(a,"gen_ai.usage.cost",U),r(a,"lunora.usage.cost.source",A===void 0?"estimated":"provider")),n&&r(a,"gen_ai.prompt",p(i,"messages")),f&&r(a,"gen_ai.completion",L(p(l,"content"))),v(typeof c=="string"?`chat ${c}`:"language_model_call",h,_,x,a)}),g},executeTool:i=>{const h=Date.now(),c=M(i),g=i.execute();return R(g,(_,x)=>{const l=[];r(l,"gen_ai.operation.name","execute_tool"),r(l,"gen_ai.tool.name",c),r(l,"gen_ai.tool.call.id",p(i,"toolCallId")),n&&r(l,"gen_ai.tool.input",z(i)),v(typeof c=="string"?`execute_tool ${c}`:"execute_tool",h,_,x,l)}),g}}};export{X as otlpTelemetry};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as t,t as i}from"./common-CJSjtsfv.mjs";const l=(a,n)=>typeof a=="string"&&a.length>0?a:n,s=a=>{const{functionId:n,recordInputs:g=!1,Sentry:r}=a;return{executeLanguageModelCall:e=>{const o={"gen_ai.operation.name":l(n,"language_model_call"),"gen_ai.request.model":t(e,"modelId"),"gen_ai.system":t(e,"provider")};return g&&(o["gen_ai.prompt"]=t(e,"messages")),r.startSpan({attributes:o,name:l(n,"language_model_call"),op:"gen_ai.generate"},()=>e.execute())},executeTool:e=>{const o=t(t(e,"toolCall"),"toolName"),c={"gen_ai.operation.name":"execute_tool","gen_ai.tool.call.id":t(e,"toolCallId"),"gen_ai.tool.name":o};return g&&(c["gen_ai.tool.input"]=i(e)),r.startSpan({attributes:c,name:`execute_tool ${l(o,"tool")}`,op:"gen_ai.execute_tool"},()=>e.execute())},onError:e=>{r.captureException(e)}}};export{s as sentryTelemetry};
|