@lunora/agent 1.0.0-alpha.81 → 1.0.0-alpha.83
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 +3 -11
- package/dist/channels.d.ts +3 -11
- package/dist/channels.mjs +1 -1
- package/dist/inbound.d.mts +1 -1
- package/dist/inbound.d.ts +1 -1
- package/dist/inbound.mjs +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/VoiceSessionDO-DuGnUFLR.mjs +1 -0
- package/dist/packem_shared/agentAsTool-DnQ2245q.mjs +1 -0
- package/dist/packem_shared/codeTool-C1tpwXz8.mjs +1 -0
- package/dist/packem_shared/{compileAgentWorkflow-D4q6vB3j.mjs → compileAgentWorkflow-Ci5gTX6C.mjs} +1 -1
- package/dist/packem_shared/{createAgentContext-iS35-Xrs.mjs → createAgentContext-CpXkr16T.mjs} +1 -1
- package/dist/packem_shared/createAgentGenerate-BOILDUZj.mjs +3 -0
- package/dist/packem_shared/createDispatchRunner-BrbbxS2q-Dbic8l08.mjs +1 -0
- package/dist/packem_shared/defineAgent-DievK_TE.mjs +3 -0
- package/dist/packem_shared/positive-integer-ztHqqpBk.mjs +1 -0
- package/dist/packem_shared/runAgentLoop-D7nLAmvV.mjs +3 -0
- package/dist/packem_shared/{runVoiceTurn-B9EXi1BC.mjs → runVoiceTurn-C6JtipJN.mjs} +1 -1
- package/dist/packem_shared/tool-output-Cmk3JWMG.mjs +1 -0
- package/dist/packem_shared/{types.d-DTKxPuh_.d.mts → types.d-B8WZl1rU.d.mts} +17 -1
- package/dist/packem_shared/{types.d-DTKxPuh_.d.ts → types.d-B8WZl1rU.d.ts} +17 -1
- package/dist/packem_shared/{voice-turn-DhxJgQW1.mjs → voice-turn-DXJmB3BN.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/skill-markdown.d.mts +1 -1
- package/dist/skill-markdown.d.ts +1 -1
- package/package.json +7 -7
- package/dist/packem_shared/VoiceSessionDO-DHtOAsd9.mjs +0 -1
- package/dist/packem_shared/agentAsTool-Xg7YCl5P.mjs +0 -1
- package/dist/packem_shared/codeTool-DC62JfaY.mjs +0 -1
- package/dist/packem_shared/createAgentGenerate-9bZ2YhpN.mjs +0 -3
- package/dist/packem_shared/createDispatchRunner-pLyQ70FK-2_j6ocGT.mjs +0 -1
- package/dist/packem_shared/defineAgent-YTqqBCP3.mjs +0 -3
- package/dist/packem_shared/runAgentLoop-oAmn3OyN.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-B8WZl1rU.mjs";
|
|
2
|
+
export type { I as InboundChannelEvent } from "./packem_shared/types.d-B8WZl1rU.mjs";
|
|
3
3
|
import '@lunora/mail/inbound';
|
|
4
4
|
import 'ai';
|
|
5
5
|
/**
|
|
@@ -51,14 +51,6 @@ interface AgentChannelTarget {
|
|
|
51
51
|
* @experimental
|
|
52
52
|
*/
|
|
53
53
|
type InboundChannelHandler = (request: Request, env: Record<string, unknown>) => Promise<Response>;
|
|
54
|
-
/**
|
|
55
|
-
* Whether a `workflow.create()` rejection is a duplicate-instance-id error — the
|
|
56
|
-
* idempotency signal — as opposed to a transient/config failure (Workflows
|
|
57
|
-
* service error, instance-creation quota, bad params). Only the former may be
|
|
58
|
-
* acked; every other failure MUST surface so the handler returns non-2xx and the
|
|
59
|
-
* provider redelivers, rather than silently dropping the event.
|
|
60
|
-
*/
|
|
61
|
-
declare const isDuplicateInstanceError: (error: unknown) => boolean;
|
|
62
54
|
/**
|
|
63
55
|
* Build an HTTP handler that starts a durable agent run from a verified inbound
|
|
64
56
|
* webhook. The channel is detected from the signature headers; EACH eligible
|
|
@@ -71,4 +63,4 @@ declare const isDuplicateInstanceError: (error: unknown) => boolean;
|
|
|
71
63
|
* @experimental
|
|
72
64
|
*/
|
|
73
65
|
declare const dispatchAgentChannel: (targets: ReadonlyArray<AgentChannelTarget>) => InboundChannelHandler;
|
|
74
|
-
export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel,
|
|
66
|
+
export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, verifyDiscord, verifyGithub, verifySlack };
|
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-B8WZl1rU.js";
|
|
2
|
+
export type { I as InboundChannelEvent } from "./packem_shared/types.d-B8WZl1rU.js";
|
|
3
3
|
import '@lunora/mail/inbound';
|
|
4
4
|
import 'ai';
|
|
5
5
|
/**
|
|
@@ -51,14 +51,6 @@ interface AgentChannelTarget {
|
|
|
51
51
|
* @experimental
|
|
52
52
|
*/
|
|
53
53
|
type InboundChannelHandler = (request: Request, env: Record<string, unknown>) => Promise<Response>;
|
|
54
|
-
/**
|
|
55
|
-
* Whether a `workflow.create()` rejection is a duplicate-instance-id error — the
|
|
56
|
-
* idempotency signal — as opposed to a transient/config failure (Workflows
|
|
57
|
-
* service error, instance-creation quota, bad params). Only the former may be
|
|
58
|
-
* acked; every other failure MUST surface so the handler returns non-2xx and the
|
|
59
|
-
* provider redelivers, rather than silently dropping the event.
|
|
60
|
-
*/
|
|
61
|
-
declare const isDuplicateInstanceError: (error: unknown) => boolean;
|
|
62
54
|
/**
|
|
63
55
|
* Build an HTTP handler that starts a durable agent run from a verified inbound
|
|
64
56
|
* webhook. The channel is detected from the signature headers; EACH eligible
|
|
@@ -71,4 +63,4 @@ declare const isDuplicateInstanceError: (error: unknown) => boolean;
|
|
|
71
63
|
* @experimental
|
|
72
64
|
*/
|
|
73
65
|
declare const dispatchAgentChannel: (targets: ReadonlyArray<AgentChannelTarget>) => InboundChannelHandler;
|
|
74
|
-
export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel,
|
|
66
|
+
export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, verifyDiscord, verifyGithub, verifySlack };
|
package/dist/channels.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as
|
|
1
|
+
import{LunoraError as m}from"@lunora/errors";import{isDuplicateInstanceError as b}from"@lunora/workflow";import{h as E,B as A}from"./packem_shared/branch-marker-boZ00zmk.mjs";const h=t=>t.toString(16).padStart(4,"0"),x=t=>{let e=8997,n=33826,r=40164,s=52210;for(let a=0;a<t.length;a+=1){const i=t.codePointAt(a)??0;e^=i&65535,n^=i>>>16&65535;const c=e*435,o=n*435,d=r*435+e*256,g=s*435+n*256,u=o+(c>>>16),f=d+(u>>>16),l=g+(f>>>16);e=c&65535,n=u&65535,r=f&65535,s=l&65535}return h(s)+h(r)+h(n)+h(e)},R=300,k=/[^0-9a-f]/iu,N=new TextEncoder,y=t=>new Uint8Array(N.encode(t)),v=t=>{if(t.length%2!==0||k.test(t))throw new m("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},w=async(t,e,n)=>{try{const r=await crypto.subtle.importKey("raw",y(t),{hash:"SHA-256",name:"HMAC"},!1,["verify"]);return await crypto.subtle.verify("HMAC",r,v(n),y(e))}catch{return!1}},S=(t,e,n)=>Number.isFinite(t)&&Math.abs(e-t)<=n,T=async t=>{const{body:e,now:n=Date.now()/1e3,signature:r,signingSecret:s,timestamp:a,tolerance:i=R}=t;return!r||!a||!r.startsWith("v0=")||!S(Number(a),n,i)?!1:w(s,`v0:${a}:${e}`,r.slice(3))},C=async t=>{const{body:e,secret:n,signature:r}=t;return r?.startsWith("sha256=")?w(n,e,r.slice(7)):!1},I=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),y(s+e))}catch{return!1}},_=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"},B=(t,e)=>{if(typeof t=="function")return t(e);const n=e[t];return typeof n=="string"?n:void 0},H=async(t,e,n,r)=>{switch(t){case"discord":return I({body:r,publicKey:e,signature:n.get("x-signature-ed25519")??void 0,timestamp:n.get("x-signature-timestamp")??void 0});case"github":return C({body:r,secret:e,signature:n.get("x-hub-signature-256")??void 0});case"slack":return T({body:r,signature:n.get("x-slack-signature")??void 0,signingSecret:e,timestamp:n.get("x-slack-request-timestamp")??void 0});default:return!1}},M=(t,e)=>{if(t==="discord")try{if(JSON.parse(e).type===1)return Response.json({type:1})}catch{}},p=()=>new Response(void 0,{status:200}),D=(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(E(e))throw new m("BAD_REQUEST",`@lunora/agent: inbound channel run params ${A}`);if(r===void 0||r==="")return await t.create({params:e}),p();try{await t.create({id:`${n}-${x(r)}`,params:e})}catch(s){if(b(s))return p();throw s}return p()},J=t=>async(e,n)=>{const r=await e.text(),s=_(e.headers);if(s===void 0)return new Response("Unrecognized webhook",{status:400});const a=t.map(o=>({config:o.agent.onInbound,target:o})).filter(o=>o.config?.channel===s),i={channel:s,headers:e.headers,json:()=>JSON.parse(r),rawBody:r};let c=!1;for(const{config:o,target:d}of a){const g=B(o.secret,n);if(g===void 0||!await H(s,g,e.headers,r))continue;c=!0;const u=M(s,r);if(u)return u;const f=await o.map(i);if(!f)continue;const l=n[d.binding];if(!l||typeof l.create!="function")throw new m("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(l,f,s,D(s,e.headers,r))}return c?new Response(void 0,{status:204}):new Response("Invalid signature",{status:401})};export{J as dispatchAgentChannel,I as verifyDiscord,C as verifyGithub,T as verifySlack};
|
package/dist/inbound.d.mts
CHANGED
package/dist/inbound.d.ts
CHANGED
package/dist/inbound.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createInboundEmailHandler as u,parseInboundEmail as
|
|
1
|
+
import{createInboundEmailHandler as u,authenticatesFrom as d,parseInboundEmail as g}from"@lunora/mail/inbound";import{h as l,B as m}from"./packem_shared/branch-marker-boZ00zmk.mjs";const f="message could not be processed",c=(r,o)=>{console.error("@lunora/agent/inbound: bouncing message —",o),r.message.setReject(f)},b=r=>{const o=u({dispatch:async(t,n)=>{for(const e of r){const s=e.agent.onEmail;if(!s)continue;const a=await s(t);if(a==null)continue;const i=n.env[e.binding];if(!i||typeof i.create!="function"){c(n,`@lunora/agent: no Workflow binding "${e.binding}" on env for an inbound agent — run codegen/dev so wrangler.jsonc declares it`);return}if(l(a)){c(n,`@lunora/agent: inbound run params ${m}`);return}await i.create({params:a});return}},parse:g,verify:d});return async(t,n,e)=>o(t,n,e)};export{b as dispatchAgentEmail};
|
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-B8WZl1rU.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-B8WZl1rU.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-B8WZl1rU.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-B8WZl1rU.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-D7nLAmvV.mjs";import{collectAgenticMemoryTools as a,toSearchResults as i}from"./packem_shared/collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as l}from"./packem_shared/agentAsTool-DnQ2245q.mjs";import{codeTool as p}from"./packem_shared/codeTool-C1tpwXz8.mjs";import{agentComponent as c,agentExtension as x}from"./component.mjs";import{default as A}from"./packem_shared/createAgentContext-CpXkr16T.mjs";import{defineAgent as d,defineAgentTool as u,isAgentDefinition as N}from"./packem_shared/defineAgent-DievK_TE.mjs";import{functionTool as D}from"./packem_shared/functionTool-D3CP4f8-.mjs";import{createAgentGenerate as M,createEpisodeExtract as O,createGraphExtract as _,createStreamGenerate as C,resolveAgentModel as G}from"./packem_shared/createAgentGenerate-BOILDUZj.mjs";import{adaptMcpResult as F,mcpTools as L}from"./packem_shared/adaptMcpResult-CVlq-_TO.mjs";import{buildModelMessages as k}from"./packem_shared/buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as R,agentClassName as V,agentDefaultName as b,voiceBindingName as h,voiceClassName as w}from"./naming.mjs";import{AGENT_MODULE as I,DEFAULT_AGENT_FUNCTION_PATHS as P,SANDBOX_INVOKE_PATH as X,SANDBOX_MODULE as y,toFunctionReference as K}from"./packem_shared/AGENT_MODULE-M4D1EejI.mjs";import{browserTool as j,containerTool as q,fsTool as z}from"./sandbox.mjs";import{defineSkill as Q,isSkillDefinition as Y}from"./packem_shared/defineSkill-DGGvDWNq.mjs";import{default as $}from"./packem_shared/VoiceSessionDO-DuGnUFLR.mjs";import{r as oe}from"./packem_shared/voice-turn-DXJmB3BN.mjs";import{default as re}from"./packem_shared/compileAgentWorkflow-Ci5gTX6C.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
|
+
import{createAi as S}from"@lunora/ai";import{J as A}from"./createDispatchRunner-BrbbxS2q-Dbic8l08.mjs";import{t as b}from"./base64-5eyBfWO3.mjs";import{p as T,d as _,a as x,i as f,b as p,c as v,e as E,f as k,r as M,t as w}from"./voice-turn-DXJmB3BN.mjs";import{createStreamGenerate as I,createCompact as R}from"./createAgentGenerate-BOILDUZj.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as C,toFunctionReference as y}from"./AGENT_MODULE-M4D1EejI.mjs";const L="@cf/openai/whisper-large-v3-turbo",N="@cf/deepgram/aura-1",O=8*1024*1024,U=100,l=4e3,m=l*4+1024,B=4002,D=4003,F=4004,z=256*1024,g=15,W=5e3;class V{agent;ai;env;exportName;paths;streamGenerate;sttModel;ttsModel;maxSessionTurns;audioBuffers=new Map;bufferedBytes=new Map;controllers=new Map;state;constructor(e,t,s,r){this.state=e,this.env=t,this.agent=s,this.exportName=r,this.paths=C,this.ai=S({binding:t.AI,env:t}),this.streamGenerate=I(s,t),this.sttModel=s.voice?.stt??L,this.ttsModel=s.voice?.tts??N,this.maxSessionTurns=s.voice?.maxTurns??U}fetch(e){if(e.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{status:426});const s=new URL(e.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=T(e.headers.get("x-lunora-identity")),a=_(e.headers.get("x-lunora-userid")),h=x(e.headers.get("x-lunora-identity-exp"));if(f(h))return p(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(e,t){const s=e.deserializeAttachment?.();if(s){if(f(s.expiresAt)){p(e);return}try{if(typeof t=="string"){await this.handleControl(e,s,t);return}this.bufferAudio(s.connectionId,new Uint8Array(t),e)}catch(r){this.send(e,{message:r instanceof Error?r.message:String(r),type:"error"})}}}webSocketClose(e){this.cleanupSocket(e)}webSocketError(e){this.cleanupSocket(e)}resolveRun(e,t){const s=e===void 0&&t===void 0?void 0:{...t===void 0?{}:{claims:t},...e===void 0?{}:{userId:e}};return A({env:this.env,label:"@lunora/agent voice",...s===void 0?{}:{identity:s}})}async transcribe(e){const t=v(e);return E(await this.ai.run(this.sttModel,{audio:b(t)}))}async synthesize(e,t){const s=this.agent.voice?.speaker;return k(await this.ai.run(this.ttsModel,{text:e,...s===void 0?{}:{speaker:s}},t===void 0?void 0:{signal:t}))}async handleControl(e,t,s){if(s.length>m){this.send(e,{message:`control frame exceeds the maximum of ${String(m)} characters`,type:"error"}),this.closeSocket(e,F,"control_frame_limit");return}let r;try{r=JSON.parse(s)}catch{return}if(r.type==="interrupt"){this.controllers.get(t.connectionId)?.abort();return}if(r.type==="text"&&r.text.length>l){this.send(e,{message:`text frame exceeds the maximum of ${String(l)} characters`,type:"error"});return}if(t.turn>=this.maxSessionTurns){this.send(e,{message:`voice session reached its ${String(this.maxSessionTurns)}-turn limit — reconnect to continue`,type:"error"}),this.closeSocket(e,B,"turn_limit");return}if(this.controllers.has(t.connectionId)){this.send(e,{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(t.connectionId);await this.runTurn(e,t,{pcm:i});return}await this.runTurn(e,t,{text:r.text})}bufferAudio(e,t,s){const r=(this.bufferedBytes.get(e)??0)+t.byteLength;if(r>O){this.audioBuffers.delete(e),this.bufferedBytes.delete(e),this.send(s,{message:"utterance exceeded the maximum buffer — send a commit sooner",type:"error"}),this.closeSocket(s,D,"utterance_too_large");return}const i=this.audioBuffers.get(e)??[];i.push(t),this.audioBuffers.set(e,i),this.bufferedBytes.set(e,r)}drainAudio(e){const t=this.audioBuffers.get(e)??[];this.audioBuffers.delete(e),this.bufferedBytes.delete(e);const s=t.reduce((n,o)=>n+o.byteLength,0),r=new Uint8Array(s);let i=0;for(const n of t)r.set(n,i),i+=n.byteLength;return r}async runTurn(e,t,s){const r=new AbortController;this.controllers.set(t.connectionId,r);try{await M({agent:this.agent,compact:R(),connectionId:t.connectionId,env:this.env,exportName:this.exportName,paths:this.paths,run:this.resolveRun(t.userId,t.identity),send:i=>{this.send(e,i)},sendAudio:i=>{this.sendAudio(e,i)},signal:r.signal,streamGenerate:this.streamGenerate,synthesize:async(i,n)=>this.synthesizeWithSignal(i,n),threadKey:t.threadKey,transcribe:async i=>this.transcribe(i),turn:t.turn,waitForDrain:async()=>this.waitForSocketDrain(e),...t.userId===void 0?{}:{owner:t.userId},...s.pcm===void 0?{}:{pcm:s.pcm},...s.text===void 0?{}:{text:s.text}})}finally{this.controllers.get(t.connectionId)===r&&this.controllers.delete(t.connectionId),e.serializeAttachment?.({...t,turn:t.turn+1})}}async speakGreeting(e,t,s,r,i,n){const o=this.resolveRun(r,i),c=new AbortController,d=()=>c.signal.aborted;this.controllers.set(t,c);try{if((await o(y(this.paths.ensureThread),{agent:this.exportName,key:s,...this.agent.initialState===void 0?{}:{initialState:this.agent.initialState},...r===void 0?{}:{owner:r}}))?.outcome!=="created")return;for await(const h of w(await this.synthesizeWithSignal(n,c.signal))){if(d()||(await this.waitForSocketDrain(e),d()))break;this.sendAudio(e,h)}d()||(await o(y(this.paths.appendMessage),{content:n,messageKey:"voice:greeting:assistant",role:"assistant",threadKey:s}),this.send(e,{text:n,type:"assistant_done"}))}catch(a){this.send(e,{message:a instanceof Error?a.message:String(a),type:"error"})}finally{this.controllers.get(t)===c&&this.controllers.delete(t)}}async synthesizeWithSignal(e,t){return t.aborted?new Uint8Array(0):this.synthesize(e,t)}cleanupSocket(e){const t=e.deserializeAttachment?.();t&&(this.controllers.get(t.connectionId)?.abort(),this.controllers.delete(t.connectionId),this.audioBuffers.delete(t.connectionId),this.bufferedBytes.delete(t.connectionId))}closeSocket(e,t,s){try{e.close?.(t,s)}catch{}}send(e,t){try{e.send(JSON.stringify(t))}catch{}}sendAudio(e,t){try{e.send(t)}catch{}}async waitForSocketDrain(e){const t=e;let s=0;for(;typeof t.bufferedAmount=="number"&&t.bufferedAmount>z&&s<W;)await new Promise(r=>{setTimeout(r,g)}),s+=g}}export{V as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as c}from"@lunora/errors";import{isDuplicateInstanceError as N}from"@lunora/workflow";import{jsonSchema as I}from"ai";import{agentBindingName as L}from"../naming.mjs";import{toFunctionReference as S,DEFAULT_AGENT_FUNCTION_PATHS as v}from"./AGENT_MODULE-M4D1EejI.mjs";import{i as h}from"./positive-integer-ztHqqpBk.mjs";const $=new Set(["complete","errored","terminated"]),_=600,w=3,P=500,M=t=>t!==null&&typeof t=="object"&&typeof t.status=="string"?t.status:"unknown",R=t=>t!==null&&typeof t=="object"?t.output:void 0,D=async t=>{await new Promise(e=>{setTimeout(e,t)})},U=async(t,e,n,m)=>{for(let a=0;a<e;a+=1){const i=await t.status(),s=M(i);if($.has(s))return{output:R(i),status:s};await m(n)}return{output:void 0,status:"timeout"}},j=t=>{if(t!==null&&typeof t=="object"&&typeof t.stopped=="string")return t.stopped},k=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 c("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 c("INTERNAL","@lunora/agent: agent.asTool requires a non-empty `description` (the parent model decides from it)");if(t.maxPolls!==void 0&&!h(t.maxPolls))throw new c("INTERNAL","@lunora/agent: agent.asTool `maxPolls` must be a positive integer");const{name:e}=t,n=L(e),m=t.maxPolls??_,a=t.pollIntervalMs??P,i=t.wait??D,s=S(v.listMessages),T=async(y,r)=>{const g=(h(r.depth)?r.depth:0)+1;if(g>w)return`Sub-agent "${e}" was not started: the maximum delegation depth of ${String(w)} is already reached. Answer with what you have instead of delegating further.`;const o=r.env[n];if(!o||typeof o.create!="function"||typeof o.get!="function")throw new c("INTERNAL",`@lunora/agent: agent.asTool("${e}") found no Workflow binding "${n}" on env — declare the "${e}" agent so codegen wires its binding`);const p=`${r.threadKey}::sub::${e}::${r.toolCallId}`,f=`sub-${e}-${r.toolCallId}`,A={depth:g,input:y.prompt,threadKey:p,...r.owner===void 0?{}:{owner:r.owner}};let l;try{const d=await o.create({id:f,params:A});l=await o.get(d.id)}catch(d){if(!N(d))throw d;l=await o.get(f)}const{output:b,status:u}=await U(l,m,a,i);if(u==="errored"||u==="terminated")return`Sub-agent "${e}" ${u} before producing an answer.`;if(u==="timeout"){try{await l.terminate()}catch{}return`Sub-agent "${e}" did not finish within the allotted time.`}if(j(b)==="maxTurns")return`Sub-agent "${e}" hit its turn cap (maxTurns) before producing a final answer. Ask it something narrower, or answer with what you have.`;const E=await r.run(s,{key:p});return k(E)};return{description:t.description,execute:T,inputSchema:I({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 h,asSchema as A}from"ai";import{i as g}from"./positive-integer-ztHqqpBk.mjs";import{M as v,c as $}from"./tool-output-Cmk3JWMG.mjs";const T=16,w=e=>{if(e===void 0)return e;const o=typeof e=="string"?e:JSON.stringify(e);return o.length<=v?e:$(o)},S=(e,o)=>{let t=e;for(const n of o.split(".")){if(t===null||typeof t!="object"||!Object.hasOwn(t,n))return;t=t[n]}return t},l=(e,o)=>{if(Array.isArray(e))return e.map(r=>l(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"?S(o[r],t.$path):o[r]}const n={};for(const[r,i]of Object.entries(t))r!=="__proto__"&&(n[r]=l(i,o));return n},b=async(e,o,t)=>{const{validate:n}=A(o.inputSchema);if(n===void 0)return t;const r=await n(t);if(r.success)return r.value;throw new a("BAD_REQUEST",`@lunora/agent: code step "${e.id}" input is invalid for tool "${e.tool}": ${r.error.message}`)},E=async(e,o,t,n)=>{const r=Array.isArray(e.steps)?e.steps:[];if(r.length>n)throw new a("BAD_REQUEST",`@lunora/agent: code_tool_too_many_steps — the script has ${String(r.length)} steps, over the cap of ${String(n)}. Split it across several code calls.`);const i={},p=[],d=new Set;for(const s of r){if(d.has(s.id))throw new a("BAD_REQUEST",`@lunora/agent: duplicate code step id "${s.id}" — each step id must be unique (later steps reference an output by id via $from)`);d.add(s.id)}for(const s of r){const c=o[s.tool];if(!c)throw new a("BAD_REQUEST",`@lunora/agent: code step calls unknown tool "${s.tool}" (available: ${Object.keys(o).join(", ")})`);const m=await b(s,c,l(s.input??{},i)),u={...t,idempotencyKey:`${t.idempotencyKey}:${s.id}`,toolCallId:`${t.toolCallId}:${s.id}`},y=()=>Promise.resolve(c.execute(m,u)),f=await t.step.do(u.idempotencyKey,y);i[s.id]=f,p.push({id:s.id,output:w(f)})}return{final:p.at(-1)?.output,results:p}},_=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("; ")}.`,O=h({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"}),P=(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\`.`);if(o.maxSteps!==void 0&&!g(o.maxSteps))throw new a("INTERNAL","@lunora/agent: codeTool `maxSteps` must be a positive integer");const n=o.maxSteps??T;return{description:o.description??_(e),execute:(r,i)=>E(r,e,i,n),inputSchema:O,isLunoraAgentTool:!0,...o.needsApproval===void 0?{}:{needsApproval:o.needsApproval}}};export{P as codeTool,l as resolveReferences,E as runToolScript};
|
package/dist/packem_shared/{compileAgentWorkflow-D4q6vB3j.mjs → compileAgentWorkflow-Ci5gTX6C.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-D7nLAmvV.mjs";import{createStreamGenerate as p,createAgentGenerate as l,createEpisodeExtract as f,createGraphExtract as d,createCompact as u}from"./createAgentGenerate-BOILDUZj.mjs";import{agentDefaultName as c}from"../naming.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as A}from"./AGENT_MODULE-M4D1EejI.mjs";import{J as T}from"./createDispatchRunner-BrbbxS2q-Dbic8l08.mjs";import{otlpTelemetry as y}from"./otlpTelemetry-CywiFp-X.mjs";const E=(r,t,a)=>t===void 0?r:T({env:a,identity:{userId:t},label:"@lunora/agent"}),O=(r,t,a)=>{const e=t.LUNORA_OTLP_ENDPOINT;if(typeof e!="string"||e===""||r.telemetry?.isEnabled===!1)return r;const n=typeof t.LUNORA_OTLP_TOKEN=="string"?t.LUNORA_OTLP_TOKEN:void 0,i=[r.telemetry?.integrations].flat().filter(o=>o!==void 0);return{...r,telemetry:{...r.telemetry,integrations:[...i,y({conversationId:a,endpoint:e,token:n})],isEnabled:!0}}},I=(r,t,a)=>s({handler:async e=>{const n=O(r,e.env,e.params.threadKey);return m({agent:n,compact:u(),env:e.env,exportName:t,extractGraph:d(),extractEpisode:f(),generate:l(n,e.env),instanceId:e.event.instanceId,params:e.params,paths:a?.paths??A,run:E(e.run,e.params.owner,e.env),step:e.step,streamGenerate:p(n,e.env)})},name:r.name??c(t)});export{I as default};
|
package/dist/packem_shared/{createAgentContext-iS35-Xrs.mjs → createAgentContext-CpXkr16T.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{J as g}from"./createDispatchRunner-BrbbxS2q-Dbic8l08.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,3 @@
|
|
|
1
|
+
import{createAi as w}from"@lunora/ai";import{LunoraError as T}from"@lunora/errors";import{jsonSchema as x,generateText as d,Output as f,streamText as C,tool as A}from"ai";const g=t=>{if(!t)return;const e={};for(const o of["inputTokens","outputTokens","totalTokens"]){const r=t[o];r!==void 0&&(e[o]=r)}return Object.keys(e).length>0?e:void 0},y=t=>t.map(e=>{const o={id:e.toolCallId,input:e.input,name:e.toolName};return e.invalid!==!0?o:{...o,invalid:e.error instanceof Error?e.error.message:String(e.error)}}),m=(t,e)=>{if(typeof t=="function")return t(e);if(typeof t=="string"){const o=e.AI;if(!o)throw new T("INTERNAL",`@lunora/agent: the agent model "${t}" is a Workers AI id but there is no \`AI\` binding on the workflow env — declare the ai binding in wrangler.jsonc`);return w({binding:o,env:e}).model(t)}return t},b=(t,e)=>{const o=m(t.model,e),r={};for(const[a,i]of Object.entries(t.tools??{}))r[a]=A({description:i.description,inputSchema:i.inputSchema});const n=t.output===void 0?void 0:f.object({schema:t.output}),s={...t.temperature===void 0?{}:{temperature:t.temperature},...t.maxOutputTokens===void 0?{}:{maxOutputTokens:t.maxOutputTokens},...t.telemetry===void 0?{}:{telemetry:t.telemetry},...t.repairToolCall===void 0?{}:{experimental_repairToolCall:t.repairToolCall}};return{defaultModel:o,output:n,staticSettings:s,tools:r}},v=(t,{activeTools:e,messages:o,model:r,signal:n,toolChoice:s})=>{const{defaultModel:a,output:i,staticSettings:h,tools:c}=t,l=e===void 0?c:Object.fromEntries(Object.entries(c).filter(([p])=>e.includes(p)));return{messages:o,model:r??a,...h,...Object.keys(l).length>0?{tools:l}:{},...s===void 0?{}:{toolChoice:s},...i===void 0?{}:{output:i},...n===void 0?{}:{abortSignal:n}}},I=(t,e)=>{const o=b(t,e);return async r=>{const n=await d(v(o,r)),s=g(n.usage);return{text:n.text,toolCalls:y(n.toolCalls),...s===void 0?{}:{usage:s},...o.output===void 0?{}:{output:n.output}}}},q=(t,e)=>{const o=b(t,e);return async(r,n)=>{const s=C(v(o,r));let a="";try{for await(const u of s.textStream)a+=u,n(u)}catch(u){if(r.signal?.aborted)return{text:a,toolCalls:[]};throw u}const[i,h,c,l]=await Promise.all([s.text,s.toolCalls,s.usage,o.output===void 0?Promise.resolve(void 0):s.output]),p=g(c);return{text:i,toolCalls:y(h),...p===void 0?{}:{usage:p},...o.output===void 0?{}:{output:l}}}},k=x({additionalProperties:!1,properties:{entities:{description:"The distinct entities (people, orgs, places, things, concepts) named in the exchange.",items:{additionalProperties:!1,properties:{name:{description:"The entity's canonical name.",type:"string"},type:{description:"An optional coarse type, e.g. person, org, place, product.",type:"string"}},required:["name"],type:"object"},type:"array"},relations:{description:"The directed relationships between the entities, as (src)-[label]->(dst) triples.",items:{additionalProperties:!1,properties:{confidence:{description:"Confidence in the relation, 0..1.",type:"number"},dst:{description:"The destination entity name (must appear in `entities`).",type:"string"},label:{description:"The relationship, a short snake_case verb phrase, e.g. works_at.",type:"string"},src:{description:"The source entity name (must appear in `entities`).",type:"string"}},required:["src","dst","label"],type:"object"},type:"array"}},required:["entities","relations"],type:"object"}),j=(t,e)=>["Extract a knowledge graph of the durable facts stated in the following exchange.","Return the distinct entities and the directed relationships between them.","Only include facts actually stated — do not invent entities or relations. Prefer few, high-signal triples.","",`User: ${t}`,"",`Assistant: ${e}`].join(`
|
|
2
|
+
`),M=()=>async({assistantText:t,env:e,model:o,userInput:r})=>{const{output:n}=await d({model:m(o,e),output:f.object({schema:k}),prompt:j(r,t)});return n},E=(t,e)=>["Summarize the following exchange as ONE concise past-tense sentence for a long-term memory log.","Capture what the user wanted and what was done or decided — a durable fact worth recalling in a later conversation.","No preamble and no quotes: return only the sentence.","",`User: ${t}`,"",`Assistant: ${e}`].join(`
|
|
3
|
+
`),_=()=>async({assistantText:t,env:e,model:o,userInput:r})=>{const{text:n}=await d({model:m(o,e),prompt:E(r,t)});return{summary:n.trim()}},O="You are compacting an ongoing conversation. Summarize the messages so far into a concise brief that preserves decisions made, facts established, open questions, and current task state — everything the assistant needs to continue coherently. Write it as notes for the assistant, not a reply to the user. No preamble.",R=()=>async({env:t,messages:e,model:o})=>{const{text:r}=await d({messages:e,model:m(o,t),system:O});return r.trim()};export{I as createAgentGenerate,R as createCompact,_ as createEpisodeExtract,M as createGraphExtract,q as createStreamGenerate,m as resolveAgentModel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as d}from"@lunora/errors";const T=(t,e,n)=>{if(e===void 0)return{dispose:()=>{},signal:t};const s=new AbortController,o=setTimeout(()=>{s.abort(n())},e);return{dispose:()=>{clearTimeout(o)},signal:s.signal}},a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",A=t=>{let e="",n=0;const s=t.length-2;for(;n<s;n+=3){const r=t[n]<<16|t[n+1]<<8|t[n+2];e+=a.charAt(r>>18&63)+a.charAt(r>>12&63)+a.charAt(r>>6&63)+a.charAt(r&63)}const o=t.length-n;if(o===1){const r=t[n]<<16;e+=a.charAt(r>>18&63)+a.charAt(r>>12&63)}else if(o===2){const r=t[n]<<16|t[n+1]<<8;e+=a.charAt(r>>18&63)+a.charAt(r>>12&63)+a.charAt(r>>6&63)}return e};new TextDecoder;const w=new TextEncoder,N="=",$=t=>{for(let e=0;e<t.length;e+=1)if(t.charCodeAt(e)>255)return!1;return!0},R=t=>A(w.encode(JSON.stringify(t))),v=t=>!t.startsWith(N)&&$(t)?t:`${N}${A(w.encode(t))}`,E="/_lunora/scheduler/dispatch",L=3e4,_=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},S=Symbol("lunoraDispatchFailure"),x=Symbol("lunoraDispatchMessageId"),b=(t,e)=>(e!==void 0&&Object.defineProperty(t,x,{value:e}),t),D=(t,e)=>(Object.defineProperty(t,S,{value:!0}),b(t,e)),U=(t,e,n,s)=>{try{const o=JSON.parse(n)?.error;if(typeof o=="object"&&o!==null&&typeof o.code=="string"){const{code:r,data:u,message:l}=o;return D(new d(r,typeof l=="string"?l:void 0,{data:u,status:e}),s)}}catch{}return b(new d("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${n}`,{status:e}),s)},J=(t,e,n)=>new d("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(n)}ms`,{status:503}),P=t=>{const{label:e}=t,n=globalThis.fetch,s=t.fetchImpl??(typeof n=="function"?n.bind(globalThis):void 0);return async(o,r,u={})=>{if(typeof s!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const l=t.env.LUNORA_ORIGIN_URL;if(typeof l!="string"||l.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const f=t.env.LUNORA_ADMIN_TOKEN;if(typeof f!="string"||f.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const I=`${_(l)}${E}`,p={authorization:`Bearer ${f}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(p["x-lunora-userid"]=v(t.identity.userId)),t.identity?.claims!==void 0&&(p["x-lunora-identity"]=R(t.identity.claims));const y=u.timeoutMs??L,m=T(void 0,y,()=>new DOMException(`dispatch timed out after ${String(y)}ms`,"TimeoutError")),g=i=>{throw i instanceof Error&&i.name==="TimeoutError"?J(e,o.__lunoraRef,y):i};let c;try{try{c=await s(I,{body:JSON.stringify({args:r??{},functionPath:o.__lunoraRef,id:u.dedupId,shardKey:u.shardKey}),headers:p,method:"POST",signal:m.signal})}catch(h){return g(h)}if(!c.ok){let h;try{h=await c.text()}catch(O){return g(O)}throw U(e,c.status,h,u.messageId)}let i;try{i=await c.text()}catch(h){return g(h)}if(i.length===0)return;try{return JSON.parse(i)}catch{throw new d("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(c.status)}): ${i}`,{status:c.status})}}finally{m.dispose()}}};export{P as J};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{LunoraError as r}from"@lunora/errors";import{collectAgenticMemoryTools as f}from"./collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as g}from"./agentAsTool-DnQ2245q.mjs";import{i as m}from"./memory-JI0lUu84.mjs";import{i as c}from"./positive-integer-ztHqqpBk.mjs";import{SKILL_NAME_PATTERN as w,RESERVED_SKILL_NAME as u}from"./defineSkill-DGGvDWNq.mjs";const T=/^[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},N=(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
|
+
|
|
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},A=e=>{const n=new Set;for(const o of e){if(typeof o.name!="string"||!w.test(o.name))throw new r("INTERNAL",`@lunora/agent: skill \`name\` must be a valid identifier (letters, digits, _ or -, starting with a letter), got ${JSON.stringify(o.name)}`);if(o.name===u)throw new r("INTERNAL",`@lunora/agent: skill name "${u}" 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)}},y=(e,n)=>{if(e===void 0)return;const o=Object.keys(n).filter(t=>!e.includes(t));if(o.length>0)throw new r("INTERNAL",`@lunora/agent: \`activeTools\` omits the agentic-memory tool(s) ${o.map(t=>`"${t}"`).join(", ")} — the model could never call them; add them to \`activeTools\` (or drop \`activeTools\` to expose every tool)`)},E=(e,n)=>{const o=(t,s)=>{if(t&&t.kind!=="graph"&&t.kind!=="episodic"&&t.source===void 0)throw new r("INTERNAL",`@lunora/agent: ${s} requires a \`source\` action unless \`kind: "graph"\` or \`kind: "episodic"\``)};o(e.memory,"`memory`");for(const t of n)o(t.knowledge,`skill "${t.name}" \`knowledge\``)},S=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&&!c(e.maxTurns))throw new r("INTERNAL","@lunora/agent: `maxTurns` must be a positive integer");if(e.voice?.maxTurns!==void 0&&!c(e.voice.maxTurns))throw new r("INTERNAL","@lunora/agent: `voice.maxTurns` must be a positive integer");const o=e.skills??[];A(o),E(e,o);const t=p(e,o),s=f(e,o);for(const[i,h]of Object.entries(s)){if(Object.hasOwn(t,i))throw new r("INTERNAL",`@lunora/agent: agentic-memory tool "${i}" collides with an existing tool — rename one (the agent's tool namespace is flat)`);t[i]=h}const l=Object.keys(s).length>0;y(e.activeTools,s);for(const i of Object.keys(t))if(!T.test(i))throw new r("INTERNAL",`@lunora/agent: tool name "${i}" is not a valid identifier (letters, digits, _ or -, starting with a letter)`);const a=k(e,o),d=N(e,o);return{...e,asTool:g,isLunoraAgent:!0,...o.some(i=>!!i.instructions)?{instructions:d}:{},...a.length>0?{memorySources:a}:{},...o.length>0||l?{tools:t}:{}}},O=e=>typeof e=="object"&&e!==null&&e.isLunoraAgent===!0,$=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{S as defineAgent,$ as defineAgentTool,O as isAgentDefinition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i=e=>Number.isInteger(e)&&e>0;export{i};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{d as J,b as O}from"./component-shared-IZozysYq.mjs";import{resolveAgentModel as Q}from"./createAgentGenerate-BOILDUZj.mjs";import{r as Y,f as Z,m as x,a as tt}from"./memory-JI0lUu84.mjs";import{buildModelMessages as F}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as q}from"../naming.mjs";import{toFunctionReference as f}from"./AGENT_MODULE-M4D1EejI.mjs";import{i as et}from"./positive-integer-ztHqqpBk.mjs";import{c as ot}from"./tool-output-Cmk3JWMG.mjs";const nt=8,at=e=>et(e)?e:0,j=e=>e===void 0?"null":JSON.stringify(e),st=async(e,t,n)=>{try{await e({error:t instanceof Error?t.message:String(t),status:"error",...n===void 0?{}:{usage:n}})}catch(o){t instanceof Error&&t.cause===void 0&&(t.cause=o)}},rt=e=>e===void 0?[]:[e].flat(),it=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),ct=(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},ut=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))},dt="WorkflowTimeoutError",pt=e=>e instanceof Error&&e.name===dt,P=4320*60*1e3,lt={day:864e5,hour:36e5,minute:6e4,month:30*864e5,second:1e3,week:7*864e5,year:365*864e5},mt=/^(\d+(?:\.\d+)?) (day|hour|minute|month|second|week|year)s?$/u,yt=e=>{if(e===void 0)return P;if(typeof e=="number")return Math.min(e,O);const t=mt.exec(e);return t===null?P:Math.min(Number(t[1])*lt[t[2]],O)},vt=async(e,t)=>{const{agent:n,deleteMessage:o,instanceId:a,patchThread:r,persist:c,step:u}=e;await c({content:`Awaiting approval to run tool "${t.name}".`,messageKey:`${a}:approval:${t.id}`,role:"tool",status:"awaiting_approval",toolCallId:t.id,toolName:t.name}),await r({status:"awaiting_input"});const i=await u.waitForEvent(`approval:${t.id}`,{timeout:yt(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(!pt(p))throw p;return{decision:"reject",note:"approval timed out"}});return await o(`${a}:approval:${t.id}`),await r({status:"running"}),i},ht=async(e,t)=>{const{depth:n,env:o,getState:a,instanceId:r,onTokenDelta:c,owner:u,persist:i,run:p,setState:s,step:d,threadKey:l,tools:y}=e,v=`tool:${t.name}:${t.id}`,g=y[t.name],w=`${r}:tool:${t.id}`;if(!g){await i({content:`Error: unknown tool "${t.name}"`,messageKey:w,role:"tool",stepName:v,toolCallId:t.id,toolName:t.name});return}if(t.invalid!==void 0){await i({content:`Error: invalid input for tool "${t.name}" — it was not run. ${t.invalid}`,messageKey:w,role:"tool",stepName:v,toolCallId:t.id,toolName:t.name});return}const S={depth:n,env:o,getState:a,idempotencyKey:v,owner:u,reportProgress:$=>{c?.({data:$,kind:"progress",threadKey:l,toolCallId:t.id})},run:p,setState:s,step:d,threadKey:l,toolCallId:t.id},C={depth:n,env:o,getState:a,idempotencyKey:v,run:p,threadKey:l,toolCallId:t.id},A=`tool:approval-gate:${t.id}`;let M;if(await ut(g,t.input,d,A,C)){const{decision:$,note:k}=await vt(e,t);if($==="reject"){const K=k===void 0?"":` Reason: ${k}`;await i({content:`Tool "${t.name}" was rejected by the user and not run.${K}`,messageKey:w,role:"tool",status:"rejected",stepName:v,toolCallId:t.id,toolName:t.name});return}M="approved"}const R=await d.do(v,()=>Promise.resolve(g.execute(t.input,S)));await i({content:ot(typeof R=="string"?R:j(R)),messageKey:w,role:"tool",stepName:v,...M===void 0?{}:{status:M},toolCallId:t.id,toolName:t.name})},ft=(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}},gt=(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)}},wt=async(e,t)=>{const{agent:n,compact:o,env:a}=e,r=gt(t,n.compaction);if(r===void 0||o===void 0)return{history:t,summary:void 0};try{const c=await o({env:a,messages:F({history:r.older}),model:n.compaction?.model??n.model});return c.length>0?{history:r.recent,summary:c}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},Tt=async(e,t,n)=>{const{agent:o,env:a,generate:r,instructions:c,listMessages:u,memoryContext:i,onTokenDelta:p,run:s,step:d,streamGenerate:l,threadKey:y}=e;return d.do(`llm:turn:${String(t)}`,async()=>{const v=await s(u,{key:y}),{history:g,summary:w}=await wt(e,v);let h={activeTools:o.activeTools,messages:F({history:g,instructions:c,memoryContext:i,summary:w}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(h=ft(h,await o.prepareStep({messages:h.messages,stepNumber:t,steps:n}),a));const S={messages:h.messages,...h.activeTools===void 0?{}:{activeTools:h.activeTools},...h.model===void 0?{}:{model:h.model},...h.toolChoice===void 0?{}:{toolChoice:h.toolChoice}};return l&&p?l(S,C=>{p({text:C,threadKey:y,turn:t})}):r(S)})},D=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))},xt=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}}),_=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},St=e=>J({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),Ct=async(e,t,n,o)=>{if(e.source===void 0)return;const a=f(e.source),{topK:r}=e,c=x("memory:retrieve",e.key),u=await n.do(c,async()=>o(a,{query:t,...r===void 0?{}:{topK:r}}));return _(u)},Mt=async(e,t,n,o,a,r)=>{if(n===void 0)return;const c=x("memory:traverse",e.key),u=await a.do(c,async()=>r(o,{owner:n,query:t,...St(e.graph)}));return _(u)},Rt=async(e,t,n,o,a)=>{if(t===void 0)return;const r=x("memory:recall",e.key),c={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},u=await o.do(r,async()=>a(n,c));return _(u)},$t=async(e,t)=>e.kind==="episodic"?Rt(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?Mt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):Ct(e,t.input,t.step,t.run),kt=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},Kt=async(e,t,n,o,a,r)=>{const c=kt(Y(e));if(c.length===0)return;const u=f(o.graphTraverse),i=f(o.episodeRecall),p=[];for(const s of c){const d=await $t(s,{episodeRecall:i,graphTraverse:u,input:t,owner:n,run:r,step:a});d!==void 0&&p.push(d)}return p.length>0?p.join(`
|
|
2
|
+
|
|
3
|
+
`):void 0},Et=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const d=Z(t);if(d!==void 0)try{const l={assistantText:a,env:n,model:d.graph?.extractionModel??t.model,userInput:r},y=await s.do(x("memory:extract",d.key),async()=>o(l));await p(f(i.graphUpsert),{...y,messageKey:`${c}:${x("extract",d.key)}`,owner:u})}catch{}},It=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s,threadKey:d}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const l=tt(t);if(l!==void 0)try{const y={assistantText:a,env:n,model:l.episodic?.extractionModel??t.model,userInput:r},{summary:v}=await s.do(x("memory:episode",l.key),async()=>o(y));await p(f(i.episodeUpsert),{messageKey:`${c}:${x("episode",l.key)}`,owner:u,summary:v,threadKey:d})}catch{}},Nt=async(e,t,n)=>{const o=e[q(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},At="12 hours",Ut=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:At,type:`agent-dequeue:${t}:${n}`})},_t=async(e,t,n)=>{const o=e.env[q(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{}},Ot=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{}},Pt=async(e,t,n,o,a)=>{const{instanceId:r,persist:c}=e,u=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const i=n.output!==void 0&&n.text.length===0?j(n.output):n.text;return await c({content:i,messageKey:`${r}:assistant:${String(t)}`,role:"assistant"}),await D(e,{text:n.text,toolCalls:[],turn:t,...u}),{final:{stopped:"final",text:n.text,turns:t+1,...n.output===void 0?{}:{output:n.output}}}}await c({content:n.text,messageKey:`${r}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const i of n.toolCalls)await ht(e,i);if(await D(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...u}),o.push(xt(n)),a.length>0&&await it(a,o))return"stopCondition"},Dt=async(e,t,n,o)=>{const a=[];let r,c=!1,u=0;for(let i=0;i<t;i+=1){const p=await Tt(e,i,a);o.value=ct(o.value,p.usage),u=i+1;const s=await Pt(e,i,p,a,n);if(s==="stopCondition"){c=!0;break}if(s!==void 0){r=s.final;break}}return{final:r,stoppedByCondition:c,turnsRun:u}},zt=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:r,extractGraph:c,generate:u,instanceId:i,onTokenDelta:p,params:s,paths:d,run:l,step:y,streamGenerate:v}=e,g=t.maxTurns??nt,w=rt(t.stopWhen),h=f(d.appendMessage),S=f(d.completeRun),C=f(d.ensureThread),A=f(d.listMessages),M=f(d.deleteMessage),R=f(d.patchThread),$=f(d.setState),k=f(d.state),K=async m=>{await l(h,{threadKey:s.threadKey,...m})},B=async m=>{await l(R,{key:s.threadKey,...m})},G=async m=>{await l(M,{messageKey:m,threadKey:s.threadKey})},L=async()=>{await K({content:s.input,messageKey:`${i}:user`,role:"user"})},E=async m=>{const N=await l(S,{instanceId:i,key:s.threadKey,...m});N?.dequeued!==void 0&&await _t({env:o,exportName:a,step:y},s.threadKey,N.dequeued)},b=async()=>await l(k,{key:s.threadKey}),W=async m=>{await l($,{key:s.threadKey,state:m})},U=await l(C,{agent:a,instanceId:i,key:s.threadKey,...t.initialState===void 0?{}:{initialState:t.initialState},...t.onConcurrentRun===void 0?{}:{onConcurrentRun:t.onConcurrentRun},...s.owner===void 0?{}:{owner:s.owner},...s.title===void 0?{}:{title:s.title}});U?.outcome==="replaced"&&await Nt(o,a,U.priorInstanceId);const z=await Kt(t,s.input,s.owner,d,y,l),H=typeof t.instructions=="function"?t.instructions({env:o,input:s.input,threadKey:s.threadKey}):t.instructions,V={agent:t,compact:n,depth:at(s.depth),env:o,generate:u,getState:b,instanceId:i,instructions:H,listMessages:A,memoryContext:z,onTokenDelta:p,owner:s.owner,deleteMessage:G,patchThread:B,persist:K,run:l,setState:W,step:y,streamGenerate:v,threadKey:s.threadKey,tools:t.tools??{}},I={value:void 0};try{U?.outcome==="queued"&&await Ut(y,s.threadKey,i),await L();const{final:m,stoppedByCondition:N,turnsRun:X}=await Dt(V,g,w,I),T=I.value===void 0?{}:{usage:I.value};return await Et({agent:t,env:o,extractGraph:c,finalText:m?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:y}),await It({agent:t,env:o,extractEpisode:r,finalText:m?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:y,threadKey:s.threadKey}),m?(await Ot(t,{env:o,params:s,step:y},{...m,...T}),await E({status:"idle",...T}),{...m,...T}):N?(await E({status:"idle",...T}),{stopped:"stopCondition",turns:X,...T}):(await E({error:`agent stopped: maxTurns (${String(g)}) reached`,status:"error",...T}),{stopped:"maxTurns",turns:g,...T})}catch(m){throw await st(E,m,I.value),m}};export{wt as compactHistory,zt as runAgentLoop,gt as splitForCompaction};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./base64-5eyBfWO3.mjs";import{p as s,c as p,f as m,e as n,r as c,t as d}from"./voice-turn-
|
|
1
|
+
import"./base64-5eyBfWO3.mjs";import{p as s,c as p,f as m,e as n,r as c,t as d}from"./voice-turn-DXJmB3BN.mjs";import"./runAgentLoop-D7nLAmvV.mjs";import"./buildModelMessages-Y4tGo1T9.mjs";import"./AGENT_MODULE-M4D1EejI.mjs";export{s as parseIdentity,p as pcmToWav,m as readSynthesisAudio,n as readTranscriptionText,c as runVoiceTurn,d as toByteIterable};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const _=4e3,O="… [truncated]",t=T=>T.length<=4e3?T:`${T.slice(0,4e3-O.length)}${O}`;export{_ as M,t as c};
|
|
@@ -80,6 +80,14 @@ interface AgentToolContext {
|
|
|
80
80
|
getState: () => Promise<Record<string, unknown> | undefined>;
|
|
81
81
|
/** Deterministic idempotency key — the tool's durable-step name. */
|
|
82
82
|
idempotencyKey: string;
|
|
83
|
+
/**
|
|
84
|
+
* Verified owner of the thread this run belongs to (the loop copies it off
|
|
85
|
+
* {@link AgentRunInput.owner}); `undefined` on an anonymous/single-tenant
|
|
86
|
+
* thread. `agent.asTool` forwards it to the CHILD run, so a sub-agent thread
|
|
87
|
+
* under an owned parent inherits the same RLS scope instead of being created
|
|
88
|
+
* ownerless — which left it readable by anyone who knew its key.
|
|
89
|
+
*/
|
|
90
|
+
owner?: string;
|
|
83
91
|
/**
|
|
84
92
|
* Emit an EPHEMERAL progress event for this tool call on the agent's live
|
|
85
93
|
* channel — the same live-only sink the streamed token deltas ride. NOT
|
|
@@ -861,7 +869,7 @@ interface AgentSubToolInput {
|
|
|
861
869
|
interface AgentAsToolOptions {
|
|
862
870
|
/** What the sub-agent does — shown to the parent's model (it decides from it). */
|
|
863
871
|
description: string;
|
|
864
|
-
/** Cap on child-run status polls before giving up — a positive integer. Default
|
|
872
|
+
/** Cap on child-run status polls before giving up — a positive integer. Default 600 (with the 500 ms default interval, a five-minute budget). */
|
|
865
873
|
maxPolls?: number;
|
|
866
874
|
/**
|
|
867
875
|
* The child agent's export name — selects its `AGENT_<NAME>` Workflow
|
|
@@ -1041,6 +1049,14 @@ interface AgentMessageRow {
|
|
|
1041
1049
|
interface AgentToolCall {
|
|
1042
1050
|
id: string;
|
|
1043
1051
|
input: unknown;
|
|
1052
|
+
/**
|
|
1053
|
+
* Why this call was REJECTED before it could run: the model's arguments
|
|
1054
|
+
* failed the tool's input schema, or did not parse as JSON. Present only on
|
|
1055
|
+
* a rejected call — the loop records it as a recoverable tool result and
|
|
1056
|
+
* never executes the tool, because the `input` above is the raw value the
|
|
1057
|
+
* provider sent, not a validated one.
|
|
1058
|
+
*/
|
|
1059
|
+
invalid?: string;
|
|
1044
1060
|
name: string;
|
|
1045
1061
|
}
|
|
1046
1062
|
/**
|
|
@@ -80,6 +80,14 @@ interface AgentToolContext {
|
|
|
80
80
|
getState: () => Promise<Record<string, unknown> | undefined>;
|
|
81
81
|
/** Deterministic idempotency key — the tool's durable-step name. */
|
|
82
82
|
idempotencyKey: string;
|
|
83
|
+
/**
|
|
84
|
+
* Verified owner of the thread this run belongs to (the loop copies it off
|
|
85
|
+
* {@link AgentRunInput.owner}); `undefined` on an anonymous/single-tenant
|
|
86
|
+
* thread. `agent.asTool` forwards it to the CHILD run, so a sub-agent thread
|
|
87
|
+
* under an owned parent inherits the same RLS scope instead of being created
|
|
88
|
+
* ownerless — which left it readable by anyone who knew its key.
|
|
89
|
+
*/
|
|
90
|
+
owner?: string;
|
|
83
91
|
/**
|
|
84
92
|
* Emit an EPHEMERAL progress event for this tool call on the agent's live
|
|
85
93
|
* channel — the same live-only sink the streamed token deltas ride. NOT
|
|
@@ -861,7 +869,7 @@ interface AgentSubToolInput {
|
|
|
861
869
|
interface AgentAsToolOptions {
|
|
862
870
|
/** What the sub-agent does — shown to the parent's model (it decides from it). */
|
|
863
871
|
description: string;
|
|
864
|
-
/** Cap on child-run status polls before giving up — a positive integer. Default
|
|
872
|
+
/** Cap on child-run status polls before giving up — a positive integer. Default 600 (with the 500 ms default interval, a five-minute budget). */
|
|
865
873
|
maxPolls?: number;
|
|
866
874
|
/**
|
|
867
875
|
* The child agent's export name — selects its `AGENT_<NAME>` Workflow
|
|
@@ -1041,6 +1049,14 @@ interface AgentMessageRow {
|
|
|
1041
1049
|
interface AgentToolCall {
|
|
1042
1050
|
id: string;
|
|
1043
1051
|
input: unknown;
|
|
1052
|
+
/**
|
|
1053
|
+
* Why this call was REJECTED before it could run: the model's arguments
|
|
1054
|
+
* failed the tool's input schema, or did not parse as JSON. Present only on
|
|
1055
|
+
* a rejected call — the loop records it as a recoverable tool result and
|
|
1056
|
+
* never executes the tool, because the `input` above is the raw value the
|
|
1057
|
+
* provider sent, not a validated one.
|
|
1058
|
+
*/
|
|
1059
|
+
invalid?: string;
|
|
1044
1060
|
name: string;
|
|
1045
1061
|
}
|
|
1046
1062
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as P,a as q}from"./base64-5eyBfWO3.mjs";import{compactHistory as z}from"./runAgentLoop-
|
|
1
|
+
import{f as P,a as q}from"./base64-5eyBfWO3.mjs";import{compactHistory as z}from"./runAgentLoop-D7nLAmvV.mjs";import{buildModelMessages as G}from"./buildModelMessages-Y4tGo1T9.mjs";import{toFunctionReference as T}from"./AGENT_MODULE-M4D1EejI.mjs";const D=new TextDecoder;new TextEncoder;const N="=",Q=t=>{if(t)try{const e=t[0]==="{"?t:D.decode(P(t)),n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n}catch{}},ct=t=>{if(t){if(!t.startsWith(N))return t;try{return D.decode(P(t.slice(N.length)))}catch{return}}},dt=t=>{const e=Number(t);return Number.isFinite(e)&&e>0?e:void 0},ut=t=>typeof t=="number"&&Date.now()>=t,ft=t=>{try{t.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),t.close?.(4001,"token_expired")}catch{}},Y=16e3,Z=1,tt=16,M=/[.!?]\s/u,et=/\s/u,nt=async function*(t){if(t instanceof Uint8Array){yield t;return}if(t instanceof ReadableStream){const e=t.getReader();try{for(;;){const{done:n,value:r}=await e.read();if(n)break;yield r}}finally{e.releaseLock()}return}yield*t},yt=(t,e=Y,n=Z,r=tt)=>{const i=n*r/8,p=e*i,m=new ArrayBuffer(44+t.byteLength),s=new DataView(m),u=(l,E)=>{for(let d=0;d<E.length;d+=1)s.setUint8(l+d,E.codePointAt(d)??0)};u(0,"RIFF"),s.setUint32(4,36+t.byteLength,!0),u(8,"WAVE"),u(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,n,!0),s.setUint32(24,e,!0),s.setUint32(28,p,!0),s.setUint16(32,i,!0),s.setUint16(34,r,!0),u(36,"data"),s.setUint32(40,t.byteLength,!0);const a=new Uint8Array(m);return a.set(t,44),a},st=t=>{const e=[];let n=t,r=M.exec(n);for(;r;){let i=r.index+1;for(;i<n.length&&et.test(n[i]??"");)i+=1;const p=n.slice(0,i).trim();p.length>0&&e.push(p),n=n.slice(i),r=M.exec(n)}return{rest:n,sentences:e}},pt=async t=>{const{agent:e,compact:n,connectionId:r,env:i,exportName:p,owner:m,paths:s,pcm:u,run:a,send:l,sendAudio:E,signal:d,streamGenerate:C,synthesize:H,text:L,threadKey:o,transcribe:F,turn:U,waitForDrain:O}=t,h=()=>d.aborted,v=T(s.appendMessage),$=T(s.ensureThread),B=T(s.listMessages),b=T(s.patchThread);await a($,{agent:p,key:o,...e.initialState===void 0?{}:{initialState:e.initialState},...m===void 0?{}:{owner:m}});try{const f=(L??(u?await F(u):"")).trim();if(f.length===0)return await a(b,{key:o,status:"idle"}),{assistantText:"",interrupted:!1,userText:""};l({text:f,type:"user_transcript"}),await a(v,{content:f,messageKey:`voice:${r}:${String(U)}:user`,role:"user",threadKey:o}),await a(b,{key:o,status:"running"});const I=typeof e.instructions=="function"?e.instructions({env:i,input:f,threadKey:o}):e.instructions,K=await a(B,{key:o}),{history:j,summary:R}=await z({agent:e,compact:n,env:i},K),W=G({history:j,...I===void 0?{}:{instructions:I},...R===void 0?{}:{summary:R}});let g="",w="",S=Promise.resolve();const V=async c=>{if(h()||c.length===0)return;let x=!1;try{for await(const y of nt(await H(c,d))){if(h()||(await O?.(),h()))break;E(y),x=!0}}catch(y){l({message:y instanceof Error?y.message:String(y),type:"error"})}x&&(w=w.length>0?`${w} ${c}`:c)},_=c=>{S=S.then(async()=>V(c))},X=await C({messages:W,signal:d},c=>{if(h())return;l({text:c,type:"assistant_delta"}),g+=c;const{rest:x,sentences:y}=st(g);g=x;for(const J of y)_(J)});!h()&&g.trim().length>0&&_(g.trim()),g="",await S;const A=h(),k=A?w:X.text;return await a(v,{content:k,messageKey:`voice:${r}:${String(U)}:assistant`,role:"assistant",threadKey:o}),await a(b,{key:o,status:"idle"}),l(A?{type:"interrupted"}:{text:k,type:"assistant_done"}),{assistantText:k,interrupted:A,userText:f}}catch(f){throw await a(b,{key:o,status:"idle"}),f}},lt=t=>Q(t),ht=t=>{if(typeof t=="object"&&t!==null&&"text"in t){const{text:e}=t;return typeof e=="string"?e:""}return""},gt=t=>{if(t instanceof Uint8Array||t instanceof ReadableStream)return t;if(t instanceof Response&&t.body)return t.body;if(typeof t=="object"&&t!==null&&"audio"in t){const{audio:e}=t;if(typeof e=="string")return q(e);if(e instanceof ReadableStream||e instanceof Uint8Array)return e}return new Uint8Array(0)};export{dt as a,ft as b,yt as c,ct as d,ht as e,gt as f,ut as i,lt as p,pt as r,nt as t};
|
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-B8WZl1rU.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-B8WZl1rU.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/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.83",
|
|
4
4
|
"description": "Durable AI agents for Lunora: defineAgent compiles a replay-safe tool-loop onto Cloudflare Workflows, with DO SQLite threads and live message subscriptions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -84,12 +84,12 @@
|
|
|
84
84
|
"access": "public"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@lunora/ai": "1.0.0-alpha.
|
|
88
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
89
|
-
"@lunora/mail": "1.0.0-alpha.
|
|
90
|
-
"@lunora/server": "1.0.0-alpha.
|
|
91
|
-
"@lunora/values": "1.0.0-alpha.
|
|
92
|
-
"@lunora/workflow": "1.0.0-alpha.
|
|
87
|
+
"@lunora/ai": "1.0.0-alpha.70",
|
|
88
|
+
"@lunora/errors": "1.0.0-alpha.30",
|
|
89
|
+
"@lunora/mail": "1.0.0-alpha.61",
|
|
90
|
+
"@lunora/server": "1.0.0-alpha.100",
|
|
91
|
+
"@lunora/values": "1.0.0-alpha.38",
|
|
92
|
+
"@lunora/workflow": "1.0.0-alpha.43",
|
|
93
93
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
94
94
|
"ai": "7.0.59",
|
|
95
95
|
"yaml": "^2.9.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createAi as S}from"@lunora/ai";import{F as A}from"./createDispatchRunner-pLyQ70FK-2_j6ocGT.mjs";import{t as b}from"./base64-5eyBfWO3.mjs";import{p as T,d as _,a as x,i as f,b as p,c as v,e as E,f as k,r as M,t as w}from"./voice-turn-DhxJgQW1.mjs";import{createStreamGenerate as I,createCompact as R}from"./createAgentGenerate-9bZ2YhpN.mjs";import{DEFAULT_AGENT_FUNCTION_PATHS as C,toFunctionReference as y}from"./AGENT_MODULE-M4D1EejI.mjs";const L="@cf/openai/whisper-large-v3-turbo",N="@cf/deepgram/aura-1",O=8*1024*1024,U=100,l=4e3,m=l*4+1024,B=4002,F=4003,D=4004,z=256*1024,g=15,W=5e3;class V{agent;ai;env;exportName;paths;streamGenerate;sttModel;ttsModel;maxSessionTurns;audioBuffers=new Map;bufferedBytes=new Map;controllers=new Map;state;constructor(e,t,s,r){this.state=e,this.env=t,this.agent=s,this.exportName=r,this.paths=C,this.ai=S({binding:t.AI,env:t}),this.streamGenerate=I(s,t),this.sttModel=s.voice?.stt??L,this.ttsModel=s.voice?.tts??N;const i=s.voice?.maxTurns;this.maxSessionTurns=Number.isInteger(i)&&i>0?i:U}fetch(e){if(e.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{status:426});const s=new URL(e.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=T(e.headers.get("x-lunora-identity")),a=_(e.headers.get("x-lunora-userid")),h=x(e.headers.get("x-lunora-identity-exp"));if(f(h))return p(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(e,t){const s=e.deserializeAttachment?.();if(s){if(f(s.expiresAt)){p(e);return}try{if(typeof t=="string"){await this.handleControl(e,s,t);return}this.bufferAudio(s.connectionId,new Uint8Array(t),e)}catch(r){this.send(e,{message:r instanceof Error?r.message:String(r),type:"error"})}}}webSocketClose(e){this.cleanupSocket(e)}webSocketError(e){this.cleanupSocket(e)}resolveRun(e,t){const s=e===void 0&&t===void 0?void 0:{...t===void 0?{}:{claims:t},...e===void 0?{}:{userId:e}};return A({env:this.env,label:"@lunora/agent voice",...s===void 0?{}:{identity:s}})}async transcribe(e){const t=v(e);return E(await this.ai.run(this.sttModel,{audio:b(t)}))}async synthesize(e,t){const s=this.agent.voice?.speaker;return k(await this.ai.run(this.ttsModel,{text:e,...s===void 0?{}:{speaker:s}},t===void 0?void 0:{signal:t}))}async handleControl(e,t,s){if(s.length>m){this.send(e,{message:`control frame exceeds the maximum of ${String(m)} characters`,type:"error"}),this.closeSocket(e,D,"control_frame_limit");return}let r;try{r=JSON.parse(s)}catch{return}if(r.type==="interrupt"){this.controllers.get(t.connectionId)?.abort();return}if(r.type==="text"&&r.text.length>l){this.send(e,{message:`text frame exceeds the maximum of ${String(l)} characters`,type:"error"});return}if(t.turn>=this.maxSessionTurns){this.send(e,{message:`voice session reached its ${String(this.maxSessionTurns)}-turn limit — reconnect to continue`,type:"error"}),this.closeSocket(e,B,"turn_limit");return}if(this.controllers.has(t.connectionId)){this.send(e,{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(t.connectionId);await this.runTurn(e,t,{pcm:i});return}await this.runTurn(e,t,{text:r.text})}bufferAudio(e,t,s){const r=(this.bufferedBytes.get(e)??0)+t.byteLength;if(r>O){this.audioBuffers.delete(e),this.bufferedBytes.delete(e),this.send(s,{message:"utterance exceeded the maximum buffer — send a commit sooner",type:"error"}),this.closeSocket(s,F,"utterance_too_large");return}const i=this.audioBuffers.get(e)??[];i.push(t),this.audioBuffers.set(e,i),this.bufferedBytes.set(e,r)}drainAudio(e){const t=this.audioBuffers.get(e)??[];this.audioBuffers.delete(e),this.bufferedBytes.delete(e);const s=t.reduce((n,o)=>n+o.byteLength,0),r=new Uint8Array(s);let i=0;for(const n of t)r.set(n,i),i+=n.byteLength;return r}async runTurn(e,t,s){const r=new AbortController;this.controllers.set(t.connectionId,r);try{await M({agent:this.agent,compact:R(),connectionId:t.connectionId,env:this.env,exportName:this.exportName,paths:this.paths,run:this.resolveRun(t.userId,t.identity),send:i=>{this.send(e,i)},sendAudio:i=>{this.sendAudio(e,i)},signal:r.signal,streamGenerate:this.streamGenerate,synthesize:async(i,n)=>this.synthesizeWithSignal(i,n),threadKey:t.threadKey,transcribe:async i=>this.transcribe(i),turn:t.turn,waitForDrain:async()=>this.waitForSocketDrain(e),...t.userId===void 0?{}:{owner:t.userId},...s.pcm===void 0?{}:{pcm:s.pcm},...s.text===void 0?{}:{text:s.text}})}finally{this.controllers.get(t.connectionId)===r&&this.controllers.delete(t.connectionId),e.serializeAttachment?.({...t,turn:t.turn+1})}}async speakGreeting(e,t,s,r,i,n){const o=this.resolveRun(r,i),c=new AbortController,d=()=>c.signal.aborted;this.controllers.set(t,c);try{if((await o(y(this.paths.ensureThread),{agent:this.exportName,key:s,...this.agent.initialState===void 0?{}:{initialState:this.agent.initialState},...r===void 0?{}:{owner:r}}))?.outcome!=="created")return;for await(const h of w(await this.synthesizeWithSignal(n,c.signal))){if(d()||(await this.waitForSocketDrain(e),d()))break;this.sendAudio(e,h)}d()||(await o(y(this.paths.appendMessage),{content:n,messageKey:"voice:greeting:assistant",role:"assistant",threadKey:s}),this.send(e,{text:n,type:"assistant_done"}))}catch(a){this.send(e,{message:a instanceof Error?a.message:String(a),type:"error"})}finally{this.controllers.get(t)===c&&this.controllers.delete(t)}}async synthesizeWithSignal(e,t){return t.aborted?new Uint8Array(0):this.synthesize(e,t)}cleanupSocket(e){const t=e.deserializeAttachment?.();t&&(this.controllers.get(t.connectionId)?.abort(),this.controllers.delete(t.connectionId),this.audioBuffers.delete(t.connectionId),this.bufferedBytes.delete(t.connectionId))}closeSocket(e,t,s){try{e.close?.(t,s)}catch{}}send(e,t){try{e.send(JSON.stringify(t))}catch{}}sendAudio(e,t){try{e.send(t)}catch{}}async waitForSocketDrain(e){const t=e;let s=0;for(;typeof t.bufferedAmount=="number"&&t.bufferedAmount>z&&s<W;)await new Promise(r=>{setTimeout(r,g)}),s+=g}}export{V as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as d}from"@lunora/errors";import{jsonSchema as N}from"ai";import{isDuplicateInstanceError as b}from"../channels.mjs";import{agentBindingName as E}from"../naming.mjs";import{toFunctionReference as I,DEFAULT_AGENT_FUNCTION_PATHS as L}from"./AGENT_MODULE-M4D1EejI.mjs";const S=new Set(["complete","errored","terminated"]),$=120,f=3,_=500,P=t=>t!==null&&typeof t=="object"&&typeof t.status=="string"?t.status:"unknown",v=async t=>{await new Promise(e=>{setTimeout(e,t)})},M=async(t,e,n,u)=>{for(let o=0;o<e;o+=1){const i=P(await t.status());if(S.has(i))return i;await u(n)}return"timeout"},R=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)");if(t.maxPolls!==void 0&&(!Number.isInteger(t.maxPolls)||t.maxPolls<1))throw new d("INTERNAL","@lunora/agent: agent.asTool `maxPolls` must be a positive integer");const{name:e}=t,n=E(e),u=t.maxPolls??$,o=t.pollIntervalMs??_,i=t.wait??v,p=I(L.listMessages),w=async(T,r)=>{const m=(Number.isInteger(r.depth)?r.depth:0)+1;if(m>f)return`Sub-agent "${e}" was not started: the maximum delegation depth of ${String(f)} is already reached. Answer with what you have instead of delegating further.`;const a=r.env[n];if(!a||typeof a.create!="function"||typeof a.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 g=`${r.threadKey}::sub::${e}::${r.toolCallId}`,h=`sub-${e}-${r.toolCallId}`,y={depth:m,input:T.prompt,threadKey:g};let s;try{const c=await a.create({id:h,params:y});s=await a.get(c.id)}catch(c){if(!b(c))throw c;s=await a.get(h)}const l=await M(s,u,o,i);if(l==="errored"||l==="terminated")return`Sub-agent "${e}" ${l} before producing an answer.`;if(l==="timeout"){try{await s.terminate()}catch{}return`Sub-agent "${e}" did not finish within the allotted time.`}const A=await r.run(p,{key:g});return R(A)};return{description:t.description,execute:w,inputSchema:N({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};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as a}from"@lunora/errors";import{jsonSchema as A}from"ai";const b=16,m=4e3,$=e=>{if(e===void 0)return e;const o=typeof e=="string"?e:JSON.stringify(e);return o.length<=m?e:`${o.slice(0,m)}… [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 y=c(n.input??{},i),f={...t,idempotencyKey:`${t.idempotencyKey}:${n.id}`,toolCallId:`${t.toolCallId}:${n.id}`},h=()=>Promise.resolve(l.execute(y,f)),u=await t.step.do(f.idempotencyKey,h);i[n.id]=u,p.push({id:n.id,output:$(u)})}return{final:p.at(-1)?.output,results:p}},S=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("; ")}.`,v=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"}),j=(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\`.`);if(o.maxSteps!==void 0&&(!Number.isInteger(o.maxSteps)||o.maxSteps<1))throw new a("INTERNAL","@lunora/agent: codeTool `maxSteps` must be a positive integer");const s=o.maxSteps??b;return{description:o.description??S(e),execute:(r,i)=>g(r,e,i,s),inputSchema:v,isLunoraAgentTool:!0,...o.needsApproval===void 0?{}:{needsApproval:o.needsApproval}}};export{j as codeTool,c as resolveReferences,g as runToolScript};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{createAi as w}from"@lunora/ai";import{LunoraError as T}from"@lunora/errors";import{jsonSchema as x,generateText as d,Output as f,streamText as C,tool as A}from"ai";const y=t=>{if(!t)return;const e={};for(const o of["inputTokens","outputTokens","totalTokens"]){const n=t[o];n!==void 0&&(e[o]=n)}return Object.keys(e).length>0?e:void 0},g=t=>t.map(e=>({id:e.toolCallId,input:e.input,name:e.toolName})),m=(t,e)=>{if(typeof t=="function")return t(e);if(typeof t=="string"){const o=e.AI;if(!o)throw new T("INTERNAL",`@lunora/agent: the agent model "${t}" is a Workers AI id but there is no \`AI\` binding on the workflow env — declare the ai binding in wrangler.jsonc`);return w({binding:o,env:e}).model(t)}return t},b=(t,e)=>{const o=m(t.model,e),n={};for(const[a,i]of Object.entries(t.tools??{}))n[a]=A({description:i.description,inputSchema:i.inputSchema});const r=t.output===void 0?void 0:f.object({schema:t.output}),s={...t.temperature===void 0?{}:{temperature:t.temperature},...t.maxOutputTokens===void 0?{}:{maxOutputTokens:t.maxOutputTokens},...t.telemetry===void 0?{}:{telemetry:t.telemetry},...t.repairToolCall===void 0?{}:{experimental_repairToolCall:t.repairToolCall}};return{defaultModel:o,output:r,staticSettings:s,tools:n}},v=(t,{activeTools:e,messages:o,model:n,signal:r,toolChoice:s})=>{const{defaultModel:a,output:i,staticSettings:h,tools:c}=t,l=e===void 0?c:Object.fromEntries(Object.entries(c).filter(([p])=>e.includes(p)));return{messages:o,model:n??a,...h,...Object.keys(l).length>0?{tools:l}:{},...s===void 0?{}:{toolChoice:s},...i===void 0?{}:{output:i},...r===void 0?{}:{abortSignal:r}}},I=(t,e)=>{const o=b(t,e);return async n=>{const r=await d(v(o,n)),s=y(r.usage);return{text:r.text,toolCalls:g(r.toolCalls),...s===void 0?{}:{usage:s},...o.output===void 0?{}:{output:r.output}}}},q=(t,e)=>{const o=b(t,e);return async(n,r)=>{const s=C(v(o,n));let a="";try{for await(const u of s.textStream)a+=u,r(u)}catch(u){if(n.signal?.aborted)return{text:a,toolCalls:[]};throw u}const[i,h,c,l]=await Promise.all([s.text,s.toolCalls,s.usage,o.output===void 0?Promise.resolve(void 0):s.output]),p=y(c);return{text:i,toolCalls:g(h),...p===void 0?{}:{usage:p},...o.output===void 0?{}:{output:l}}}},k=x({additionalProperties:!1,properties:{entities:{description:"The distinct entities (people, orgs, places, things, concepts) named in the exchange.",items:{additionalProperties:!1,properties:{name:{description:"The entity's canonical name.",type:"string"},type:{description:"An optional coarse type, e.g. person, org, place, product.",type:"string"}},required:["name"],type:"object"},type:"array"},relations:{description:"The directed relationships between the entities, as (src)-[label]->(dst) triples.",items:{additionalProperties:!1,properties:{confidence:{description:"Confidence in the relation, 0..1.",type:"number"},dst:{description:"The destination entity name (must appear in `entities`).",type:"string"},label:{description:"The relationship, a short snake_case verb phrase, e.g. works_at.",type:"string"},src:{description:"The source entity name (must appear in `entities`).",type:"string"}},required:["src","dst","label"],type:"object"},type:"array"}},required:["entities","relations"],type:"object"}),j=(t,e)=>["Extract a knowledge graph of the durable facts stated in the following exchange.","Return the distinct entities and the directed relationships between them.","Only include facts actually stated — do not invent entities or relations. Prefer few, high-signal triples.","",`User: ${t}`,"",`Assistant: ${e}`].join(`
|
|
2
|
-
`),M=()=>async({assistantText:t,env:e,model:o,userInput:n})=>{const{output:r}=await d({model:m(o,e),output:f.object({schema:k}),prompt:j(n,t)});return r},O=(t,e)=>["Summarize the following exchange as ONE concise past-tense sentence for a long-term memory log.","Capture what the user wanted and what was done or decided — a durable fact worth recalling in a later conversation.","No preamble and no quotes: return only the sentence.","",`User: ${t}`,"",`Assistant: ${e}`].join(`
|
|
3
|
-
`),_=()=>async({assistantText:t,env:e,model:o,userInput:n})=>{const{text:r}=await d({model:m(o,e),prompt:O(n,t)});return{summary:r.trim()}},E="You are compacting an ongoing conversation. Summarize the messages so far into a concise brief that preserves decisions made, facts established, open questions, and current task state — everything the assistant needs to continue coherently. Write it as notes for the assistant, not a reply to the user. No preamble.",R=()=>async({env:t,messages:e,model:o})=>{const{text:n}=await d({messages:e,model:m(o,t),system:E});return n.trim()};export{I as createAgentGenerate,R as createCompact,_ as createEpisodeExtract,M as createGraphExtract,q as createStreamGenerate,m as resolveAgentModel};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as d}from"@lunora/errors";const T=(t,e,n)=>{if(e===void 0)return{dispose:()=>{},signal:t};const s=new AbortController,r=setTimeout(()=>{s.abort(n())},e);return{dispose:()=>{clearTimeout(r)},signal:s.signal}},a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",w=t=>{let e="",n=0;const s=t.length-2;for(;n<s;n+=3){const o=t[n]<<16|t[n+1]<<8|t[n+2];e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)+a.charAt(o>>6&63)+a.charAt(o&63)}const r=t.length-n;if(r===1){const o=t[n]<<16;e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)}else if(r===2){const o=t[n]<<16|t[n+1]<<8;e+=a.charAt(o>>18&63)+a.charAt(o>>12&63)+a.charAt(o>>6&63)}return e};new TextDecoder;const b=new TextEncoder,N="=",$=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(N)&&$(t)?t:`${N}${w(b.encode(t))}`,E="/_lunora/scheduler/dispatch",L=3e4,_=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},S=Symbol("lunoraDispatchFailure"),x=Symbol("lunoraDispatchMessageId"),A=(t,e)=>(Object.defineProperty(t,S,{value:!0}),e!==void 0&&Object.defineProperty(t,x,{value:e}),t),D=(t,e,n,s)=>{try{const r=JSON.parse(n)?.error;if(typeof r=="object"&&r!==null&&typeof r.code=="string"){const{code:o,data:u,message:l}=r;return A(new d(o,typeof l=="string"?l:void 0,{data:u,status:e}),s)}}catch{}return A(new d("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${n}`,{status:e}),s)},U=(t,e,n)=>new d("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(n)}ms`,{status:503}),M=t=>{const{label:e}=t,n=globalThis.fetch,s=t.fetchImpl??(typeof n=="function"?n.bind(globalThis):void 0);return async(r,o,u={})=>{if(typeof s!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const l=t.env.LUNORA_ORIGIN_URL;if(typeof l!="string"||l.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const f=t.env.LUNORA_ADMIN_TOKEN;if(typeof f!="string"||f.length===0)throw new d("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const I=`${_(l)}${E}`,p={authorization:`Bearer ${f}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(p["x-lunora-userid"]=v(t.identity.userId)),t.identity?.claims!==void 0&&(p["x-lunora-identity"]=R(t.identity.claims));const y=u.timeoutMs??L,m=T(void 0,y,()=>new DOMException(`dispatch timed out after ${String(y)}ms`,"TimeoutError")),g=i=>{throw i instanceof Error&&i.name==="TimeoutError"?U(e,r.__lunoraRef,y):i};let c;try{try{c=await s(I,{body:JSON.stringify({args:o??{},functionPath:r.__lunoraRef,id:u.dedupId,shardKey:u.shardKey}),headers:p,method:"POST",signal:m.signal})}catch(h){return g(h)}if(!c.ok){let h;try{h=await c.text()}catch(O){return g(O)}throw D(e,c.status,h,u.messageId)}let i;try{i=await c.text()}catch(h){return g(h)}if(i.length===0)return;try{return JSON.parse(i)}catch{throw new d("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(c.status)}): ${i}`,{status:c.status})}}finally{m.dispose()}}};export{M as F};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{LunoraError as r}from"@lunora/errors";import{collectAgenticMemoryTools as h}from"./collectAgenticMemoryTools-BeMWT2qt.mjs";import{agentAsTool as f}from"./agentAsTool-Xg7YCl5P.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
|
-
|
|
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,3 +0,0 @@
|
|
|
1
|
-
import{d as J,b as O}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 F}from"./buildModelMessages-Y4tGo1T9.mjs";import{agentBindingName as q}from"../naming.mjs";import{toFunctionReference as g}from"./AGENT_MODULE-M4D1EejI.mjs";const et=8,ot=e=>Number.isInteger(e)&&e>0?e:0,j=e=>e===void 0?"null":JSON.stringify(e),nt=e=>e===void 0?[]:[e].flat(),at=async(e,t)=>(await Promise.all(e.map(async o=>o({steps:t})))).some(Boolean),st=(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},rt=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))},it="WorkflowTimeoutError",ct=e=>e instanceof Error&&e.name===it,P=4320*60*1e3,ut={day:864e5,hour:36e5,minute:6e4,month:30*864e5,second:1e3,week:7*864e5,year:365*864e5},dt=/^(\d+(?:\.\d+)?) (day|hour|minute|month|second|week|year)s?$/u,pt=e=>{if(e===void 0)return P;if(typeof e=="number")return Math.min(e,O);const t=dt.exec(e);return t===null?P:Math.min(Number(t[1])*ut[t[2]],O)},lt=async(e,t)=>{const{agent:n,deleteMessage:o,instanceId:a,patchThread:r,persist:c,step:u}=e;await c({content:`Awaiting approval to run tool "${t.name}".`,messageKey:`${a}:approval:${t.id}`,role:"tool",status:"awaiting_approval",toolCallId:t.id,toolName:t.name}),await r({status:"awaiting_input"});const i=await u.waitForEvent(`approval:${t.id}`,{timeout:pt(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(!ct(p))throw p;return{decision:"reject",note:"approval timed out"}});return await o(`${a}:approval:${t.id}`),await r({status:"running"}),i},mt=async(e,t)=>{const{depth:n,env:o,getState:a,instanceId:r,onTokenDelta:c,persist:u,run:i,setState:p,step:s,threadKey:d,tools:l}=e,m=`tool:${t.name}:${t.id}`,h=l[t.name],f=`${r}:tool:${t.id}`;if(!h){await u({content:`Error: unknown tool "${t.name}"`,messageKey:f,role:"tool",stepName:m,toolCallId:t.id,toolName:t.name});return}const v={depth:n,env:o,getState:a,idempotencyKey:m,reportProgress:R=>{c?.({data:R,kind:"progress",threadKey:d,toolCallId:t.id})},run:i,setState:p,step:s,threadKey:d,toolCallId:t.id},x={depth:n,env:o,getState:a,idempotencyKey:m,run:i,threadKey:d,toolCallId:t.id},S=`tool:approval-gate:${t.id}`;let C;if(await rt(h,t.input,s,S,x)){const{decision:R,note:K}=await lt(e,t);if(R==="reject"){const I=K===void 0?"":` Reason: ${K}`;await u({content:`Tool "${t.name}" was rejected by the user and not run.${I}`,messageKey:f,role:"tool",status:"rejected",stepName:m,toolCallId:t.id,toolName:t.name});return}C="approved"}const M=await s.do(m,()=>Promise.resolve(h.execute(t.input,v)));await u({content:typeof M=="string"?M:j(M),messageKey:f,role:"tool",stepName:m,...C===void 0?{}:{status:C},toolCallId:t.id,toolName:t.name})},yt=(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}},vt=(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)}},gt=async(e,t)=>{const{agent:n,compact:o,env:a}=e,r=vt(t,n.compaction);if(r===void 0||o===void 0)return{history:t,summary:void 0};try{const c=await o({env:a,messages:F({history:r.older}),model:n.compaction?.model??n.model});return c.length>0?{history:r.recent,summary:c}:{history:t,summary:void 0}}catch{return{history:t,summary:void 0}}},ht=async(e,t,n)=>{const{agent:o,env:a,generate:r,instructions:c,listMessages:u,memoryContext:i,onTokenDelta:p,run:s,step:d,streamGenerate:l,threadKey:m}=e;return d.do(`llm:turn:${String(t)}`,async()=>{const h=await s(u,{key:m}),{history:f,summary:$}=await gt(e,h);let v={activeTools:o.activeTools,messages:F({history:f,instructions:c,memoryContext:i,summary:$}),model:void 0,toolChoice:o.toolChoice};o.prepareStep&&(v=yt(v,await o.prepareStep({messages:v.messages,stepNumber:t,steps:n}),a));const x={messages:v.messages,...v.activeTools===void 0?{}:{activeTools:v.activeTools},...v.model===void 0?{}:{model:v.model},...v.toolChoice===void 0?{}:{toolChoice:v.toolChoice}};return l&&p?l(x,S=>{p({text:S,threadKey:m,turn:t})}):r(x)})},D=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))},ft=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}}),U=e=>{const t=e?.context;return typeof t=="string"&&t.length>0?t:void 0},wt=e=>J({depth:e?.depth,fanOut:e?.fanOut,maxNodes:e?.maxNodes,maxSeeds:e?.maxSeeds}),Tt=async(e,t,n,o)=>{if(e.source===void 0)return;const a=g(e.source),{topK:r}=e,c=T("memory:retrieve",e.key),u=await n.do(c,async()=>o(a,{query:t,...r===void 0?{}:{topK:r}}));return U(u)},xt=async(e,t,n,o,a,r)=>{if(n===void 0)return;const c=T("memory:traverse",e.key),u=await a.do(c,async()=>r(o,{owner:n,query:t,...wt(e.graph)}));return U(u)},St=async(e,t,n,o,a)=>{if(t===void 0)return;const r=T("memory:recall",e.key),c={owner:t,...e.episodic?.recall===void 0?{}:{limit:e.episodic.recall}},u=await o.do(r,async()=>a(n,c));return U(u)},Ct=async(e,t)=>e.kind==="episodic"?St(e,t.owner,t.episodeRecall,t.step,t.run):e.kind==="graph"?xt(e,t.input,t.owner,t.graphTraverse,t.step,t.run):Tt(e,t.input,t.step,t.run),Mt=e=>{const t=e.findIndex(n=>n.kind==="episodic");return e.filter((n,o)=>n.kind!=="episodic"||o===t)},Rt=async(e,t,n,o,a,r)=>{const c=Mt(Y(e));if(c.length===0)return;const u=g(o.graphTraverse),i=g(o.episodeRecall),p=[];for(const s of c){const d=await Ct(s,{episodeRecall:i,graphTraverse:u,input:t,owner:n,run:r,step:a});d!==void 0&&p.push(d)}return p.length>0?p.join(`
|
|
2
|
-
|
|
3
|
-
`):void 0},kt=async e=>{const{agent:t,env:n,extractGraph:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const d=Z(t);if(d!==void 0)try{const l={assistantText:a,env:n,model:d.graph?.extractionModel??t.model,userInput:r},m=await s.do(T("memory:extract",d.key),async()=>o(l));await p(g(i.graphUpsert),{...m,messageKey:`${c}:${T("extract",d.key)}`,owner:u})}catch{}},$t=async e=>{const{agent:t,env:n,extractEpisode:o,finalText:a,input:r,instanceId:c,owner:u,paths:i,run:p,step:s,threadKey:d}=e;if(o===void 0||u===void 0||a===void 0||a.length===0)return;const l=tt(t);if(l!==void 0)try{const m={assistantText:a,env:n,model:l.episodic?.extractionModel??t.model,userInput:r},{summary:h}=await s.do(T("memory:episode",l.key),async()=>o(m));await p(g(i.episodeUpsert),{messageKey:`${c}:${T("episode",l.key)}`,owner:u,summary:h,threadKey:d})}catch{}},Kt=async(e,t,n)=>{const o=e[q(t)];if(!(!o||typeof o.get!="function"))try{await(await o.get(n)).terminate()}catch{}},Et="12 hours",Nt=async(e,t,n)=>{await e.waitForEvent(`dequeue:${n}`,{timeout:Et,type:`agent-dequeue:${t}:${n}`})},It=async(e,t,n)=>{const o=e.env[q(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{}},At=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{}},Ut=async(e,t,n,o,a)=>{const{instanceId:r,persist:c}=e,u=n.usage===void 0?{}:{usage:n.usage};if(n.toolCalls.length===0){const i=n.output!==void 0&&n.text.length===0?j(n.output):n.text;return await c({content:i,messageKey:`${r}:assistant:${String(t)}`,role:"assistant"}),await D(e,{text:n.text,toolCalls:[],turn:t,...u}),{final:{stopped:"final",text:n.text,turns:t+1,...n.output===void 0?{}:{output:n.output}}}}await c({content:n.text,messageKey:`${r}:assistant:${String(t)}`,role:"assistant",toolCalls:n.toolCalls});for(const i of n.toolCalls)await mt(e,i);if(await D(e,{text:n.text,toolCalls:n.toolCalls,turn:t,...u}),o.push(ft(n)),a.length>0&&await at(a,o))return"stopCondition"},_t=async(e,t,n,o)=>{const a=[];let r,c=!1,u=0;for(let i=0;i<t;i+=1){const p=await ht(e,i,a);o.value=st(o.value,p.usage),u=i+1;const s=await Ut(e,i,p,a,n);if(s==="stopCondition"){c=!0;break}if(s!==void 0){r=s.final;break}}return{final:r,stoppedByCondition:c,turnsRun:u}},Bt=async e=>{const{agent:t,compact:n,env:o,exportName:a,extractEpisode:r,extractGraph:c,generate:u,instanceId:i,onTokenDelta:p,params:s,paths:d,run:l,step:m,streamGenerate:h}=e,f=t.maxTurns??et,$=nt(t.stopWhen),v=g(d.appendMessage),x=g(d.completeRun),S=g(d.ensureThread),C=g(d.listMessages),M=g(d.deleteMessage),R=g(d.patchThread),K=g(d.setState),I=g(d.state),_=async y=>{await l(v,{threadKey:s.threadKey,...y})},B=async y=>{await l(R,{key:s.threadKey,...y})},G=async y=>{await l(M,{messageKey:y,threadKey:s.threadKey})},b=async()=>{await _({content:s.input,messageKey:`${i}:user`,role:"user"})},E=async y=>{const N=await l(x,{instanceId:i,key:s.threadKey,...y});N?.dequeued!==void 0&&await It({env:o,exportName:a,step:m},s.threadKey,N.dequeued)},L=async()=>await l(I,{key:s.threadKey}),W=async y=>{await l(K,{key:s.threadKey,state:y})},A=await l(S,{agent:a,instanceId:i,key:s.threadKey,...t.initialState===void 0?{}:{initialState:t.initialState},...t.onConcurrentRun===void 0?{}:{onConcurrentRun:t.onConcurrentRun},...s.owner===void 0?{}:{owner:s.owner},...s.title===void 0?{}:{title:s.title}});A?.outcome==="replaced"&&await Kt(o,a,A.priorInstanceId);const z=await Rt(t,s.input,s.owner,d,m,l),H=typeof t.instructions=="function"?t.instructions({env:o,input:s.input,threadKey:s.threadKey}):t.instructions,V={agent:t,compact:n,depth:ot(s.depth),env:o,generate:u,getState:L,instanceId:i,instructions:H,listMessages:C,memoryContext:z,onTokenDelta:p,deleteMessage:G,patchThread:B,persist:_,run:l,setState:W,step:m,streamGenerate:h,threadKey:s.threadKey,tools:t.tools??{}},k={value:void 0};try{A?.outcome==="queued"&&await Nt(m,s.threadKey,i),await b();const{final:y,stoppedByCondition:N,turnsRun:X}=await _t(V,f,$,k),w=k.value===void 0?{}:{usage:k.value};return await kt({agent:t,env:o,extractGraph:c,finalText:y?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:m}),await $t({agent:t,env:o,extractEpisode:r,finalText:y?.text,input:s.input,instanceId:i,owner:s.owner,paths:d,run:l,step:m,threadKey:s.threadKey}),y?(await At(t,{env:o,params:s,step:m},{...y,...w}),await E({status:"idle",...w}),{...y,...w}):N?(await E({status:"idle",...w}),{stopped:"stopCondition",turns:X,...w}):(await E({error:`agent stopped: maxTurns (${String(f)}) reached`,status:"error",...w}),{stopped:"maxTurns",turns:f,...w})}catch(y){throw await E({error:y instanceof Error?y.message:String(y),status:"error",...k.value===void 0?{}:{usage:k.value}}),y}};export{gt as compactHistory,Bt as runAgentLoop,vt as splitForCompaction};
|