@lunora/agent 1.0.0-alpha.60 → 1.0.0-alpha.61
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/channels.d.mts +2 -2
- package/dist/channels.d.ts +2 -2
- package/dist/channels.mjs +1 -1
- package/dist/component.d.mts +1 -0
- package/dist/component.d.ts +1 -0
- package/dist/component.mjs +2 -2
- package/dist/inbound.d.mts +1 -1
- package/dist/inbound.d.ts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/AGENT_MODULE-M4D1EejI.mjs +1 -0
- package/dist/packem_shared/{VoiceSessionDO-A6u5NXI1.mjs → VoiceSessionDO-DPDIzZSY.mjs} +1 -1
- package/dist/packem_shared/{agentAsTool-D5iLpvYU.mjs → agentAsTool-DrFnh9UQ.mjs} +1 -1
- package/dist/packem_shared/codeTool-qdwj8j8S.mjs +1 -0
- package/dist/packem_shared/{collectAgenticMemoryTools-UE8gWzQU.mjs → collectAgenticMemoryTools-BeMWT2qt.mjs} +1 -1
- package/dist/packem_shared/{compileAgentWorkflow-BvkRUzx_.mjs → compileAgentWorkflow-DITp-XD6.mjs} +1 -1
- package/dist/packem_shared/component-shared-IZozysYq.mjs +1 -0
- package/dist/packem_shared/{createAgentContext-CfD3hIZ2.mjs → createAgentContext-VYm8bG12.mjs} +1 -1
- package/dist/packem_shared/createDispatchRunner-CH4tZsza-CJeRsY7-.mjs +1 -0
- package/dist/packem_shared/{defineAgent-Bqj9exe-.mjs → defineAgent-CZdh7y3W.mjs} +1 -1
- package/dist/packem_shared/{functionTool-DbrqDql3.mjs → functionTool-D3CP4f8-.mjs} +1 -1
- package/dist/packem_shared/{normalizeEntityName-bz1Thnmp.mjs → normalizeEntityName-Ce0X6Afj.mjs} +1 -1
- package/dist/packem_shared/runAgentLoop-KUUoFT3r.mjs +3 -0
- package/dist/packem_shared/{runVoiceTurn-PVWugRHc.mjs → runVoiceTurn-9zfLZi2_.mjs} +1 -1
- package/dist/packem_shared/{types.d-BoMo2eJj.d.mts → types.d-eCuvcLzf.d.mts} +21 -0
- package/dist/packem_shared/{types.d-BoMo2eJj.d.ts → types.d-eCuvcLzf.d.ts} +21 -0
- package/dist/packem_shared/{voice-turn-DXT1uMUn.mjs → voice-turn-CL9QCbEf.mjs} +1 -1
- package/dist/reply.d.mts +1 -1
- package/dist/reply.d.ts +1 -1
- package/dist/sandbox.d.mts +1 -1
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.mjs +1 -1
- package/dist/skill-markdown.d.mts +1 -1
- package/dist/skill-markdown.d.ts +1 -1
- package/package.json +3 -3
- package/dist/packem_shared/AGENT_MODULE-CLaSQy3P.mjs +0 -1
- package/dist/packem_shared/codeTool-B1_HVhnJ.mjs +0 -1
- package/dist/packem_shared/component-shared-Cn6E5d_q.mjs +0 -1
- package/dist/packem_shared/createDispatchRunner-CGafifJ7-C__lmjdK.mjs +0 -1
- package/dist/packem_shared/runAgentLoop-6fGTajbG.mjs +0 -3
package/dist/channels.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AgentDefinition } from "./packem_shared/types.d-
|
|
2
|
-
export type { I as InboundChannelEvent } from "./packem_shared/types.d-
|
|
1
|
+
import { A as AgentDefinition } from "./packem_shared/types.d-eCuvcLzf.mjs";
|
|
2
|
+
export type { I as InboundChannelEvent } from "./packem_shared/types.d-eCuvcLzf.mjs";
|
|
3
3
|
import '@lunora/mail/inbound';
|
|
4
4
|
import 'ai';
|
|
5
5
|
/**
|
package/dist/channels.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AgentDefinition } from "./packem_shared/types.d-
|
|
2
|
-
export type { I as InboundChannelEvent } from "./packem_shared/types.d-
|
|
1
|
+
import { A as AgentDefinition } from "./packem_shared/types.d-eCuvcLzf.js";
|
|
2
|
+
export type { I as InboundChannelEvent } from "./packem_shared/types.d-eCuvcLzf.js";
|
|
3
3
|
import '@lunora/mail/inbound';
|
|
4
4
|
import 'ai';
|
|
5
5
|
/**
|
package/dist/channels.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as
|
|
1
|
+
import{LunoraError as w}from"@lunora/errors";import{h as b,B as E}from"./packem_shared/branch-marker-boZ00zmk.mjs";const A=300,x=/[^0-9a-f]/iu,N=new TextEncoder,p=t=>new Uint8Array(N.encode(t)),v=t=>{if(t.length%2!==0||x.test(t))throw new w("BAD_REQUEST","@lunora/agent: malformed hex signature");const e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n+=1)e[n]=Number.parseInt(t.slice(n*2,n*2+2),16);return e},m=async(t,e,n)=>{try{const r=await crypto.subtle.importKey("raw",p(t),{hash:"SHA-256",name:"HMAC"},!1,["verify"]);return await crypto.subtle.verify("HMAC",r,v(n),p(e))}catch{return!1}},R=(t,e,n)=>Number.isFinite(t)&&Math.abs(e-t)<=n,S=async t=>{const{body:e,now:n=Date.now()/1e3,signature:r,signingSecret:s,timestamp:a,tolerance:o=A}=t;return!r||!a||!r.startsWith("v0=")||!R(Number(a),n,o)?!1:m(s,`v0:${a}:${e}`,r.slice(3))},k=async t=>{const{body:e,secret:n,signature:r}=t;return r?.startsWith("sha256=")?m(n,e,r.slice(7)):!1},T=async t=>{const{body:e,publicKey:n,signature:r,timestamp:s}=t;if(!r||!s)return!1;try{const a=await crypto.subtle.importKey("raw",v(n),{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify({name:"Ed25519"},a,v(r),p(s+e))}catch{return!1}},C=t=>{if(t.has("x-slack-signature"))return"slack";if(t.has("x-hub-signature-256"))return"github";if(t.has("x-signature-ed25519"))return"discord"},I=(t,e)=>{if(typeof t=="function")return t(e);const n=e[t];return typeof n=="string"?n:void 0},_=async(t,e,n,r)=>{switch(t){case"discord":return T({body:r,publicKey:e,signature:n.get("x-signature-ed25519")??void 0,timestamp:n.get("x-signature-timestamp")??void 0});case"github":return k({body:r,secret:e,signature:n.get("x-hub-signature-256")??void 0});case"slack":return S({body:r,signature:n.get("x-slack-signature")??void 0,signingSecret:e,timestamp:n.get("x-slack-request-timestamp")??void 0});default:return!1}},B=(t,e)=>{if(t==="discord")try{if(JSON.parse(e).type===1)return Response.json({type:1})}catch{}},h=t=>t.toString(16).padStart(4,"0"),D=t=>{let e=8997,n=33826,r=40164,s=52210;for(let a=0;a<t.length;a+=1){const o=t.codePointAt(a)??0;e^=o&65535,n^=o>>>16&65535;const c=e*435,i=n*435,d=r*435+e*256,g=s*435+n*256,u=i+(c>>>16),l=d+(u>>>16),f=g+(l>>>16);e=c&65535,n=u&65535,r=l&65535,s=f&65535}return h(s)+h(r)+h(n)+h(e)},H=/already[\s-]?exists/iu,y=()=>new Response(void 0,{status:200}),M=t=>H.test(t instanceof Error?t.message:String(t)),U=(t,e,n)=>{if(t==="github")return e.get("x-github-delivery")??void 0;try{const r=JSON.parse(n),s=t==="slack"?r.event_id:r.id;return typeof s=="string"?s:void 0}catch{return}},O=async(t,e,n,r)=>{if(b(e))throw new w("BAD_REQUEST",`@lunora/agent: inbound channel run params ${E}`);if(r===void 0||r==="")return await t.create({params:e}),y();try{await t.create({id:`${n}-${D(r)}`,params:e})}catch(s){if(M(s))return y();throw s}return y()},L=t=>async(e,n)=>{const r=await e.text(),s=C(e.headers);if(s===void 0)return new Response("Unrecognized webhook",{status:400});const a=t.map(i=>({config:i.agent.onInbound,target:i})).filter(i=>i.config?.channel===s),o={channel:s,headers:e.headers,json:()=>JSON.parse(r),rawBody:r};let c=!1;for(const{config:i,target:d}of a){const g=I(i.secret,n);if(g===void 0||!await _(s,g,e.headers,r))continue;c=!0;const u=B(s,r);if(u)return u;const l=await i.map(o);if(!l)continue;const f=n[d.binding];if(!f||typeof f.create!="function")throw new w("INTERNAL",`@lunora/agent: no Workflow binding "${d.binding}" on env for an inbound-channel agent — run codegen/dev so wrangler.jsonc declares it`);return await O(f,l,s,U(s,e.headers,r))}return c?new Response(void 0,{status:204}):new Response("Invalid signature",{status:401})};export{L as dispatchAgentChannel,M as isDuplicateInstanceError,T as verifyDiscord,k as verifyGithub,S as verifySlack};
|
package/dist/component.d.mts
CHANGED
|
@@ -73,6 +73,7 @@ interface AgentComponent {
|
|
|
73
73
|
functions: {
|
|
74
74
|
agentAppendMessage: AgentRegisteredFunction;
|
|
75
75
|
agentCompleteRun: AgentRegisteredFunction;
|
|
76
|
+
agentDeleteMessage: AgentRegisteredFunction;
|
|
76
77
|
agentEnsureThread: AgentRegisteredFunction;
|
|
77
78
|
agentEpisodeRecall: AgentRegisteredFunction;
|
|
78
79
|
agentEpisodeUpsert: AgentRegisteredFunction;
|
package/dist/component.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ interface AgentComponent {
|
|
|
73
73
|
functions: {
|
|
74
74
|
agentAppendMessage: AgentRegisteredFunction;
|
|
75
75
|
agentCompleteRun: AgentRegisteredFunction;
|
|
76
|
+
agentDeleteMessage: AgentRegisteredFunction;
|
|
76
77
|
agentEnsureThread: AgentRegisteredFunction;
|
|
77
78
|
agentEpisodeRecall: AgentRegisteredFunction;
|
|
78
79
|
agentEpisodeUpsert: AgentRegisteredFunction;
|
package/dist/component.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{LunoraError as
|
|
2
|
-
`)}});return{agentEpisodeRecall:f(o),agentEpisodeUpsert:f(u)}},$="threads",D="messages",M="run_queue",h=`${k}_${$}`,A=`${k}_${D}`,q=`${k}_${M}`,N=5,Z=780*60*1e3,ee=B(k,{tables:{[D]:v({content:e.string(),createdAt:e.number(),messageKey:e.string(),role:e.union(e.literal("user"),e.literal("assistant"),e.literal("tool"),e.literal("system")),seq:e.number(),status:e.optional(e.union(e.literal("awaiting_approval"),e.literal("approved"),e.literal("rejected"))),stepName:e.optional(e.string()),threadKey:e.string(),toolCallId:e.optional(e.string()),toolCalls:e.optional(e.array(e.object({id:e.string(),input:e.any(),name:e.string()}))),toolName:e.optional(e.string())}).index("byThread",["threadKey","seq"]).index("byMessageKey",["threadKey","messageKey"],{unique:!0}).public(),[$]:v({agent:e.string(),createdAt:e.number(),error:e.optional(e.string()),instanceId:e.optional(e.string()),key:e.string(),messageCount:e.number(),owner:e.optional(e.string()),state:e.optional(e.any()),status:e.union(e.literal("idle"),e.literal("running"),e.literal("error"),e.literal("cancelled"),e.literal("awaiting_input")),title:e.optional(e.string()),updatedAt:e.number(),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).index("byKey",["key"],{unique:!0}).index("byAgent",["agent"]).index("byInstance",["instanceId"]).public(),[M]:v({agent:e.string(),enqueuedAt:e.number(),instanceId:e.string(),position:e.number(),threadKey:e.string()}).index("byThread",["threadKey","position"]).index("byThreadInstance",["threadKey","instanceId"],{unique:!0}).public(),...P,...z}}),{mutation:g,query:_}=S.dataModel().create(),te=async(u,o,d)=>{if(o.instanceId===void 0)throw new I("CONFLICT",`@lunora/agent: thread "${o.key}" already has a run in flight (instance "${o.priorInstanceId}") — cannot queue a dispatch with no instance id`);const{instanceId:c}=o,m=await u.query(q).withIndex("byThreadInstance",w=>w.eq("threadKey",o.key).eq("instanceId",c)).first();if(m)return{outcome:"queued",position:m.position};const y=await u.query(q).withIndex("byThread",w=>w.eq("threadKey",o.key)).collect();if(y.length>=N)throw new I("CONFLICT",`@lunora/agent: thread "${o.key}" run queue is full (depth ${String(N)}) — rejecting instance "${c}"`);const b=(y.at(-1)?.position??-1)+1;return await u.insert(q,{agent:o.agent,enqueuedAt:d,instanceId:c,position:b,threadKey:o.key}),{outcome:"queued",position:b}},ne=async(u,o,d)=>{if(o.policy==="queue")return te(u,{agent:o.agent,instanceId:o.instanceId,key:o.key,priorInstanceId:o.priorInstanceId},d);if(o.policy!=="replace")throw new I("CONFLICT",`@lunora/agent: thread "${o.key}" already has a run in flight (instance "${o.priorInstanceId}") — onConcurrentRun="${o.policy}"`);return await u.patch(o.existingId,{error:void 0,status:"running",updatedAt:d,...o.instanceId===void 0?{}:{instanceId:o.instanceId}}),{outcome:"replaced",priorInstanceId:o.priorInstanceId}},se=()=>{const u=g.input({agent:e.string(),initialState:e.optional(e.any()),instanceId:e.optional(e.string()),key:e.string(),onConcurrentRun:e.optional(e.union(e.literal("reject"),e.literal("queue"),e.literal("replace"))),owner:e.optional(e.string()),title:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const a=Date.now(),i=await n.db.query(h).withIndex("byKey",r=>r.eq("key",t.key)).first();if(i){if(i.owner!==t.owner&&t.owner!==void 0)throw new Error(`@lunora/agent: thread "${t.key}" belongs to another owner`);const r=i.instanceId,s=typeof i.updatedAt=="number"?i.updatedAt:0;return!(a-s>Z)&&(i.status==="running"||i.status==="awaiting_input")&&r!==void 0&&(t.instanceId===void 0||t.instanceId!==r)?ne(n.db,{agent:t.agent,existingId:i._id,instanceId:t.instanceId,key:t.key,policy:t.onConcurrentRun??"reject",priorInstanceId:r},a):(await n.db.patch(i._id,{error:void 0,status:"running",updatedAt:a,...t.instanceId===void 0?{}:{instanceId:t.instanceId}}),{outcome:"continued"})}return await n.db.insert(h,{agent:t.agent,createdAt:a,key:t.key,messageCount:0,status:"running",updatedAt:a,...j({instanceId:t.instanceId,owner:t.owner,state:t.initialState,title:t.title})}),{outcome:"created"}}),o=g.input({content:e.string(),messageKey:e.string(),role:e.union(e.literal("user"),e.literal("assistant"),e.literal("tool"),e.literal("system")),status:e.optional(e.union(e.literal("awaiting_approval"),e.literal("approved"),e.literal("rejected"))),stepName:e.optional(e.string()),threadKey:e.string(),toolCallId:e.optional(e.string()),toolCalls:e.optional(e.array(e.object({id:e.string(),input:e.any(),name:e.string()}))),toolName:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(A).withIndex("byMessageKey",p=>p.eq("threadKey",t.threadKey).eq("messageKey",t.messageKey)).first();if(a)return{seq:a.seq};const i=await n.db.query(h).withIndex("byKey",p=>p.eq("key",t.threadKey)).first();if(!i)throw new Error(`@lunora/agent: cannot append to unknown thread "${t.threadKey}" — run agentEnsureThread first`);const r=i.messageCount,s=Date.now();return await n.db.insert(A,{content:t.content,createdAt:s,messageKey:t.messageKey,role:t.role,seq:r,threadKey:t.threadKey,...t.status===void 0?{}:{status:t.status},...t.stepName===void 0?{}:{stepName:t.stepName},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolCalls===void 0?{}:{toolCalls:t.toolCalls},...t.toolName===void 0?{}:{toolName:t.toolName}}),await n.db.patch(i._id,{messageCount:r+1,updatedAt:s}),{seq:r}}),d=g.input({error:e.optional(e.string()),instanceId:e.optional(e.string()),key:e.optional(e.string()),status:e.optional(e.union(e.literal("idle"),e.literal("running"),e.literal("error"),e.literal("cancelled"),e.literal("awaiting_input"))),title:e.optional(e.string()),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).mutation(async({args:t,ctx:n})=>{const{instanceId:a,key:i}=t;let r;i!==void 0?r=await n.db.query(h).withIndex("byKey",s=>s.eq("key",i)).first():a!==void 0&&(r=await n.db.query(h).withIndex("byInstance",s=>s.eq("instanceId",a)).first()),r&&await n.db.patch(r._id,{updatedAt:Date.now(),...t.error===void 0?{}:{error:t.error},...t.status===void 0?{}:{status:t.status},...t.title===void 0?{}:{title:t.title},...t.usage===void 0?{}:{usage:t.usage}})}),c=g.input({error:e.optional(e.string()),instanceId:e.string(),key:e.string(),status:e.union(e.literal("idle"),e.literal("error"),e.literal("cancelled")),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).mutation(async({args:t,ctx:n})=>{const a=Date.now(),i=await n.db.query(h).withIndex("byKey",l=>l.eq("key",t.key)).first();if(i?.instanceId!==t.instanceId){const l=await n.db.query(q).withIndex("byThreadInstance",E=>E.eq("threadKey",t.key).eq("instanceId",t.instanceId)).first();return l&&await n.db.delete(l._id),{}}const s=(await n.db.query(q).withIndex("byThread",l=>l.eq("threadKey",t.key)).collect())[0];if(!s)return await n.db.patch(i._id,{status:t.status,updatedAt:a,...t.error===void 0?{}:{error:t.error},...t.usage===void 0?{}:{usage:t.usage}}),{};const p=s.instanceId;return await n.db.delete(s._id),await n.db.patch(i._id,{instanceId:p,status:"running",updatedAt:a,...t.error===void 0?{}:{error:t.error},...t.usage===void 0?{}:{usage:t.usage}}),{dequeued:p}}),m=g.input({key:e.string(),state:e.any()}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(h).withIndex("byKey",i=>i.eq("key",t.key)).first();a&&await n.db.patch(a._id,{state:t.state,updatedAt:Date.now()})}),y=(t,n)=>{if(!t)return;const{owner:a}=t;if(!(a!==void 0&&a!==(n.userId??void 0)))return t},b=_.input({key:e.string()}).query(async({args:t,ctx:n})=>{const a=await n.db.query(h).withIndex("byKey",i=>i.eq("key",t.key)).first();return y(a,n.auth)}),w=_.input({key:e.string()}).query(async({args:t,ctx:n})=>{const a=await n.db.query(h).withIndex("byKey",i=>i.eq("key",t.key)).first();return y(a,n.auth)?.state}),O=_.input({key:e.string(),limit:e.optional(e.number())}).query(async({args:t,ctx:n})=>{const a=await n.db.query(h).withIndex("byKey",i=>i.eq("key",t.key)).first();return y(a,n.auth)===void 0?[]:t.limit!==void 0?(await n.db.query(A).withIndex("byThread",r=>r.eq("threadKey",t.key)).order("desc").take(t.limit)).toReversed():n.db.query(A).withIndex("byThread",i=>i.eq("threadKey",t.key)).collect()}),L=g.input({decision:e.union(e.literal("approve"),e.literal("reject")),instanceId:e.string(),note:e.optional(e.string()),threadKey:e.string(),toolCallId:e.string()}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(h).withIndex("byKey",l=>l.eq("key",t.threadKey)).first(),i=y(a,n.auth);if(i===void 0)throw new I("FORBIDDEN",`@lunora/agent: not allowed to resolve approvals on thread "${t.threadKey}"`);if(i.instanceId!==t.instanceId)throw new I("FORBIDDEN",`@lunora/agent: instance "${t.instanceId}" does not own thread "${t.threadKey}"`);const r=i.agent,{agents:s}=n,p=s?.[r];if(typeof p?.sendEvent!="function")throw new I("INTERNAL",`@lunora/agent: no ctx.agents["${r}"] producer to resolve the approval — run codegen/dev so the agent binding is wired`);return await p.sendEvent(t.instanceId,{payload:{decision:t.decision,toolCallId:t.toolCallId,...t.note===void 0?{}:{note:t.note}},type:`agent-approval:${t.toolCallId}`}),{resolved:!0}}),U=g.input({agent:e.string(),input:e.string(),threadKey:e.string(),title:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const{agents:a}=n,i=a?.[t.agent];if(typeof i?.run!="function")throw new I("INTERNAL",`@lunora/agent: no ctx.agents["${t.agent}"] producer to start a run — run codegen/dev so the agent binding is wired, and check the agent name`);if(i.publicRun!==!0)throw new I("FORBIDDEN",`@lunora/agent: agent "${t.agent}" is not enabled for public runs — set defineAgent({ publicRun: true }) to allow an external client (e.g. the @lunora/mcp server) to start it`);const r=n.auth.userId??void 0,s=await n.db.query(h).withIndex("byKey",l=>l.eq("key",t.threadKey)).first();if(s){const l=s.status,E=s.instanceId,T=s.owner;if((l==="running"||l==="awaiting_input")&&E!==void 0&&(T===void 0||T===r))return{id:E,threadKey:t.threadKey};if(T!==r&&r!==void 0)throw new I("FORBIDDEN",`@lunora/agent: thread "${t.threadKey}" belongs to another owner`)}const{id:p}=await i.run({input:t.input,threadKey:t.threadKey,...r===void 0?{}:{owner:r},...t.title===void 0?{}:{title:t.title}});return{id:p,threadKey:t.threadKey}}),C=F(),R=V();return{extension:ee,functions:{agentAppendMessage:f(o),agentCompleteRun:f(c),agentEnsureThread:f(u),agentEpisodeRecall:R.agentEpisodeRecall,agentEpisodeUpsert:R.agentEpisodeUpsert,agentGraphTraverse:C.agentGraphTraverse,agentGraphUpsert:C.agentGraphUpsert,agentMessages:O,agentPatchThread:f(d),agentResolveApproval:L,agentRun:U,agentSetState:f(m),agentState:w,agentThread:b}}};export{se as agentComponent,ee as agentExtension,ce as normalizeEntityName,pe as sandboxComponent};
|
|
1
|
+
import{LunoraError as g}from"@lunora/errors";import{defineTable as v,initLunora as D,defineSchemaExtension as j}from"@lunora/server";import{v as e}from"@lunora/values";import{a as f,A as k,c as P,d as F}from"./packem_shared/component-shared-IZozysYq.mjs";import{graphTables as G,graphComponent as H}from"./packem_shared/normalizeEntityName-Ce0X6Afj.mjs";import{normalizeEntityName as pe}from"./packem_shared/normalizeEntityName-Ce0X6Afj.mjs";import{sandboxComponent as we}from"./packem_shared/sandboxComponent-BtOkUYpY.mjs";const A="agent_episodes",X=5,Q=20,Y=500,x=200,z=/\s+/gu,V=u=>u===void 0||!Number.isFinite(u)?X:Math.min(Q,Math.max(1,Math.trunc(u))),W={episodes:v({createdAt:e.number(),messageKey:e.string(),owner:e.string(),summary:e.string(),threadKey:e.optional(e.string())}).index("byOwnerCreatedAt",["owner","createdAt"]).index("byOwnerMessageKey",["owner","messageKey"],{unique:!0}).public()},{mutation:J,query:Z}=D.dataModel().create(),ee=()=>{const u=J.input({createdAt:e.optional(e.number()),messageKey:e.string(),owner:e.string(),summary:e.string(),threadKey:e.optional(e.string())}).mutation(async({args:s,ctx:y})=>{const w=s.summary.replaceAll(z," ").trim().slice(0,Y);if(w.length===0)return{recorded:!1};if(await y.db.query(A).withIndex("byOwnerMessageKey",h=>h.eq("owner",s.owner).eq("messageKey",s.messageKey)).first())return{recorded:!1};await y.db.insert(A,{createdAt:s.createdAt??Date.now(),messageKey:s.messageKey,owner:s.owner,summary:w,...s.threadKey===void 0?{}:{threadKey:s.threadKey}});const m=await y.db.query(A).withIndex("byOwnerCreatedAt",h=>h.eq("owner",s.owner)).order("asc").take(x+1);for(const h of m.slice(0,Math.max(0,m.length-x)))await y.db.delete(h._id);return{recorded:!0}}),o=Z.input({limit:e.optional(e.number()),owner:e.string()}).query(async({args:s,ctx:y})=>{const w=await y.db.query(A).withIndex("byOwnerCreatedAt",I=>I.eq("owner",s.owner)).order("desc").take(V(s.limit));return w.length===0?{context:""}:{context:w.toReversed().map(I=>`- ${I.summary}`).join(`
|
|
2
|
+
`)}});return{agentEpisodeRecall:f(o),agentEpisodeUpsert:f(u)}},S="threads",$="messages",M="run_queue",p=`${k}_${S}`,K=`${k}_${$}`,E=`${k}_${M}`,N=5,te=780*60*1e3,ne=j(k,{tables:{[$]:v({content:e.string(),createdAt:e.number(),messageKey:e.string(),role:e.union(e.literal("user"),e.literal("assistant"),e.literal("tool"),e.literal("system")),seq:e.number(),status:e.optional(e.union(e.literal("awaiting_approval"),e.literal("approved"),e.literal("rejected"))),stepName:e.optional(e.string()),threadKey:e.string(),toolCallId:e.optional(e.string()),toolCalls:e.optional(e.array(e.object({id:e.string(),input:e.any(),name:e.string()}))),toolName:e.optional(e.string())}).index("byThread",["threadKey","seq"]).index("byMessageKey",["threadKey","messageKey"],{unique:!0}).public(),[S]:v({agent:e.string(),createdAt:e.number(),error:e.optional(e.string()),instanceId:e.optional(e.string()),key:e.string(),messageCount:e.number(),owner:e.optional(e.string()),state:e.optional(e.any()),status:e.union(e.literal("idle"),e.literal("running"),e.literal("error"),e.literal("cancelled"),e.literal("awaiting_input")),title:e.optional(e.string()),updatedAt:e.number(),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).index("byKey",["key"],{unique:!0}).index("byAgent",["agent"]).index("byInstance",["instanceId"]).public(),[M]:v({agent:e.string(),enqueuedAt:e.number(),instanceId:e.string(),position:e.number(),threadKey:e.string()}).index("byThread",["threadKey","position"]).index("byThreadInstance",["threadKey","instanceId"],{unique:!0}).public(),...G,...W}}),{mutation:b,query:T}=D.dataModel().create(),ie=async(u,o,s)=>{if(o.instanceId===void 0)throw new g("CONFLICT",`@lunora/agent: thread "${o.key}" already has a run in flight (instance "${o.priorInstanceId}") — cannot queue a dispatch with no instance id`);const{instanceId:y}=o,w=await u.query(E).withIndex("byThreadInstance",h=>h.eq("threadKey",o.key).eq("instanceId",y)).first();if(w)return{outcome:"queued",position:w.position};const I=await u.query(E).withIndex("byThread",h=>h.eq("threadKey",o.key)).collect();if(I.length>=N)throw new g("CONFLICT",`@lunora/agent: thread "${o.key}" run queue is full (depth ${String(N)}) — rejecting instance "${y}"`);const m=(I.at(-1)?.position??-1)+1;return await u.insert(E,{agent:o.agent,enqueuedAt:s,instanceId:y,position:m,threadKey:o.key}),{outcome:"queued",position:m}},ae=async(u,o,s)=>{if(o.policy==="queue")return ie(u,{agent:o.agent,instanceId:o.instanceId,key:o.key,priorInstanceId:o.priorInstanceId},s);if(o.policy!=="replace")throw new g("CONFLICT",`@lunora/agent: thread "${o.key}" already has a run in flight (instance "${o.priorInstanceId}") — onConcurrentRun="${o.policy}"`);return await u.patch(o.existingId,{error:void 0,status:"running",updatedAt:s,...o.instanceId===void 0?{}:{instanceId:o.instanceId}}),{outcome:"replaced",priorInstanceId:o.priorInstanceId}},le=()=>{const u=b.input({agent:e.string(),initialState:e.optional(e.any()),instanceId:e.optional(e.string()),key:e.string(),onConcurrentRun:e.optional(e.union(e.literal("reject"),e.literal("queue"),e.literal("replace"))),owner:e.optional(e.string()),title:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const a=Date.now(),i=await n.db.query(p).withIndex("byKey",r=>r.eq("key",t.key)).first();if(i){if(i.owner!==t.owner&&t.owner!==void 0)throw new Error(`@lunora/agent: thread "${t.key}" belongs to another owner`);const r=i.instanceId,d=typeof i.updatedAt=="number"?i.updatedAt:0,c=i.status==="awaiting_input"?P:te;return!(a-d>c)&&(i.status==="running"||i.status==="awaiting_input")&&r!==void 0&&(t.instanceId===void 0||t.instanceId!==r)?ae(n.db,{agent:t.agent,existingId:i._id,instanceId:t.instanceId,key:t.key,policy:t.onConcurrentRun??"reject",priorInstanceId:r},a):(await n.db.patch(i._id,{error:void 0,status:"running",updatedAt:a,...t.instanceId===void 0?{}:{instanceId:t.instanceId}}),{outcome:"continued"})}return await n.db.insert(p,{agent:t.agent,createdAt:a,key:t.key,messageCount:0,status:"running",updatedAt:a,...F({instanceId:t.instanceId,owner:t.owner,state:t.initialState,title:t.title})}),{outcome:"created"}}),o=b.input({content:e.string(),messageKey:e.string(),role:e.union(e.literal("user"),e.literal("assistant"),e.literal("tool"),e.literal("system")),status:e.optional(e.union(e.literal("awaiting_approval"),e.literal("approved"),e.literal("rejected"))),stepName:e.optional(e.string()),threadKey:e.string(),toolCallId:e.optional(e.string()),toolCalls:e.optional(e.array(e.object({id:e.string(),input:e.any(),name:e.string()}))),toolName:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(K).withIndex("byMessageKey",c=>c.eq("threadKey",t.threadKey).eq("messageKey",t.messageKey)).first();if(a)return{seq:a.seq};const i=await n.db.query(p).withIndex("byKey",c=>c.eq("key",t.threadKey)).first();if(!i)throw new Error(`@lunora/agent: cannot append to unknown thread "${t.threadKey}" — run agentEnsureThread first`);const r=i.messageCount,d=Date.now();return await n.db.insert(K,{content:t.content,createdAt:d,messageKey:t.messageKey,role:t.role,seq:r,threadKey:t.threadKey,...t.status===void 0?{}:{status:t.status},...t.stepName===void 0?{}:{stepName:t.stepName},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolCalls===void 0?{}:{toolCalls:t.toolCalls},...t.toolName===void 0?{}:{toolName:t.toolName}}),await n.db.patch(i._id,{messageCount:r+1,updatedAt:d}),{seq:r}}),s=b.input({messageKey:e.string(),threadKey:e.string()}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(K).withIndex("byMessageKey",i=>i.eq("threadKey",t.threadKey).eq("messageKey",t.messageKey)).first();a&&await n.db.delete(a._id)}),y=b.input({error:e.optional(e.string()),instanceId:e.optional(e.string()),key:e.optional(e.string()),status:e.optional(e.union(e.literal("idle"),e.literal("running"),e.literal("error"),e.literal("cancelled"),e.literal("awaiting_input"))),title:e.optional(e.string()),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).mutation(async({args:t,ctx:n})=>{const{instanceId:a,key:i}=t;let r;i!==void 0?r=await n.db.query(p).withIndex("byKey",d=>d.eq("key",i)).first():a!==void 0&&(r=await n.db.query(p).withIndex("byInstance",d=>d.eq("instanceId",a)).first()),r&&await n.db.patch(r._id,{updatedAt:Date.now(),...t.error===void 0?{}:{error:t.error},...t.status===void 0?{}:{status:t.status},...t.title===void 0?{}:{title:t.title},...t.usage===void 0?{}:{usage:t.usage}})}),w=b.input({error:e.optional(e.string()),instanceId:e.string(),key:e.string(),status:e.union(e.literal("idle"),e.literal("error"),e.literal("cancelled")),usage:e.optional(e.object({inputTokens:e.optional(e.number()),outputTokens:e.optional(e.number()),totalTokens:e.optional(e.number())}))}).mutation(async({args:t,ctx:n})=>{const a=Date.now(),i=await n.db.query(p).withIndex("byKey",l=>l.eq("key",t.key)).first();if(i?.instanceId!==t.instanceId){const l=await n.db.query(E).withIndex("byThreadInstance",q=>q.eq("threadKey",t.key).eq("instanceId",t.instanceId)).first();return l&&await n.db.delete(l._id),{}}const d=(await n.db.query(E).withIndex("byThread",l=>l.eq("threadKey",t.key)).collect())[0];if(!d)return await n.db.patch(i._id,{status:t.status,updatedAt:a,...t.error===void 0?{}:{error:t.error},...t.usage===void 0?{}:{usage:t.usage}}),{};const c=d.instanceId;return await n.db.delete(d._id),await n.db.patch(i._id,{instanceId:c,status:"running",updatedAt:a,...t.error===void 0?{}:{error:t.error},...t.usage===void 0?{}:{usage:t.usage}}),{dequeued:c}}),I=b.input({key:e.string(),state:e.any()}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(p).withIndex("byKey",i=>i.eq("key",t.key)).first();a&&await n.db.patch(a._id,{state:t.state,updatedAt:Date.now()})}),m=(t,n)=>{if(!t)return;const{owner:a}=t;if(!(a!==void 0&&a!==(n.userId??void 0)))return t},h=T.input({key:e.string()}).query(async({args:t,ctx:n})=>{const a=await n.db.query(p).withIndex("byKey",i=>i.eq("key",t.key)).first();return m(a,n.auth)}),O=T.input({key:e.string()}).query(async({args:t,ctx:n})=>{const a=await n.db.query(p).withIndex("byKey",i=>i.eq("key",t.key)).first();return m(a,n.auth)?.state}),L=T.input({key:e.string(),limit:e.optional(e.number())}).query(async({args:t,ctx:n})=>{const a=await n.db.query(p).withIndex("byKey",i=>i.eq("key",t.key)).first();return m(a,n.auth)===void 0?[]:t.limit!==void 0?(await n.db.query(K).withIndex("byThread",r=>r.eq("threadKey",t.key)).order("desc").take(t.limit)).toReversed():n.db.query(K).withIndex("byThread",i=>i.eq("threadKey",t.key)).collect()}),U=b.input({decision:e.union(e.literal("approve"),e.literal("reject")),instanceId:e.string(),note:e.optional(e.string()),threadKey:e.string(),toolCallId:e.string()}).mutation(async({args:t,ctx:n})=>{const a=await n.db.query(p).withIndex("byKey",l=>l.eq("key",t.threadKey)).first(),i=m(a,n.auth);if(i===void 0)throw new g("FORBIDDEN",`@lunora/agent: not allowed to resolve approvals on thread "${t.threadKey}"`);if(i.instanceId!==t.instanceId)throw new g("FORBIDDEN",`@lunora/agent: instance "${t.instanceId}" does not own thread "${t.threadKey}"`);const r=i.agent,{agents:d}=n,c=d?.[r];if(typeof c?.sendEvent!="function")throw new g("INTERNAL",`@lunora/agent: no ctx.agents["${r}"] producer to resolve the approval — run codegen/dev so the agent binding is wired`);return await c.sendEvent(t.instanceId,{payload:{decision:t.decision,toolCallId:t.toolCallId,...t.note===void 0?{}:{note:t.note}},type:`agent-approval:${t.toolCallId}`}),{resolved:!0}}),B=b.input({agent:e.string(),input:e.string(),threadKey:e.string(),title:e.optional(e.string())}).mutation(async({args:t,ctx:n})=>{const{agents:a}=n,i=a?.[t.agent];if(typeof i?.run!="function")throw new g("INTERNAL",`@lunora/agent: no ctx.agents["${t.agent}"] producer to start a run — run codegen/dev so the agent binding is wired, and check the agent name`);if(i.publicRun!==!0)throw new g("FORBIDDEN",`@lunora/agent: agent "${t.agent}" is not enabled for public runs — set defineAgent({ publicRun: true }) to allow an external client (e.g. the @lunora/mcp server) to start it`);const r=n.auth.userId??void 0,d=await n.db.query(p).withIndex("byKey",l=>l.eq("key",t.threadKey)).first();if(d){const l=d.status,q=d.instanceId,_=d.owner;if((l==="running"||l==="awaiting_input")&&q!==void 0&&(_===void 0||_===r))return{id:q,threadKey:t.threadKey};if(_!==r&&r!==void 0)throw new g("FORBIDDEN",`@lunora/agent: thread "${t.threadKey}" belongs to another owner`)}const{id:c}=await i.run({input:t.input,threadKey:t.threadKey,...r===void 0?{}:{owner:r},...t.title===void 0?{}:{title:t.title}});return{id:c,threadKey:t.threadKey}}),C=H(),R=ee();return{extension:ne,functions:{agentAppendMessage:f(o),agentCompleteRun:f(w),agentEnsureThread:f(u),agentEpisodeRecall:R.agentEpisodeRecall,agentEpisodeUpsert:R.agentEpisodeUpsert,agentGraphTraverse:C.agentGraphTraverse,agentGraphUpsert:C.agentGraphUpsert,agentMessages:L,agentDeleteMessage:f(s),agentPatchThread:f(y),agentResolveApproval:U,agentRun:B,agentSetState:f(I),agentState:O,agentThread:h}}};export{le as agentComponent,ne as agentExtension,pe as normalizeEntityName,we as sandboxComponent};
|
package/dist/inbound.d.mts
CHANGED
package/dist/inbound.d.ts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AgentDefinition, e as AgentCompact, f as AgentEpisodeExtract, g as AgentGraphExtract, h as AgentGenerate, i as AgentTokenSink, j as AgentRunInput, k as AgentFunctionPaths, l as AgentRunFunction, m as AgentStepLike, n as AgentStreamGenerate, o as AgentRunResult, p as AgentMessageRow, q as AgentConfig, d as SkillDefinition, r as AnyAgentTool, s as AgentAsToolOptions, t as AgentSubToolInput, c as AgentToolDefinition, u as AgentBindingSpec, v as AgentHandle, w as AgentToolConfig, x as AgentFunctionReference, y as AgentModelInput, z as SkillConfig } from "./packem_shared/types.d-
|
|
2
|
-
export type { B as AgentApprovalContext, C as AgentEmailMapper, D as AgentEmailRun, E as AgentGenerateOptions, F as AgentGenerateResult, G as AgentInstructionsContext, H as AgentLiveEvent, J as AgentMemoryOptions, K as AgentMemorySource, L as AgentMessageStatus, M as AgentOnReply, N as AgentOnStepFinish, O as AgentPrepareStep, P as AgentPrepareStepInput, Q as AgentPrepareStepResult, R as AgentProgressEvent, T as AgentReplyInfo, a as AgentReplyRef, U as AgentRunHandle, V as AgentStepFinishInfo, W as AgentStepInfo, X as AgentThreadStatus, Y as AgentTokenDelta, Z as AgentToolCall, b as AgentToolContext, _ as AgentUsage, $ as AgentVoiceConfig, a0 as AgentWorkflowBindingLike, a1 as AgentWorkflowInstanceLike, a2 as EnsureThreadOutcome } from "./packem_shared/types.d-
|
|
1
|
+
import { A as AgentDefinition, e as AgentCompact, f as AgentEpisodeExtract, g as AgentGraphExtract, h as AgentGenerate, i as AgentTokenSink, j as AgentRunInput, k as AgentFunctionPaths, l as AgentRunFunction, m as AgentStepLike, n as AgentStreamGenerate, o as AgentRunResult, p as AgentMessageRow, q as AgentConfig, d as SkillDefinition, r as AnyAgentTool, s as AgentAsToolOptions, t as AgentSubToolInput, c as AgentToolDefinition, u as AgentBindingSpec, v as AgentHandle, w as AgentToolConfig, x as AgentFunctionReference, y as AgentModelInput, z as SkillConfig } from "./packem_shared/types.d-eCuvcLzf.mjs";
|
|
2
|
+
export type { B as AgentApprovalContext, C as AgentEmailMapper, D as AgentEmailRun, E as AgentGenerateOptions, F as AgentGenerateResult, G as AgentInstructionsContext, H as AgentLiveEvent, J as AgentMemoryOptions, K as AgentMemorySource, L as AgentMessageStatus, M as AgentOnReply, N as AgentOnStepFinish, O as AgentPrepareStep, P as AgentPrepareStepInput, Q as AgentPrepareStepResult, R as AgentProgressEvent, T as AgentReplyInfo, a as AgentReplyRef, U as AgentRunHandle, V as AgentStepFinishInfo, W as AgentStepInfo, X as AgentThreadStatus, Y as AgentTokenDelta, Z as AgentToolCall, b as AgentToolContext, _ as AgentUsage, $ as AgentVoiceConfig, a0 as AgentWorkflowBindingLike, a1 as AgentWorkflowInstanceLike, a2 as EnsureThreadOutcome } from "./packem_shared/types.d-eCuvcLzf.mjs";
|
|
3
3
|
export { type AgentComponent, agentComponent, agentExtension } from "./component.mjs";
|
|
4
4
|
import { FlexibleSchema, LanguageModel, ModelMessage } from 'ai';
|
|
5
5
|
export { agentBindingName, agentClassName, agentDefaultName, voiceBindingName, voiceClassName } from "./naming.mjs";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AgentDefinition, e as AgentCompact, f as AgentEpisodeExtract, g as AgentGraphExtract, h as AgentGenerate, i as AgentTokenSink, j as AgentRunInput, k as AgentFunctionPaths, l as AgentRunFunction, m as AgentStepLike, n as AgentStreamGenerate, o as AgentRunResult, p as AgentMessageRow, q as AgentConfig, d as SkillDefinition, r as AnyAgentTool, s as AgentAsToolOptions, t as AgentSubToolInput, c as AgentToolDefinition, u as AgentBindingSpec, v as AgentHandle, w as AgentToolConfig, x as AgentFunctionReference, y as AgentModelInput, z as SkillConfig } from "./packem_shared/types.d-
|
|
2
|
-
export type { B as AgentApprovalContext, C as AgentEmailMapper, D as AgentEmailRun, E as AgentGenerateOptions, F as AgentGenerateResult, G as AgentInstructionsContext, H as AgentLiveEvent, J as AgentMemoryOptions, K as AgentMemorySource, L as AgentMessageStatus, M as AgentOnReply, N as AgentOnStepFinish, O as AgentPrepareStep, P as AgentPrepareStepInput, Q as AgentPrepareStepResult, R as AgentProgressEvent, T as AgentReplyInfo, a as AgentReplyRef, U as AgentRunHandle, V as AgentStepFinishInfo, W as AgentStepInfo, X as AgentThreadStatus, Y as AgentTokenDelta, Z as AgentToolCall, b as AgentToolContext, _ as AgentUsage, $ as AgentVoiceConfig, a0 as AgentWorkflowBindingLike, a1 as AgentWorkflowInstanceLike, a2 as EnsureThreadOutcome } from "./packem_shared/types.d-
|
|
1
|
+
import { A as AgentDefinition, e as AgentCompact, f as AgentEpisodeExtract, g as AgentGraphExtract, h as AgentGenerate, i as AgentTokenSink, j as AgentRunInput, k as AgentFunctionPaths, l as AgentRunFunction, m as AgentStepLike, n as AgentStreamGenerate, o as AgentRunResult, p as AgentMessageRow, q as AgentConfig, d as SkillDefinition, r as AnyAgentTool, s as AgentAsToolOptions, t as AgentSubToolInput, c as AgentToolDefinition, u as AgentBindingSpec, v as AgentHandle, w as AgentToolConfig, x as AgentFunctionReference, y as AgentModelInput, z as SkillConfig } from "./packem_shared/types.d-eCuvcLzf.js";
|
|
2
|
+
export type { B as AgentApprovalContext, C as AgentEmailMapper, D as AgentEmailRun, E as AgentGenerateOptions, F as AgentGenerateResult, G as AgentInstructionsContext, H as AgentLiveEvent, J as AgentMemoryOptions, K as AgentMemorySource, L as AgentMessageStatus, M as AgentOnReply, N as AgentOnStepFinish, O as AgentPrepareStep, P as AgentPrepareStepInput, Q as AgentPrepareStepResult, R as AgentProgressEvent, T as AgentReplyInfo, a as AgentReplyRef, U as AgentRunHandle, V as AgentStepFinishInfo, W as AgentStepInfo, X as AgentThreadStatus, Y as AgentTokenDelta, Z as AgentToolCall, b as AgentToolContext, _ as AgentUsage, $ as AgentVoiceConfig, a0 as AgentWorkflowBindingLike, a1 as AgentWorkflowInstanceLike, a2 as EnsureThreadOutcome } from "./packem_shared/types.d-eCuvcLzf.js";
|
|
3
3
|
export { type AgentComponent, agentComponent, agentExtension } from "./component.js";
|
|
4
4
|
import { FlexibleSchema, LanguageModel, ModelMessage } from 'ai';
|
|
5
5
|
export { agentBindingName, agentClassName, agentDefaultName, voiceBindingName, voiceClassName } from "./naming.js";
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{runAgentLoop as t,splitForCompaction as r}from"./packem_shared/runAgentLoop-
|
|
1
|
+
import{runAgentLoop as t,splitForCompaction as r}from"./packem_shared/runAgentLoop-KUUoFT3r.mjs";import{collectAgenticMemoryTools as a,toSearchResults as i}from"./packem_shared/collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as l}from"./packem_shared/agentAsTool-DrFnh9UQ.mjs";import{codeTool as p}from"./packem_shared/codeTool-qdwj8j8S.mjs";import{agentComponent as c,agentExtension as x}from"./component.mjs";import{default as A}from"./packem_shared/createAgentContext-VYm8bG12.mjs";import{defineAgent as d,defineAgentTool as u,isAgentDefinition as N}from"./packem_shared/defineAgent-CZdh7y3W.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-9bZ2YhpN.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-DPDIzZSY.mjs";import{r as oe}from"./packem_shared/voice-turn-CL9QCbEf.mjs";import{default as re}from"./packem_shared/compileAgentWorkflow-DITp-XD6.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,p 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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e="agents",a="sandbox",n=`${a}:invoke`,s={appendMessage:`${e}:agentAppendMessage`,completeRun:`${e}:agentCompleteRun`,deleteMessage:`${e}:agentDeleteMessage`,ensureThread:`${e}:agentEnsureThread`,episodeRecall:`${e}:agentEpisodeRecall`,episodeUpsert:`${e}:agentEpisodeUpsert`,graphTraverse:`${e}:agentGraphTraverse`,graphUpsert:`${e}:agentGraphUpsert`,listMessages:`${e}:agentMessages`,patchThread:`${e}:agentPatchThread`,run:`${e}:agentRun`,setState:`${e}:agentSetState`,state:`${e}:agentState`},r=t=>typeof t=="string"?{__lunoraRef:t}:t;export{e as AGENT_MODULE,s as DEFAULT_AGENT_FUNCTION_PATHS,n as SANDBOX_INVOKE_PATH,a as SANDBOX_MODULE,r as toFunctionReference};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createAi as g}from"@lunora/ai";import{
|
|
1
|
+
import{createAi as g}from"@lunora/ai";import{F as b}from"./createDispatchRunner-CH4tZsza-CJeRsY7-.mjs";import{t as m}from"./base64-5eyBfWO3.mjs";import{p as A,d as S,a as v,i as l,b as f,c as w,e as k,f as x,r as T,t as E}from"./voice-turn-CL9QCbEf.mjs";import{createStreamGenerate as M}from"./createAgentGenerate-9bZ2YhpN.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as B,toFunctionReference as p}from"./AGENT_MODULE-M4D1EejI.mjs";const _="@cf/openai/whisper-large-v3-turbo",I="@cf/deepgram/aura-1",U=8*1024*1024,F=256*1024,y=15,D=5e3;class O{agent;ai;env;exportName;paths;streamGenerate;sttModel;ttsModel;audioBuffers=new Map;bufferedBytes=new Map;controllers=new Map;state;constructor(t,e,s,r){this.state=t,this.env=e,this.agent=s,this.exportName=r,this.paths=B,this.ai=g({binding:e.AI,env:e}),this.streamGenerate=M(s,e),this.sttModel=s.voice?.stt??_,this.ttsModel=s.voice?.tts??I}fetch(t){if(t.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{status:426});const s=new URL(t.url).searchParams.get("threadKey");if(!s)return new Response("Missing threadKey",{status:400});const r=globalThis.WebSocketPair,i=new r,n=i[0],o=i[1];this.state.acceptWebSocket(o);const c=crypto.randomUUID(),d=A(t.headers.get("x-lunora-identity")),a=S(t.headers.get("x-lunora-userid")),h=v(t.headers.get("x-lunora-identity-exp"));if(l(h))return f(o),new Response(null,{status:101,webSocket:n});o.serializeAttachment?.({connectionId:c,threadKey:s,turn:0,...h===void 0?{}:{expiresAt:h},...d===void 0?{}:{identity:d},...a===void 0?{}:{userId:a}}),this.send(o,{audioFormat:this.agent.voice?.audioFormat??"mp3",type:"ready"});const u=this.agent.voice?.greeting;return u&&u.length>0&&this.state.waitUntil?.(this.speakGreeting(o,c,s,a,d,u)),new Response(null,{status:101,webSocket:n})}async webSocketMessage(t,e){const s=t.deserializeAttachment?.();if(s){if(l(s.expiresAt)){f(t);return}try{if(typeof e=="string"){await this.handleControl(t,s,e);return}this.bufferAudio(s.connectionId,new Uint8Array(e),t)}catch(r){this.send(t,{message:r instanceof Error?r.message:String(r),type:"error"})}}}webSocketClose(t){this.cleanupSocket(t)}webSocketError(t){this.cleanupSocket(t)}resolveRun(t,e){const s=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",...s===void 0?{}:{identity:s}})}async transcribe(t){const e=w(t);return k(await this.ai.run(this.sttModel,{audio:m(e)}))}async synthesize(t,e){const s=this.agent.voice?.speaker;return x(await this.ai.run(this.ttsModel,{text:t,...s===void 0?{}:{speaker:s}},e===void 0?void 0:{signal:e}))}async handleControl(t,e,s){let r;try{r=JSON.parse(s)}catch{return}if(r.type==="interrupt"){this.controllers.get(e.connectionId)?.abort();return}if(this.controllers.has(e.connectionId)){this.send(t,{message:"a turn is already in progress — send an interrupt before the next utterance",type:"error"});return}if(r.type==="commit"){const i=this.drainAudio(e.connectionId);await this.runTurn(t,e,{pcm:i});return}await this.runTurn(t,e,{text:r.text})}bufferAudio(t,e,s){const r=(this.bufferedBytes.get(t)??0)+e.byteLength;if(r>U){this.audioBuffers.delete(t),this.bufferedBytes.delete(t),this.send(s,{message:"utterance exceeded the maximum buffer — send a commit sooner",type:"error"});return}const i=this.audioBuffers.get(t)??[];i.push(e),this.audioBuffers.set(t,i),this.bufferedBytes.set(t,r)}drainAudio(t){const e=this.audioBuffers.get(t)??[];this.audioBuffers.delete(t),this.bufferedBytes.delete(t);const s=e.reduce((n,o)=>n+o.byteLength,0),r=new Uint8Array(s);let i=0;for(const n of e)r.set(n,i),i+=n.byteLength;return r}async runTurn(t,e,s){const r=new AbortController;this.controllers.set(e.connectionId,r);try{await T({agent:this.agent,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:r.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},...s.pcm===void 0?{}:{pcm:s.pcm},...s.text===void 0?{}:{text:s.text}})}finally{this.controllers.get(e.connectionId)===r&&this.controllers.delete(e.connectionId),t.serializeAttachment?.({...e,turn:e.turn+1})}}async speakGreeting(t,e,s,r,i,n){const o=this.resolveRun(r,i),c=new AbortController,d=()=>c.signal.aborted;this.controllers.set(e,c);try{await o(p(this.paths.ensureThread),{agent:this.exportName,key:s,...this.agent.initialState===void 0?{}:{initialState:this.agent.initialState},...r===void 0?{}:{owner:r}});for await(const a of E(await this.synthesizeWithSignal(n,c.signal))){if(d()||(await this.waitForSocketDrain(t),d()))break;this.sendAudio(t,a)}d()||(await o(p(this.paths.appendMessage),{content:n,messageKey:"voice:greeting:assistant",role:"assistant",threadKey:s}),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))}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 s=0;for(;typeof e.bufferedAmount=="number"&&e.bufferedAmount>F&&s<D;)await new Promise(r=>{setTimeout(r,y)}),s+=y}}export{O as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as d}from"@lunora/errors";import{jsonSchema as y}from"ai";import{isDuplicateInstanceError as A}from"../channels.mjs";import{agentBindingName as L}from"../naming.mjs";import{toFunctionReference as N,DEFAULT_AGENT_FUNCTION_PATHS as b}from"./AGENT_MODULE-
|
|
1
|
+
import{LunoraError as d}from"@lunora/errors";import{jsonSchema as y}from"ai";import{isDuplicateInstanceError as A}from"../channels.mjs";import{agentBindingName as L}from"../naming.mjs";import{toFunctionReference as N,DEFAULT_AGENT_FUNCTION_PATHS as b}from"./AGENT_MODULE-M4D1EejI.mjs";const E=new Set(["complete","errored","terminated"]),I=120,S=500,$=t=>t!==null&&typeof t=="object"&&typeof t.status=="string"?t.status:"unknown",_=async t=>{await new Promise(e=>{setTimeout(e,t)})},M=async(t,e,n,c)=>{for(let a=0;a<e;a+=1){const i=$(await t.status());if(E.has(i))return i;await c(n)}return"timeout"},P=t=>{for(let e=t.length-1;e>=0;e-=1){const n=t[e];if(n?.role==="assistant"&&(n.toolCalls===void 0||n.toolCalls.length===0))return n.content}return""},k=t=>{if(typeof t.name!="string"||t.name.length===0)throw new d("INTERNAL","@lunora/agent: agent.asTool requires a `name` (the child agent's export name, selecting its AGENT_* binding)");if(typeof t.description!="string"||t.description.length===0)throw new d("INTERNAL","@lunora/agent: agent.asTool requires a non-empty `description` (the parent model decides from it)");const{name:e}=t,n=L(e),c=t.maxPolls??I,a=t.pollIntervalMs??S,i=t.wait??_,p=N(b.listMessages),f=async(h,r)=>{const o=r.env[n];if(!o||typeof o.create!="function"||typeof o.get!="function")throw new d("INTERNAL",`@lunora/agent: agent.asTool("${e}") found no Workflow binding "${n}" on env — declare the "${e}" agent so codegen wires its binding`);const m=`${r.threadKey}::sub::${e}::${r.toolCallId}`,g=`sub-${e}-${r.toolCallId}`,w={input:h.prompt,threadKey:m};let u;try{const l=await o.create({id:g,params:w});u=await o.get(l.id)}catch(l){if(!A(l))throw l;u=await o.get(g)}const s=await M(u,c,a,i);if(s==="errored"||s==="terminated")return`Sub-agent "${e}" ${s} before producing an answer.`;if(s==="timeout")return`Sub-agent "${e}" did not finish within the allotted time.`;const T=await r.run(p,{key:m});return P(T)};return{description:t.description,execute:f,inputSchema:y({properties:{prompt:{description:"The task or question to delegate to the sub-agent.",type:"string"}},required:["prompt"],type:"object"}),isLunoraAgentTool:!0}};export{k as agentAsTool};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as a}from"@lunora/errors";import{jsonSchema as A}from"ai";const $=16,y=4e3,b=e=>{if(e===void 0)return e;const o=typeof e=="string"?e:JSON.stringify(e);return o.length<=y?e:`${o.slice(0,y)}… [truncated]`},T=(e,o)=>{let t=e;for(const s of o.split(".")){if(t===null||typeof t!="object"||!Object.hasOwn(t,s))return;t=t[s]}return t},c=(e,o)=>{if(Array.isArray(e))return e.map(r=>c(r,o));if(e===null||typeof e!="object")return e;const t=e;if(typeof t.$from=="string"){const r=t.$from;if(!(r in o))throw new a("BAD_REQUEST",`@lunora/agent: code step references unknown result "${r}" (define it in an earlier step)`);return typeof t.$path=="string"?T(o[r],t.$path):o[r]}const s={};for(const[r,i]of Object.entries(t))r!=="__proto__"&&(s[r]=c(i,o));return s},g=async(e,o,t,s)=>{const r=Array.isArray(e.steps)?e.steps.slice(0,s):[],i={},p=[],d=new Set;for(const n of r){if(d.has(n.id))throw new a("BAD_REQUEST",`@lunora/agent: duplicate code step id "${n.id}" — each step id must be unique (later steps reference an output by id via $from)`);d.add(n.id)}for(const n of r){const l=o[n.tool];if(!l)throw new a("BAD_REQUEST",`@lunora/agent: code step calls unknown tool "${n.tool}" (available: ${Object.keys(o).join(", ")})`);const m=c(n.input??{},i),f={...t,idempotencyKey:`${t.idempotencyKey}:${n.id}`,toolCallId:`${t.toolCallId}:${n.id}`},h=()=>Promise.resolve(l.execute(m,f)),u=await t.step.do(f.idempotencyKey,h);i[n.id]=u,p.push({id:n.id,output:b(u)})}return{final:p.at(-1)?.output,results:p}},v=e=>`Compose MULTIPLE tool calls in one turn as a script, instead of one call per turn. Provide \`steps\`: an ordered array of \`{ id, tool, input }\`. A later step's \`input\` may reference an earlier step's output with \`{ "$from": "<stepId>", "$path": "optional.dot.path" }\`. Available tools: ${Object.entries(e).map(([o,t])=>`"${o}" — ${t.description}`).join("; ")}.`,w=A({properties:{steps:{description:"Ordered tool calls; a later input may reference an earlier output via { $from, $path }.",items:{additionalProperties:!1,properties:{id:{description:"A name later steps reference this output by.",type:"string"},input:{additionalProperties:!0,description:"The tool input (may embed $from refs).",type:"object"},tool:{description:"The tool to call.",type:"string"}},required:["id","tool"],type:"object"},type:"array"}},required:["steps"],type:"object"}),S=(e,o={})=>{const t=e;if(!t||typeof t!="object"||Object.keys(t).length===0)throw new a("INTERNAL","@lunora/agent: codeTool requires a non-empty map of tools to compose");for(const[r,i]of Object.entries(t))if(i.needsApproval!==void 0&&i.needsApproval!==!1)throw new a("INTERNAL",`@lunora/agent: codeTool cannot compose "${r}" — it has a \`needsApproval\` gate a code-mode script can't pause for. Expose it as a normal top-level tool, or gate the whole script via codeTool's \`needsApproval\`.`);const s=o.maxSteps??$;return{description:o.description??v(e),execute:(r,i)=>g(r,e,i,s),inputSchema:w,isLunoraAgentTool:!0,...o.needsApproval===void 0?{}:{needsApproval:o.needsApproval}}};export{S as codeTool,c as resolveReferences,g as runToolScript};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsonSchema as u}from"ai";import{toFunctionReference as d}from"./AGENT_MODULE-
|
|
1
|
+
import{jsonSchema as u}from"ai";import{toFunctionReference as d}from"./AGENT_MODULE-M4D1EejI.mjs";const h=240,m=50,y=(t,s)=>t.length<=s?t:`${t.slice(0,s)}…`,f=t=>{if(!(t===void 0||!Number.isFinite(t)))return Math.min(m,Math.max(1,Math.trunc(t)))},g=(t,s)=>{const r=t??{},i=Array.isArray(r.chunks)?r.chunks:[],e=Array.isArray(r.sources)?r.sources:[];return{results:i.map(o=>({id:typeof o.id=="string"?o.id:"",score:typeof o.score=="number"?o.score:0,snippet:y(typeof o.text=="string"?o.text:"",s),sourceId:typeof o.sourceId=="string"?o.sourceId:""})),sources:e}},S=u({additionalProperties:!1,properties:{query:{description:"Natural-language search query.",type:"string"},topK:{description:"Maximum number of hits to return.",type:"number"}},required:["query"],type:"object"}),A=u({additionalProperties:!1,properties:{id:{description:"The `id` of a hit returned by the search tool.",type:"string"}},required:["id"],type:"object"}),b=(t,s,r)=>{const i=d(s),e=Math.max(1,t.snippetChars??h),o=t.topK;return{description:`Search long-term memory for passages relevant to a query. Returns ranked { id, sourceId, score, snippet } hits — call again with a refined query to dig deeper.${r===void 0?"":` Use \`${r}\` with a hit's \`id\` to fetch its full text.`}`,execute:async(n,p)=>{const a=f(n.topK)??o,l=await p.run(i,{query:n.query,...a===void 0?{}:{topK:a}});return g(l,e)},inputSchema:S,isLunoraAgentTool:!0}},T=t=>{const s=d(t);return{description:"Fetch the full text of a memory document by the `id` from a search hit.",execute:(r,i)=>i.run(s,{id:r.id}),inputSchema:A,isLunoraAgentTool:!0}},k=(t,s)=>{const r=[];t.memory&&r.push({key:"default",...t.memory});for(const e of s)e.knowledge&&r.push({key:e.name,...e.knowledge});const i={};for(const e of r){if(e.kind==="graph"||e.kind==="episodic"||e.mode!=="agentic"||e.source===void 0)continue;const o=e.key==="default"?"searchMemory":`search_${e.key}`,c=e.key==="default"?"readMemory":`read_${e.key}`,n=e.read!==void 0;i[o]=b(e,e.source,n?c:void 0),n&&(i[c]=T(e.read))}return i};export{k as collectAgenticMemoryTools,g as toSearchResults};
|
package/dist/packem_shared/{compileAgentWorkflow-BvkRUzx_.mjs → compileAgentWorkflow-DITp-XD6.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineWorkflow as s}from"@lunora/workflow";import{runAgentLoop as m}from"./runAgentLoop-
|
|
1
|
+
import{defineWorkflow as s}from"@lunora/workflow";import{runAgentLoop as m}from"./runAgentLoop-KUUoFT3r.mjs";import{createStreamGenerate as p,createAgentGenerate as l,createEpisodeExtract as f,createGraphExtract as d,createCompact as u}from"./createAgentGenerate-9bZ2YhpN.mjs";import{agentDefaultName as c}from"../naming.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as A}from"./AGENT_MODULE-M4D1EejI.mjs";import{F as T}from"./createDispatchRunner-CH4tZsza-CJeRsY7-.mjs";import{otlpTelemetry as y}from"./otlpTelemetry-yAjOjxn0.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o="agent",A=6048e5,a=12096e5,r=n=>({...n,visibility:"internal"}),_=n=>{const s={};for(const[e,t]of Object.entries(n))t!==void 0&&(s[e]=t);return s};export{o as A,r as a,A as b,a as c,_ as d};
|
package/dist/packem_shared/{createAgentContext-CfD3hIZ2.mjs → createAgentContext-VYm8bG12.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{F as g}from"./createDispatchRunner-CH4tZsza-CJeRsY7-.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 u}from"@lunora/errors";const O=(t,e,n)=>{if(e===void 0)return{dispose:()=>{},signal:t};const o=new AbortController,r=setTimeout(()=>{o.abort(n())},e);return{dispose:()=>{clearTimeout(r)},signal:o.signal}},T=t=>{let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)},w=t=>T(t).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");new TextDecoder;const b=new TextEncoder,m="=",A=t=>{for(let e=0;e<t.length;e+=1)if(t.charCodeAt(e)>255)return!1;return!0},R=t=>w(b.encode(JSON.stringify(t))),v=t=>!t.startsWith(m)&&A(t)?t:`${m}${w(b.encode(t))}`,_="/_lunora/scheduler/dispatch",E=3e4,L=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},S=Symbol("lunoraDispatchFailure"),x=Symbol("lunoraDispatchMessageId"),N=(t,e)=>(Object.defineProperty(t,S,{value:!0}),e!==void 0&&Object.defineProperty(t,x,{value:e}),t),D=(t,e,n,o)=>{try{const r=JSON.parse(n)?.error;if(typeof r=="object"&&r!==null&&typeof r.code=="string"){const{code:d,data:i,message:c}=r;return N(new u(d,typeof c=="string"?c:void 0,{data:i,status:e}),o)}}catch{}return N(new u("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${n}`,{status:e}),o)},U=(t,e,n)=>new u("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(n)}ms`,{status:503}),M=t=>{const{label:e}=t,n=globalThis.fetch,o=t.fetchImpl??(typeof n=="function"?n.bind(globalThis):void 0);return async(r,d,i={})=>{if(typeof o!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const c=t.env.LUNORA_ORIGIN_URL;if(typeof c!="string"||c.length===0)throw new u("INTERNAL",`${e}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const h=t.env.LUNORA_ADMIN_TOKEN;if(typeof h!="string"||h.length===0)throw new u("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const $=`${L(c)}${_}`,f={authorization:`Bearer ${h}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(f["x-lunora-userid"]=v(t.identity.userId)),t.identity?.claims!==void 0&&(f["x-lunora-identity"]=R(t.identity.claims));const p=i.timeoutMs??E,g=O(void 0,p,()=>new DOMException(`dispatch timed out after ${String(p)}ms`,"TimeoutError")),y=a=>{throw a instanceof Error&&a.name==="TimeoutError"?U(e,r.__lunoraRef,p):a};let s;try{try{s=await o($,{body:JSON.stringify({args:d??{},functionPath:r.__lunoraRef,id:i.dedupId,shardKey:i.shardKey}),headers:f,method:"POST",signal:g.signal})}catch(l){return y(l)}if(!s.ok){let l;try{l=await s.text()}catch(I){return y(I)}throw D(e,s.status,l,i.messageId)}let a;try{a=await s.text()}catch(l){return y(l)}if(a.length===0)return;try{return JSON.parse(a)}catch{throw new u("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(s.status)}): ${a}`,{status:s.status})}}finally{g.dispose()}}};export{M as F};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{LunoraError as r}from"@lunora/errors";import{collectAgenticMemoryTools as h}from"./collectAgenticMemoryTools-
|
|
1
|
+
import{LunoraError as r}from"@lunora/errors";import{collectAgenticMemoryTools as h}from"./collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as f}from"./agentAsTool-DrFnh9UQ.mjs";import{i as m}from"./memory-JI0lUu84.mjs";import{SKILL_NAME_PATTERN as g,RESERVED_SKILL_NAME as c}from"./defineSkill-DGGvDWNq.mjs";const w=/^[a-zA-Z][\w-]*$/u,p=(e,n)=>{const o={...e.tools};for(const t of n)for(const[s,l]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]=l}return o},T=(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},N=e=>{const n=new Set;for(const o of e){if(typeof o.name!="string"||!g.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)}},A=(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)`)},y=(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\``)},v=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&&(!Number.isInteger(e.maxTurns)||e.maxTurns<1))throw new r("INTERNAL","@lunora/agent: `maxTurns` must be a positive integer");const o=e.skills??[];N(o),y(e,o);const t=p(e,o),s=h(e,o);for(const[i,d]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]=d}const l=Object.keys(s).length>0;A(e.activeTools,s);for(const i of Object.keys(t))if(!w.test(i))throw new r("INTERNAL",`@lunora/agent: tool name "${i}" is not a valid identifier (letters, digits, _ or -, starting with a letter)`);const a=k(e,o),u=T(e,o);return{...e,asTool:f,isLunoraAgent:!0,...o.some(i=>!!i.instructions)?{instructions:u}:{},...a.length>0?{memorySources:a}:{},...o.length>0||l?{tools:t}:{}}},S=e=>typeof e=="object"&&e!==null&&e.isLunoraAgent===!0,O=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{v as defineAgent,O as defineAgentTool,S as isAgentDefinition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as o}from"@lunora/errors";import{toFunctionReference as c}from"./AGENT_MODULE-
|
|
1
|
+
import{LunoraError as o}from"@lunora/errors";import{toFunctionReference as c}from"./AGENT_MODULE-M4D1EejI.mjs";const m=(r,e)=>{if(typeof e.description!="string"||e.description.length===0)throw new o("INTERNAL","@lunora/agent: functionTool requires a non-empty `description` (the model decides from it)");if(e.inputSchema===void 0)throw new o("INTERNAL","@lunora/agent: functionTool requires an `inputSchema` (a zod schema or `jsonSchema(...)`)");const t=c(r);return{description:e.description,execute:(i,n)=>n.run(t,{...i,idempotencyKey:n.idempotencyKey}),inputSchema:e.inputSchema,isLunoraAgentTool:!0}};export{m as functionTool};
|
package/dist/packem_shared/{normalizeEntityName-bz1Thnmp.mjs → normalizeEntityName-Ce0X6Afj.mjs}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineTable as A,initLunora as q}from"@lunora/server";import{v as e}from"@lunora/values";import{A as _,a as f,d as S}from"./component-shared-
|
|
1
|
+
import{defineTable as A,initLunora as q}from"@lunora/server";import{v as e}from"@lunora/values";import{A as _,a as f,d as S}from"./component-shared-IZozysYq.mjs";const T="entities",x="edges",b=`${_}_${T}`,g=`${_}_${x}`,X={[T]:A({createdAt:e.number(),firstMessageKey:e.optional(e.string()),name:e.string(),owner:e.string(),type:e.optional(e.string()),updatedAt:e.number(),weight:e.optional(e.number())}).index("byOwnerName",["owner","name"],{unique:!0}).index("byOwnerUpdatedAt",["owner","updatedAt"]).public(),[x]:A({createdAt:e.number(),dstName:e.string(),label:e.string(),messageKey:e.string(),owner:e.string(),srcName:e.string(),updatedAt:e.number(),weight:e.optional(e.number())}).index("byOwnerSrc",["owner","srcName"]).index("byOwnerDst",["owner","dstName"]).index("byTriple",["owner","srcName","label","dstName"],{unique:!0}).public()},E=64,O=2,G=4,D=8,C=32,R=500,I=/\s+/gu,K=/[^\p{L}\p{N}]+/u,h=t=>t.trim().replaceAll(I," ").toLowerCase(),L=t=>t.toLowerCase().split(K).filter(o=>o.length>=2),P=t=>({dstName:t.dstName,label:t.label,srcName:t.srcName,weight:t.weight??1}),U=(t,o)=>o.weight-t.weight||t.label.localeCompare(o.label)||t.srcName.localeCompare(o.srcName)||t.dstName.localeCompare(o.dstName),$=(t,o)=>o.some(n=>t.includes(n)||n.includes(t)),v=t=>t.map(o=>`- ${o.srcName} —[${o.label}]→ ${o.dstName}`).toSorted((o,n)=>o.localeCompare(n)).join(`
|
|
2
2
|
`),H=t=>`${t.srcName}\0${t.label}\0${t.dstName}`,B=(t,o,n,r)=>{const a=H(t);r.collectedKeys.has(a)||(r.collectedKeys.add(a),r.collected.push(t));const l=t.srcName===o?t.dstName:t.srcName;!r.seen.has(l)&&r.seen.size<n.maxNodes&&(r.seen.add(l),r.next.push(l))},F=async(t,o,n)=>{const r={collected:[],collectedKeys:new Set,next:[],seen:new Set(o)};let a=o.slice(0,n.maxNodes);for(let l=0;l<n.depth&&a.length>0;l+=1){r.next=[];for(const m of a){const p=(await t(m)).toSorted(U).slice(0,n.fanOut);for(const s of p)B(s,m,n,r)}a=r.next}return r.collected},{mutation:M,query:W}=q.dataModel().create(),Y=()=>{const t=M.input({entities:e.array(e.object({name:e.string(),type:e.optional(e.string())})),messageKey:e.string(),owner:e.string(),relations:e.array(e.object({confidence:e.optional(e.number()),dst:e.string(),label:e.string(),src:e.string()}))}).mutation(async({args:n,ctx:r})=>{const a=Date.now(),l=async(s,i)=>{const c=h(s);if(c.length===0)return;const d=await r.db.query(b).withIndex("byOwnerName",u=>u.eq("owner",n.owner).eq("name",c)).first();return d?(i!==void 0&&d.type===void 0&&await r.db.patch(d._id,{type:i,updatedAt:a}),c):(await r.db.insert(b,{createdAt:a,name:c,owner:n.owner,updatedAt:a,weight:1,...S({firstMessageKey:n.messageKey,type:i})}),c)},m=async s=>{const i=h(s.src),c=h(s.dst),d=h(s.label);if(i.length===0||c.length===0||d.length===0||i===c)return!1;await l(i),await l(c);const u=s.confidence??1,N=await r.db.query(g).withIndex("byTriple",y=>y.eq("owner",n.owner).eq("srcName",i).eq("label",d).eq("dstName",c)).first();if(N){const y=N.weight??1;await r.db.patch(N._id,{updatedAt:a,weight:Math.max(y,u)})}else await r.db.insert(g,{createdAt:a,dstName:c,label:d,messageKey:n.messageKey,owner:n.owner,srcName:i,updatedAt:a,weight:u});return!0};let w=0;for(const s of n.entities.slice(0,E))await l(s.name,s.type)!==void 0&&(w+=1);let p=0;for(const s of n.relations.slice(0,E))await m(s)&&(p+=1);return{entities:w,relations:p}}),o=W.input({depth:e.optional(e.number()),fanOut:e.optional(e.number()),maxNodes:e.optional(e.number()),maxSeeds:e.optional(e.number()),owner:e.string(),query:e.string()}).query(async({args:n,ctx:r})=>{const a=L(n.query);if(a.length===0)return{context:""};const m=(await r.db.query(b).withIndex("byOwnerUpdatedAt",s=>s.eq("owner",n.owner)).order("desc").take(R)).filter(s=>$(s.name,a)).toSorted((s,i)=>(i.weight??1)-(s.weight??1)||s.name.localeCompare(i.name)).slice(0,n.maxSeeds??G).map(s=>s.name);if(m.length===0)return{context:""};const p=await F(async s=>{const[i,c]=await Promise.all([r.db.query(g).withIndex("byOwnerSrc",d=>d.eq("owner",n.owner).eq("srcName",s)).collect(),r.db.query(g).withIndex("byOwnerDst",d=>d.eq("owner",n.owner).eq("dstName",s)).collect()]);return[...i,...c].map(d=>P(d))},m,{depth:n.depth??O,fanOut:n.fanOut??D,maxNodes:n.maxNodes??C});return{context:v(p)}});return{agentGraphTraverse:f(o),agentGraphUpsert:f(t)}};export{Y as graphComponent,X as graphTables,h as normalizeEntityName};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{d as J,b as _}from"./component-shared-IZozysYq.mjs";import{resolveAgentModel as Q}from"./createAgentGenerate-9bZ2YhpN.mjs";import{r as Y,f as Z,m as T,a as tt}from"./memory-JI0lUu84.mjs";import{buildModelMessages as D}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as F}from"../naming.mjs";import{toFunctionReference as g}from"./AGENT_MODULE-M4D1EejI.mjs";const et=8,q=e=>e===void 0?"null":JSON.stringify(e),ot=e=>e===void 0?[]:[e].flat(),nt=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),at=(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},st=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))},rt="WorkflowTimeoutError",it=e=>e instanceof Error&&e.name===rt,O=4320*60*1e3,ct={day:864e5,hour:36e5,minute:6e4,month:30*864e5,second:1e3,week:7*864e5,year:365*864e5},ut=/^(\d+(?:\.\d+)?) (day|hour|minute|month|second|week|year)s?$/u,dt=e=>{if(e===void 0)return O;if(typeof e=="number")return Math.min(e,_);const t=ut.exec(e);return t===null?O:Math.min(Number(t[1])*ct[t[2]],_)},pt=async(e,t)=>{const{agent:n,deleteMessage:o,instanceId:a,patchThread:r,persist:i,step:u}=e;await i({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 c=await u.waitForEvent(`approval:${t.id}`,{timeout:dt(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(!it(p))throw p;return{decision:"reject",note:"approval timed out"}});return await o(`${a}:approval:${t.id}`),await r({status:"running"}),c},lt=async(e,t)=>{const{env:n,getState:o,instanceId:a,onTokenDelta:r,persist:i,run:u,setState:c,step:p,threadKey:s,tools:l}=e,d=`tool:${t.name}:${t.id}`,y=l[t.name],h=`${a}:tool:${t.id}`;if(!y){await i({content:`Error: unknown tool "${t.name}"`,messageKey:h,role:"tool",stepName:d,toolCallId:t.id,toolName:t.name});return}const C={env:n,getState:o,idempotencyKey:d,reportProgress:R=>{r?.({data:R,kind:"progress",threadKey:s,toolCallId:t.id})},run:u,setState:c,step:p,threadKey:s,toolCallId:t.id},v={env:n,getState:o,idempotencyKey:d,run:u,threadKey:s,toolCallId:t.id},S=`tool:approval-gate:${t.id}`;let f;if(await st(y,t.input,p,S,v)){const{decision:R,note:$}=await pt(e,t);if(R==="reject"){const N=$===void 0?"":` Reason: ${$}`;await i({content:`Tool "${t.name}" was rejected by the user and not run.${N}`,messageKey:h,role:"tool",status:"rejected",stepName:d,toolCallId:t.id,toolName:t.name});return}f="approved"}const M=await p.do(d,()=>Promise.resolve(y.execute(t.input,C)));await i({content:typeof M=="string"?M:q(M),messageKey:h,role:"tool",stepName:d,...f===void 0?{}:{status:f},toolCallId:t.id,toolName:t.name})},mt=(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:Q(t.model,n),toolChoice:t.toolChoice??e.toolChoice}},yt=(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)}},vt=async(e,t)=>{const{agent:n,compact:o,env:a}=e,r=yt(t,n.compaction);if(r===void 0||o===void 0)return{history:t,summary:void 0};try{const i=await o({env:a,messages:D({history:r.older}),model:n.compaction?.model??n.model});return i.length>0?{history:r.recent,summary:i}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},gt=async(e,t,n)=>{const{agent:o,env:a,generate:r,instructions:i,listMessages:u,memoryContext:c,onTokenDelta:p,run:s,step:l,streamGenerate:d,threadKey:y}=e;return l.do(`llm:turn:${String(t)}`,async()=>{const h=await s(u,{key:y}),{history:x,summary:C}=await vt(e,h);let v={activeTools:o.activeTools,messages:D({history:x,instructions:i,memoryContext:c,summary:C}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(v=mt(v,await o.prepareStep({messages:v.messages,stepNumber:t,steps:n}),a));const S={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 d&&p?d(S,f=>{p({text:f,threadKey:y,turn:t})}):r(S)})},P=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))},ht=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}}),A=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},ft=e=>J({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),wt=async(e,t,n,o)=>{if(e.source===void 0)return;const a=g(e.source),{topK:r}=e,i=T("memory:retrieve",e.key),u=await n.do(i,async()=>o(a,{query:t,...r===void 0?{}:{topK:r}}));return A(u)},Tt=async(e,t,n,o,a,r)=>{if(n===void 0)return;const i=T("memory:traverse",e.key),u=await a.do(i,async()=>r(o,{owner:n,query:t,...ft(e.graph)}));return A(u)},xt=async(e,t,n,o,a)=>{if(t===void 0)return;const r=T("memory:recall",e.key),i={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},u=await o.do(r,async()=>a(n,i));return A(u)},St=async(e,t)=>e.kind==="episodic"?xt(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?Tt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):wt(e,t.input,t.step,t.run),Ct=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},Mt=async(e,t,n,o,a,r)=>{const i=Ct(Y(e));if(i.length===0)return;const u=g(o.graphTraverse),c=g(o.episodeRecall),p=[];for(const s of i){const l=await St(s,{episodeRecall:c,graphTraverse:u,input:t,owner:n,run:r,step:a});l!==void 0&&p.push(l)}return p.length>0?p.join(`
|
|
2
|
+
|
|
3
|
+
`):void 0},Rt=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:r,instanceId:i,owner:u,paths:c,run:p,step:s}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const l=Z(t);if(l!==void 0)try{const d={assistantText:a,env:n,model:l.graph?.extractionModel??t.model,userInput:r},y=await s.do(T("memory:extract",l.key),async()=>o(d));await p(g(c.graphUpsert),{...y,messageKey:`${i}:${T("extract",l.key)}`,owner:u})}catch{}},kt=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:r,instanceId:i,owner:u,paths:c,run:p,step:s,threadKey:l}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const d=tt(t);if(d!==void 0)try{const y={assistantText:a,env:n,model:d.episodic?.extractionModel??t.model,userInput:r},{summary:h}=await s.do(T("memory:episode",d.key),async()=>o(y));await p(g(c.episodeUpsert),{messageKey:`${i}:${T("episode",d.key)}`,owner:u,summary:h,threadKey:l})}catch{}},$t=async(e,t,n)=>{const o=e[F(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},Kt="12 hours",Et=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:Kt,type:`agent-dequeue:${t}:${n}`})},Nt=async(e,t,n)=>{const o=e.env[F(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{}},It=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{}},At=async(e,t,n,o,a)=>{const{instanceId:r,persist:i}=e,u=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const c=n.output!==void 0&&n.text.length===0?q(n.output):n.text;return await i({content:c,messageKey:`${r}:assistant:${String(t)}`,role:"assistant"}),await P(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 i({content:n.text,messageKey:`${r}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const c of n.toolCalls)await lt(e,c);if(await P(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...u}),o.push(ht(n)),a.length>0&&await nt(a,o))return"stopCondition"},Ut=async(e,t,n,o)=>{const a=[];let r,i=!1,u=0;for(let c=0;c<t;c+=1){const p=await gt(e,c,a);o.value=at(o.value,p.usage),u=c+1;const s=await At(e,c,p,a,n);if(s==="stopCondition"){i=!0;break}if(s!==void 0){r=s.final;break}}return{final:r,stoppedByCondition:i,turnsRun:u}},jt=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:r,extractGraph:i,generate:u,instanceId:c,onTokenDelta:p,params:s,paths:l,run:d,step:y,streamGenerate:h}=e,x=t.maxTurns??et,C=ot(t.stopWhen),v=g(l.appendMessage),S=g(l.completeRun),f=g(l.ensureThread),M=g(l.listMessages),R=g(l.deleteMessage),$=g(l.patchThread),N=g(l.setState),j=g(l.state),U=async m=>{await d(v,{threadKey:s.threadKey,...m})},B=async m=>{await d($,{key:s.threadKey,...m})},G=async m=>{await d(R,{messageKey:m,threadKey:s.threadKey})},L=async()=>{await U({content:s.input,messageKey:`${c}:user`,role:"user"})},K=async m=>{const E=await d(S,{instanceId:c,key:s.threadKey,...m});E?.dequeued!==void 0&&await Nt({env:o,exportName:a,step:y},s.threadKey,E.dequeued)},b=async()=>await d(j,{key:s.threadKey}),W=async m=>{await d(N,{key:s.threadKey,state:m})},I=await d(f,{agent:a,instanceId:c,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}});I?.outcome==="replaced"&&await $t(o,a,I.priorInstanceId);const H=await Mt(t,s.input,s.owner,l,y,d),V=typeof t.instructions=="function"?t.instructions({env:o,input:s.input,threadKey:s.threadKey}):t.instructions,X={agent:t,compact:n,env:o,generate:u,getState:b,instanceId:c,instructions:V,listMessages:M,memoryContext:H,onTokenDelta:p,deleteMessage:G,patchThread:B,persist:U,run:d,setState:W,step:y,streamGenerate:h,threadKey:s.threadKey,tools:t.tools??{}},k={value:void 0};try{I?.outcome==="queued"&&await Et(y,s.threadKey,c),await L();const{final:m,stoppedByCondition:E,turnsRun:z}=await Ut(X,x,C,k),w=k.value===void 0?{}:{usage:k.value};return await Rt({agent:t,env:o,extractGraph:i,finalText:m?.text,input:s.input,instanceId:c,owner:s.owner,paths:l,run:d,step:y}),await kt({agent:t,env:o,extractEpisode:r,finalText:m?.text,input:s.input,instanceId:c,owner:s.owner,paths:l,run:d,step:y,threadKey:s.threadKey}),m?(await It(t,{env:o,params:s,step:y},{...m,...w}),await K({status:"idle",...w}),{...m,...w}):E?(await K({status:"idle",...w}),{stopped:"stopCondition",turns:z,...w}):(await K({error:`agent stopped: maxTurns (${String(x)}) reached`,status:"error",...w}),{stopped:"maxTurns",turns:x,...w})}catch(m){throw await K({error:m instanceof Error?m.message:String(m),status:"error",...k.value===void 0?{}:{usage:k.value}}),m}};export{jt as runAgentLoop,yt as splitForCompaction};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./base64-5eyBfWO3.mjs";import{p as s,c as i,f as p,e as n,r as m,t as c}from"./voice-turn-
|
|
1
|
+
import"./base64-5eyBfWO3.mjs";import{p as s,c as i,f as p,e as n,r as m,t as c}from"./voice-turn-CL9QCbEf.mjs";import"./buildModelMessages-Y4tGo1T9.mjs";import"./AGENT_MODULE-M4D1EejI.mjs";export{s as parseIdentity,i as pcmToWav,p as readSynthesisAudio,n as readTranscriptionText,m as runVoiceTurn,c as toByteIterable};
|
|
@@ -610,6 +610,22 @@ interface AgentInboundChannel {
|
|
|
610
610
|
interface AgentConfig {
|
|
611
611
|
/** Restrict the tools the model may call, by name. Default: all tools. */
|
|
612
612
|
activeTools?: ReadonlyArray<string>;
|
|
613
|
+
/**
|
|
614
|
+
* How long a human-in-the-loop tool approval may stay pending before the
|
|
615
|
+
* run stops waiting — a Cloudflare Workflows duration: milliseconds, or a
|
|
616
|
+
* `"<n> <unit>"` string like `"3 days"` (the unit set is the host's, so a
|
|
617
|
+
* typo is a compile error). Default `"3 days"`.
|
|
618
|
+
*
|
|
619
|
+
* On timeout the call is treated as REJECTED (the run records why and
|
|
620
|
+
* continues down the normal rejection path), so a run whose approver never
|
|
621
|
+
* answers ends instead of hibernating forever.
|
|
622
|
+
*
|
|
623
|
+
* CLAMPED to one week. A longer wait would outlive the thread's
|
|
624
|
+
* abandoned-run horizon, letting a new run reclaim the thread while the
|
|
625
|
+
* approval is still pending — which is the exact failure this timeout
|
|
626
|
+
* exists to prevent, so it cannot be configured back into existence.
|
|
627
|
+
*/
|
|
628
|
+
approvalTimeout?: `${number} ${"day" | "hour" | "minute" | "month" | "second" | "week" | "year"}${"s" | ""}` | number;
|
|
613
629
|
/**
|
|
614
630
|
* Automatic thread-history compaction. When the persisted history exceeds
|
|
615
631
|
* `maxMessages`, the loop summarizes the older messages (all but the most
|
|
@@ -942,6 +958,11 @@ interface AgentFunctionPaths {
|
|
|
942
958
|
* next queued run in the same mutation.
|
|
943
959
|
*/
|
|
944
960
|
completeRun: string;
|
|
961
|
+
/**
|
|
962
|
+
* The internal `agents:agentDeleteMessage` mutation the loop dispatches to
|
|
963
|
+
* retire the HITL approval marker once the decision has landed.
|
|
964
|
+
*/
|
|
965
|
+
deleteMessage: string;
|
|
945
966
|
ensureThread: string;
|
|
946
967
|
/** The internal `agents:agentEpisodeRecall` query the loop dispatches for an episodic-kind read. */
|
|
947
968
|
episodeRecall: string;
|
|
@@ -610,6 +610,22 @@ interface AgentInboundChannel {
|
|
|
610
610
|
interface AgentConfig {
|
|
611
611
|
/** Restrict the tools the model may call, by name. Default: all tools. */
|
|
612
612
|
activeTools?: ReadonlyArray<string>;
|
|
613
|
+
/**
|
|
614
|
+
* How long a human-in-the-loop tool approval may stay pending before the
|
|
615
|
+
* run stops waiting — a Cloudflare Workflows duration: milliseconds, or a
|
|
616
|
+
* `"<n> <unit>"` string like `"3 days"` (the unit set is the host's, so a
|
|
617
|
+
* typo is a compile error). Default `"3 days"`.
|
|
618
|
+
*
|
|
619
|
+
* On timeout the call is treated as REJECTED (the run records why and
|
|
620
|
+
* continues down the normal rejection path), so a run whose approver never
|
|
621
|
+
* answers ends instead of hibernating forever.
|
|
622
|
+
*
|
|
623
|
+
* CLAMPED to one week. A longer wait would outlive the thread's
|
|
624
|
+
* abandoned-run horizon, letting a new run reclaim the thread while the
|
|
625
|
+
* approval is still pending — which is the exact failure this timeout
|
|
626
|
+
* exists to prevent, so it cannot be configured back into existence.
|
|
627
|
+
*/
|
|
628
|
+
approvalTimeout?: `${number} ${"day" | "hour" | "minute" | "month" | "second" | "week" | "year"}${"s" | ""}` | number;
|
|
613
629
|
/**
|
|
614
630
|
* Automatic thread-history compaction. When the persisted history exceeds
|
|
615
631
|
* `maxMessages`, the loop summarizes the older messages (all but the most
|
|
@@ -942,6 +958,11 @@ interface AgentFunctionPaths {
|
|
|
942
958
|
* next queued run in the same mutation.
|
|
943
959
|
*/
|
|
944
960
|
completeRun: string;
|
|
961
|
+
/**
|
|
962
|
+
* The internal `agents:agentDeleteMessage` mutation the loop dispatches to
|
|
963
|
+
* retire the HITL approval marker once the decision has landed.
|
|
964
|
+
*/
|
|
965
|
+
deleteMessage: string;
|
|
945
966
|
ensureThread: string;
|
|
946
967
|
/** The internal `agents:agentEpisodeRecall` query the loop dispatches for an episodic-kind read. */
|
|
947
968
|
episodeRecall: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as N,a as W}from"./base64-5eyBfWO3.mjs";import{buildModelMessages as X}from"./buildModelMessages-Y4tGo1T9.mjs";import{toFunctionReference as x}from"./AGENT_MODULE-
|
|
1
|
+
import{f as N,a as W}from"./base64-5eyBfWO3.mjs";import{buildModelMessages as X}from"./buildModelMessages-Y4tGo1T9.mjs";import{toFunctionReference as x}from"./AGENT_MODULE-M4D1EejI.mjs";const D=new TextDecoder;new TextEncoder;const R="=",J=t=>{if(t)try{const e=t[0]==="{"?t:D.decode(N(t)),n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}},nt=t=>{if(t){if(!t.startsWith(R))return t;try{return D.decode(N(t.slice(R.length)))}catch{return}}},st=t=>{const e=Number(t);return Number.isFinite(e)&&e>0?e:void 0},rt=t=>typeof t=="number"&&Date.now()>=t,it=t=>{try{t.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),t.close?.(4001,"token_expired")}catch{}},q=16e3,z=1,G=16,I=/[^.!?]*[.!?]+\s+/u,Y=async function*(t){if(t instanceof Uint8Array){yield t;return}if(t instanceof ReadableStream){const e=t.getReader();try{for(;;){const{done:n,value:i}=await e.read();if(n)break;yield i}}finally{e.releaseLock()}return}yield*t},at=(t,e=q,n=z,i=G)=>{const d=n*i/8,u=e*d,f=new ArrayBuffer(44+t.byteLength),s=new DataView(f),r=(w,p)=>{for(let l=0;l<p.length;l+=1)s.setUint8(w+l,p.codePointAt(l)??0)};r(0,"RIFF"),s.setUint32(4,36+t.byteLength,!0),r(8,"WAVE"),r(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,u,!0),s.setUint16(32,d,!0),s.setUint16(34,i,!0),r(36,"data"),s.setUint32(40,t.byteLength,!0);const y=new Uint8Array(f);return y.set(t,44),y},Q=t=>{const e=[];let n=t,i=I.exec(n);for(;i&&i[0].length>0;){const d=i[0],u=d.trim();u.length>0&&e.push(u),n=n.slice(d.length),i=I.exec(n)}return{rest:n,sentences:e}},ot=async t=>{const{agent:e,connectionId:n,env:i,exportName:d,owner:u,paths:f,pcm:s,run:r,send:y,sendAudio:w,signal:p,streamGenerate:l,synthesize:M,text:P,threadKey:c,transcribe:C,turn:T,waitForDrain:L}=t,h=()=>p.aborted,U=x(f.appendMessage),B=x(f.ensureThread),F=x(f.listMessages),S=x(f.patchThread),b=(P??(s?await C(s):"")).trim();if(b.length===0)return{assistantText:"",interrupted:!1,userText:""};y({text:b,type:"user_transcript"}),await r(B,{agent:d,key:c,...e.initialState===void 0?{}:{initialState:e.initialState},...u===void 0?{}:{owner:u}}),await r(U,{content:b,messageKey:`voice:${n}:${String(T)}:user`,role:"user",threadKey:c}),await r(S,{key:c,status:"running"});const k=typeof e.instructions=="function"?e.instructions({env:i,input:b,threadKey:c}):e.instructions,O=await r(F,{key:c}),$=X({history:O,...k===void 0?{}:{instructions:k}});let g="",E="",A=Promise.resolve();const K=async a=>{if(h()||a.length===0)return;let m=!1;try{for await(const o of Y(await M(a,p))){if(h()||(await L?.(),h()))break;w(o),m=!0}}catch(o){y({message:o instanceof Error?o.message:String(o),type:"error"})}m&&(E=E.length>0?`${E} ${a}`:a)},v=a=>{A=A.then(async()=>K(a))};try{const a=await l({messages:$,signal:p},_=>{if(h())return;y({text:_,type:"assistant_delta"}),g+=_;const{rest:j,sentences:H}=Q(g);g=j;for(const V of H)v(V)});!h()&&g.trim().length>0&&v(g.trim()),g="",await A;const m=h(),o=m?E:a.text;return await r(U,{content:o,messageKey:`voice:${n}:${String(T)}:assistant`,role:"assistant",threadKey:c}),await r(S,{key:c,status:"idle"}),y(m?{type:"interrupted"}:{text:o,type:"assistant_done"}),{assistantText:o,interrupted:m,userText:b}}catch(a){throw await r(S,{key:c,status:"idle"}),a}},ct=t=>J(t),dt=t=>{if(typeof t=="object"&&t!==null&&"text"in t){const{text:e}=t;return typeof e=="string"?e:""}return""},ut=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 W(e);if(e instanceof ReadableStream||e instanceof Uint8Array)return e}return new Uint8Array(0)};export{st as a,it as b,at as c,nt as d,dt as e,ut as f,rt as i,ct as p,ot as r,Y as t};
|
package/dist/reply.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Mailer } from '@lunora/mail';
|
|
2
2
|
import { InboundEmail } from '@lunora/mail/inbound';
|
|
3
|
-
import { a as AgentReplyRef } from "./packem_shared/types.d-
|
|
3
|
+
import { a as AgentReplyRef } from "./packem_shared/types.d-eCuvcLzf.mjs";
|
|
4
4
|
import 'ai';
|
|
5
5
|
/** The email arm of {@link AgentReplyRef}, narrowed for the helpers below. */
|
|
6
6
|
type EmailReplyRef = Extract<AgentReplyRef, {
|
package/dist/reply.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Mailer } from '@lunora/mail';
|
|
2
2
|
import { InboundEmail } from '@lunora/mail/inbound';
|
|
3
|
-
import { a as AgentReplyRef } from "./packem_shared/types.d-
|
|
3
|
+
import { a as AgentReplyRef } from "./packem_shared/types.d-eCuvcLzf.js";
|
|
4
4
|
import 'ai';
|
|
5
5
|
/** The email arm of {@link AgentReplyRef}, narrowed for the helpers below. */
|
|
6
6
|
type EmailReplyRef = Extract<AgentReplyRef, {
|
package/dist/sandbox.d.mts
CHANGED
package/dist/sandbox.d.ts
CHANGED
package/dist/sandbox.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as a}from"@lunora/errors";import{jsonSchema as i}from"ai";import{toFunctionReference as p,SANDBOX_INVOKE_PATH as c}from"./packem_shared/AGENT_MODULE-
|
|
1
|
+
import{LunoraError as a}from"@lunora/errors";import{jsonSchema as i}from"ai";import{toFunctionReference as p,SANDBOX_INVOKE_PATH as c}from"./packem_shared/AGENT_MODULE-M4D1EejI.mjs";const s=p(c),d='Drive a headless browser: screenshot a page, render it to PDF, read its HTML content, or scrape it. Set `op` to "screenshot" | "pdf" | "content" | "scrape" and pass the target `url`.',h='Talk to a sandboxed container: `fetch` an HTTP path on it, or `exec` a command inside it. Set `op` to "fetch" (with `path`) or "exec" (with `command`).',l='Read and write files in a persistent sandbox filesystem. Set `op` to "ls" (list a directory), "read", "write" (with `content`), "rm", or "stat", and pass `path`.',u=e=>e.op==="write"||e.op==="rm",T=i({properties:{content:{description:"write: the file contents.",type:"string"},op:{description:"The filesystem operation to run.",enum:["ls","read","write","rm","stat"],type:"string"},path:{description:"The file or directory path, relative to the sandbox root.",type:"string"}},required:["op"],type:"object"}),m=i({properties:{fullPage:{description:"screenshot: capture the full scrollable page rather than just the viewport.",type:"boolean"},op:{description:"The browser operation to run.",enum:["screenshot","scrape","pdf","content"],type:"string"},selector:{description:"scrape: optional CSS selector hint to narrow the extraction.",type:"string"},type:{description:"screenshot: image encoding (default png).",enum:["png","jpeg"],type:"string"},url:{description:"The URL to operate on.",type:"string"}},required:["op","url"],type:"object"}),g=new Set(["DELETE","PATCH","POST","PUT"]),f=e=>e.op==="exec"||g.has((e.method??"GET").toUpperCase()),y=i({properties:{args:{description:"exec: command arguments.",items:{type:"string"},type:"array"},body:{description:"fetch: request body.",type:"string"},command:{description:"exec: the command to run.",type:"string"},method:{description:"fetch: HTTP method (default GET).",type:"string"},op:{description:"The container operation to run.",enum:["fetch","exec"],type:"string"},path:{description:"fetch: request path on the container (e.g. /health).",type:"string"}},required:["op"],type:"object"}),w=(e={})=>({description:e.description??d,execute:(t,r)=>r.run(s,{...t,kind:"browser"}),inputSchema:m,isLunoraAgentTool:!0,...e.needsApproval===void 0?{}:{needsApproval:e.needsApproval}}),O=(e,t={})=>{if(typeof e!="string"||e.length===0)throw new a("INTERNAL","@lunora/agent: containerTool requires a container `name` (the ctx.containers.<name> key from lunora/containers.ts)");const r=t.needsApproval??f;return{description:t.description??h,execute:(o,n)=>n.run(s,{...o,kind:"container",name:e}),inputSchema:y,isLunoraAgentTool:!0,needsApproval:r}},_=(e,t={})=>{if(typeof e!="string"||e.length===0)throw new a("INTERNAL","@lunora/agent: fsTool requires an R2 `bucket` binding name (the r2_bucket declared in wrangler.jsonc)");return{description:t.description??l,execute:(r,o)=>{const n=typeof t.root=="function"?t.root(o):t.root??"";return o.run(s,{...r,bucket:e,kind:"fs",root:n})},inputSchema:T,isLunoraAgentTool:!0,needsApproval:t.needsApproval??u}};export{w as browserTool,O as containerTool,_ as fsTool};
|
package/dist/skill-markdown.d.ts
CHANGED
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.61",
|
|
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",
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
"@lunora/ai": "1.0.0-alpha.60",
|
|
88
88
|
"@lunora/errors": "1.0.0-alpha.22",
|
|
89
89
|
"@lunora/mail": "1.0.0-alpha.51",
|
|
90
|
-
"@lunora/server": "1.0.0-alpha.
|
|
90
|
+
"@lunora/server": "1.0.0-alpha.80",
|
|
91
91
|
"@lunora/values": "1.0.0-alpha.27",
|
|
92
|
-
"@lunora/workflow": "1.0.0-alpha.
|
|
92
|
+
"@lunora/workflow": "1.0.0-alpha.31",
|
|
93
93
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
94
94
|
"ai": "7.0.59",
|
|
95
95
|
"yaml": "^2.9.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e="agents",a="sandbox",n=`${a}:invoke`,s={appendMessage:`${e}:agentAppendMessage`,completeRun:`${e}:agentCompleteRun`,ensureThread:`${e}:agentEnsureThread`,episodeRecall:`${e}:agentEpisodeRecall`,episodeUpsert:`${e}:agentEpisodeUpsert`,graphTraverse:`${e}:agentGraphTraverse`,graphUpsert:`${e}:agentGraphUpsert`,listMessages:`${e}:agentMessages`,patchThread:`${e}:agentPatchThread`,run:`${e}:agentRun`,setState:`${e}:agentSetState`,state:`${e}:agentState`},r=t=>typeof t=="string"?{__lunoraRef:t}:t;export{e as AGENT_MODULE,s as DEFAULT_AGENT_FUNCTION_PATHS,n as SANDBOX_INVOKE_PATH,a as SANDBOX_MODULE,r as toFunctionReference};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as a}from"@lunora/errors";import{jsonSchema as A}from"ai";const $=16,y=4e3,b=e=>{if(e===void 0)return e;const o=typeof e=="string"?e:JSON.stringify(e);return o.length<=y?e:`${o.slice(0,y)}… [truncated]`},T=(e,o)=>{let t=e;for(const s of o.split(".")){if(t===null||typeof t!="object"||!Object.hasOwn(t,s))return;t=t[s]}return t},c=(e,o)=>{if(Array.isArray(e))return e.map(r=>c(r,o));if(e===null||typeof e!="object")return e;const t=e;if(typeof t.$from=="string"){const r=t.$from;if(!(r in o))throw new a("BAD_REQUEST",`@lunora/agent: code step references unknown result "${r}" (define it in an earlier step)`);return typeof t.$path=="string"?T(o[r],t.$path):o[r]}const s={};for(const[r,i]of Object.entries(t))s[r]=c(i,o);return s},g=async(e,o,t,s)=>{const r=Array.isArray(e.steps)?e.steps.slice(0,s):[],i={},p=[],d=new Set;for(const n of r){if(d.has(n.id))throw new a("BAD_REQUEST",`@lunora/agent: duplicate code step id "${n.id}" — each step id must be unique (later steps reference an output by id via $from)`);d.add(n.id)}for(const n of r){const l=o[n.tool];if(!l)throw new a("BAD_REQUEST",`@lunora/agent: code step calls unknown tool "${n.tool}" (available: ${Object.keys(o).join(", ")})`);const m=c(n.input??{},i),f={...t,idempotencyKey:`${t.idempotencyKey}:${n.id}`,toolCallId:`${t.toolCallId}:${n.id}`},h=()=>Promise.resolve(l.execute(m,f)),u=await t.step.do(f.idempotencyKey,h);i[n.id]=u,p.push({id:n.id,output:b(u)})}return{final:p.at(-1)?.output,results:p}},v=e=>`Compose MULTIPLE tool calls in one turn as a script, instead of one call per turn. Provide \`steps\`: an ordered array of \`{ id, tool, input }\`. A later step's \`input\` may reference an earlier step's output with \`{ "$from": "<stepId>", "$path": "optional.dot.path" }\`. Available tools: ${Object.entries(e).map(([o,t])=>`"${o}" — ${t.description}`).join("; ")}.`,w=A({properties:{steps:{description:"Ordered tool calls; a later input may reference an earlier output via { $from, $path }.",items:{additionalProperties:!1,properties:{id:{description:"A name later steps reference this output by.",type:"string"},input:{additionalProperties:!0,description:"The tool input (may embed $from refs).",type:"object"},tool:{description:"The tool to call.",type:"string"}},required:["id","tool"],type:"object"},type:"array"}},required:["steps"],type:"object"}),S=(e,o={})=>{const t=e;if(!t||typeof t!="object"||Object.keys(t).length===0)throw new a("INTERNAL","@lunora/agent: codeTool requires a non-empty map of tools to compose");for(const[r,i]of Object.entries(t))if(i.needsApproval!==void 0&&i.needsApproval!==!1)throw new a("INTERNAL",`@lunora/agent: codeTool cannot compose "${r}" — it has a \`needsApproval\` gate a code-mode script can't pause for. Expose it as a normal top-level tool, or gate the whole script via codeTool's \`needsApproval\`.`);const s=o.maxSteps??$;return{description:o.description??v(e),execute:(r,i)=>g(r,e,i,s),inputSchema:w,isLunoraAgentTool:!0,...o.needsApproval===void 0?{}:{needsApproval:o.needsApproval}}};export{S as codeTool,c as resolveReferences,g as runToolScript};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const o="agent",r=n=>({...n,visibility:"internal"}),a=n=>{const t={};for(const[s,e]of Object.entries(n))e!==void 0&&(t[s]=e);return t};export{o as A,r as a,a as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as i}from"@lunora/errors";const O=t=>{let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)},m=t=>O(t).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");new TextDecoder;const b=new TextEncoder,g="=",A=t=>{for(let e=0;e<t.length;e+=1)if(t.charCodeAt(e)>255)return!1;return!0},R=t=>m(b.encode(JSON.stringify(t))),T=t=>!t.startsWith(g)&&A(t)?t:`${g}${m(b.encode(t))}`,_="/_lunora/scheduler/dispatch",L=3e4,S=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},v=Symbol("lunoraDispatchFailure"),E=Symbol("lunoraDispatchMessageId"),N=(t,e)=>(Object.defineProperty(t,v,{value:!0}),e!==void 0&&Object.defineProperty(t,E,{value:e}),t),x=(t,e,n,c)=>{try{const o=JSON.parse(n)?.error;if(typeof o=="object"&&o!==null&&typeof o.code=="string"){const{code:h,data:l,message:s}=o;return N(new i(h,typeof s=="string"?s:void 0,{data:l,status:e}),c)}}catch{}return N(new i("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${n}`,{status:e}),c)},U=(t,e,n)=>new i("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(n)}ms`,{status:503}),J=t=>{const{label:e}=t,n=globalThis.fetch,c=t.fetchImpl??(typeof n=="function"?n.bind(globalThis):void 0);return async(o,h,l={})=>{if(typeof c!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const s=t.env.LUNORA_ORIGIN_URL;if(typeof s!="string"||s.length===0)throw new i("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 i("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const w=`${S(s)}${_}`,d={authorization:`Bearer ${f}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(d["x-lunora-userid"]=T(t.identity.userId)),t.identity?.claims!==void 0&&(d["x-lunora-identity"]=R(t.identity.claims));const y=l.timeoutMs??L,$=AbortSignal.timeout(y),p=r=>{throw r instanceof Error&&r.name==="TimeoutError"?U(e,o.__lunoraRef,y):r};let a;try{a=await c(w,{body:JSON.stringify({args:h??{},functionPath:o.__lunoraRef,shardKey:l.shardKey}),headers:d,method:"POST",signal:$})}catch(r){return p(r)}if(!a.ok){let r;try{r=await a.text()}catch(I){return p(I)}throw x(e,a.status,r,l.messageId)}let u;try{u=await a.text()}catch(r){return p(r)}if(u.length!==0)try{return JSON.parse(u)}catch{throw new i("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(a.status)}): ${u}`,{status:a.status})}}};export{J as H};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{d as z}from"./component-shared-Cn6E5d_q.mjs";import{resolveAgentModel as J}from"./createAgentGenerate-9bZ2YhpN.mjs";import{r as Q,f as W,m as x,a as X}from"./memory-JI0lUu84.mjs";import{buildModelMessages as F}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as D}from"../naming.mjs";import{toFunctionReference as g}from"./AGENT_MODULE-CLaSQy3P.mjs";const V=8,G=e=>e===void 0?"null":JSON.stringify(e),Y=e=>e===void 0?[]:[e].flat(),Z=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),tt=(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},et=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))},ot=async(e,t)=>{const{instanceId:n,patchThread:o,persist:a,step:r}=e;await a({content:`Awaiting approval to run tool "${t.name}".`,messageKey:`${n}:approval:${t.id}`,role:"tool",status:"awaiting_approval",toolCallId:t.id,toolName:t.name}),await o({status:"awaiting_input"});const i=await r.waitForEvent(`approval:${t.id}`,{type:`agent-approval:${t.id}`});return await o({status:"running"}),{decision:i.payload.decision,...i.payload.note===void 0?{}:{note:i.payload.note}}},nt=async(e,t)=>{const{env:n,getState:o,instanceId:a,onTokenDelta:r,persist:i,run:d,setState:c,step:l,threadKey:s,tools:p}=e,u=`tool:${t.name}:${t.id}`,m=p[t.name],f=`${a}:tool:${t.id}`;if(!m){await i({content:`Error: unknown tool "${t.name}"`,messageKey:f,role:"tool",stepName:u,toolCallId:t.id,toolName:t.name});return}const S={env:n,getState:o,idempotencyKey:u,reportProgress:$=>{r?.({data:$,kind:"progress",threadKey:s,toolCallId:t.id})},run:d,setState:c,step:l,threadKey:s,toolCallId:t.id},v={env:n,getState:o,idempotencyKey:u,run:d,threadKey:s,toolCallId:t.id},C=`tool:approval-gate:${t.id}`;let h;if(await et(m,t.input,l,C,v)){const{decision:$,note:R}=await ot(e,t);if($==="reject"){const I=R===void 0?"":` Reason: ${R}`;await i({content:`Tool "${t.name}" was rejected by the user and not run.${I}`,messageKey:f,role:"tool",status:"rejected",stepName:u,toolCallId:t.id,toolName:t.name});return}h="approved"}const k=await l.do(u,()=>Promise.resolve(m.execute(t.input,S)));await i({content:typeof k=="string"?k:G(k),messageKey:f,role:"tool",stepName:u,...h===void 0?{}:{status:h},toolCallId:t.id,toolName:t.name})},at=(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:J(t.model,n),toolChoice:t.toolChoice??e.toolChoice}},st=(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)}},rt=async(e,t)=>{const{agent:n,compact:o,env:a}=e,r=st(t,n.compaction);if(r===void 0||o===void 0)return{history:t,summary:void 0};try{const i=await o({env:a,messages:F({history:r.older}),model:n.compaction?.model??n.model});return i.length>0?{history:r.recent,summary:i}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},it=async(e,t,n)=>{const{agent:o,env:a,generate:r,instructions:i,listMessages:d,memoryContext:c,onTokenDelta:l,run:s,step:p,streamGenerate:u,threadKey:m}=e;return p.do(`llm:turn:${String(t)}`,async()=>{const f=await s(d,{key:m}),{history:T,summary:S}=await rt(e,f);let v={activeTools:o.activeTools,messages:F({history:T,instructions:i,memoryContext:c,summary:S}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(v=at(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 u&&l?u(C,h=>{l({text:h,threadKey:m,turn:t})}):r(C)})},q=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))},ct=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}}),A=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},ut=e=>z({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),dt=async(e,t,n,o)=>{if(e.source===void 0)return;const a=g(e.source),{topK:r}=e,i=x("memory:retrieve",e.key),d=await n.do(i,async()=>o(a,{query:t,...r===void 0?{}:{topK:r}}));return A(d)},pt=async(e,t,n,o,a,r)=>{if(n===void 0)return;const i=x("memory:traverse",e.key),d=await a.do(i,async()=>r(o,{owner:n,query:t,...ut(e.graph)}));return A(d)},lt=async(e,t,n,o,a)=>{if(t===void 0)return;const r=x("memory:recall",e.key),i={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},d=await o.do(r,async()=>a(n,i));return A(d)},mt=async(e,t)=>e.kind==="episodic"?lt(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?pt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):dt(e,t.input,t.step,t.run),yt=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},vt=async(e,t,n,o,a,r)=>{const i=yt(Q(e));if(i.length===0)return;const d=g(o.graphTraverse),c=g(o.episodeRecall),l=[];for(const s of i){const p=await mt(s,{episodeRecall:c,graphTraverse:d,input:t,owner:n,run:r,step:a});p!==void 0&&l.push(p)}return l.length>0?l.join(`
|
|
2
|
-
|
|
3
|
-
`):void 0},gt=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:r,instanceId:i,owner:d,paths:c,run:l,step:s}=e;if(o===void 0||d===void 0||a===void 0||a.length===0)return;const p=W(t);if(p!==void 0)try{const u={assistantText:a,env:n,model:p.graph?.extractionModel??t.model,userInput:r},m=await s.do(x("memory:extract",p.key),async()=>o(u));await l(g(c.graphUpsert),{...m,messageKey:`${i}:${x("extract",p.key)}`,owner:d})}catch{}},ft=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:r,instanceId:i,owner:d,paths:c,run:l,step:s,threadKey:p}=e;if(o===void 0||d===void 0||a===void 0||a.length===0)return;const u=X(t);if(u!==void 0)try{const m={assistantText:a,env:n,model:u.episodic?.extractionModel??t.model,userInput:r},{summary:f}=await s.do(x("memory:episode",u.key),async()=>o(m));await l(g(c.episodeUpsert),{messageKey:`${i}:${x("episode",u.key)}`,owner:d,summary:f,threadKey:p})}catch{}},ht=async(e,t,n)=>{const o=e[D(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},wt="12 hours",xt=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:wt,type:`agent-dequeue:${t}:${n}`})},Tt=async(e,t,n)=>{const o=e.env[D(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{}},Ct=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{}},St=async(e,t,n,o,a)=>{const{instanceId:r,persist:i}=e,d=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const c=n.output!==void 0&&n.text.length===0?G(n.output):n.text;return await i({content:c,messageKey:`${r}:assistant:${String(t)}`,role:"assistant"}),await q(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 i({content:n.text,messageKey:`${r}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const c of n.toolCalls)await nt(e,c);if(await q(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...d}),o.push(ct(n)),a.length>0&&await Z(a,o))return"stopCondition"},kt=async(e,t,n,o)=>{const a=[];let r,i=!1,d=0;for(let c=0;c<t;c+=1){const l=await it(e,c,a);o.value=tt(o.value,l.usage),d=c+1;const s=await St(e,c,l,a,n);if(s==="stopCondition"){i=!0;break}if(s!==void 0){r=s.final;break}}return{final:r,stoppedByCondition:i,turnsRun:d}},Et=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:r,extractGraph:i,generate:d,instanceId:c,onTokenDelta:l,params:s,paths:p,run:u,step:m,streamGenerate:f}=e,T=t.maxTurns??V,S=Y(t.stopWhen),v=g(p.appendMessage),C=g(p.completeRun),h=g(p.ensureThread),k=g(p.listMessages),$=g(p.patchThread),R=g(p.setState),I=g(p.state),U=async y=>{await u(v,{threadKey:s.threadKey,...y})},P=async y=>{await u($,{key:s.threadKey,...y})},j=async()=>{await U({content:s.input,messageKey:`${c}:user`,role:"user"})},M=async y=>{const N=await u(C,{instanceId:c,key:s.threadKey,...y});N?.dequeued!==void 0&&await Tt({env:o,exportName:a,step:m},s.threadKey,N.dequeued)},B=async()=>await u(I,{key:s.threadKey}),O=async y=>{await u(R,{key:s.threadKey,state:y})},E=await u(h,{agent:a,instanceId:c,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}});E?.outcome==="replaced"&&await ht(o,a,E.priorInstanceId);const _=await vt(t,s.input,s.owner,p,m,u),b=typeof t.instructions=="function"?t.instructions({env:o,input:s.input,threadKey:s.threadKey}):t.instructions,H={agent:t,compact:n,env:o,generate:d,getState:B,instanceId:c,instructions:b,listMessages:k,memoryContext:_,onTokenDelta:l,patchThread:P,persist:U,run:u,setState:O,step:m,streamGenerate:f,threadKey:s.threadKey,tools:t.tools??{}},K={value:void 0};try{E?.outcome==="queued"&&await xt(m,s.threadKey,c),await j();const{final:y,stoppedByCondition:N,turnsRun:L}=await kt(H,T,S,K),w=K.value===void 0?{}:{usage:K.value};return await gt({agent:t,env:o,extractGraph:i,finalText:y?.text,input:s.input,instanceId:c,owner:s.owner,paths:p,run:u,step:m}),await ft({agent:t,env:o,extractEpisode:r,finalText:y?.text,input:s.input,instanceId:c,owner:s.owner,paths:p,run:u,step:m,threadKey:s.threadKey}),y?(await Ct(t,{env:o,params:s,step:m},{...y,...w}),await M({status:"idle",...w}),{...y,...w}):N?(await M({status:"idle",...w}),{stopped:"stopCondition",turns:L,...w}):(await M({error:`agent stopped: maxTurns (${String(T)}) reached`,status:"error",...w}),{stopped:"maxTurns",turns:T,...w})}catch(y){throw await M({error:y instanceof Error?y.message:String(y),status:"error",...K.value===void 0?{}:{usage:K.value}}),y}};export{Et as runAgentLoop,st as splitForCompaction};
|