@toolpack-sdk/agents 2.1.0 → 2.2.0

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.
@@ -1 +1 @@
1
- "use strict";var R=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var U=(e,t)=>{for(var n in t)R(e,n,{get:t[n],enumerable:!0})},H=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of O(t))!G.call(e,s)&&s!==n&&R(e,s,{get:()=>t[s],enumerable:!(i=B(t,s))||i.enumerable});return e};var W=e=>H(R({},"__esModule",{value:!0}),e);var Q={};U(Q,{CAPTURE_INTERCEPTOR_MARKER:()=>A,DepthExceededError:()=>C,InvocationDepthExceededError:()=>x,SKIP_SENTINEL:()=>h,composeChain:()=>_,createAddressCheckInterceptor:()=>M,createCaptureInterceptor:()=>F,createDepthGuardInterceptor:()=>L,createEventDedupInterceptor:()=>b,createIntentClassifierInterceptor:()=>j,createNoiseFilterInterceptor:()=>N,createParticipantResolverInterceptor:()=>P,createRateLimitInterceptor:()=>D,createSelfFilterInterceptor:()=>k,createTracerInterceptor:()=>$,executeChain:()=>K,isSkipSentinel:()=>y,skip:()=>v});module.exports=W(Q);var h=Symbol("interceptor-skip-sentinel");function y(e){return e===h}function v(){return h}var x=class extends Error{constructor(t,n){super(`Invocation depth ${t} exceeds maximum ${n}`),this.name="InvocationDepthExceededError"}};function _(e,t,n,i,s={}){let o=s.maxInvocationDepth??5;return{async execute(r){let g=(u=>({agent:t,channel:n,registry:i,invocationDepth:u,delegateAndWait:async(l,d)=>{let p=u+1;if(p>o)throw new x(p,o);if(!i)throw new Error(`Cannot delegate to "${l}": agent is running in standalone mode without a registry`);let m=i.getAgent(l);if(!m)throw new Error(`Agent "${l}" not found for delegation`);let f={message:d.message??"",intent:d.intent,data:d.data,context:d.context,conversationId:d.conversationId??r.conversationId??`delegation-${Date.now()}`};return await m.invokeAgent(f)},skip:v}))(0),a=async u=>{let l=u??r;return await t.invokeAgent(l)};for(let u=e.length-1;u>=0;u--){let l=e[u],d=a;a=async p=>await l(p??r,g,d)}return await a()}}}async function K(e,t){let n=await e.execute(t);return n===h?null:n}var w=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;has(t){return this.cache.has(t)}set(t,n){if(this.cache.has(t)&&this.cache.delete(t),this.cache.size>=this.maxSize){let i=this.cache.keys().next().value;i!==void 0&&this.cache.delete(i)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}};function b(e={}){let t=e.maxCacheSize??1e3,n=e.getEventId??(s=>s.context?.eventId),i=new w(t);return async(s,o,r)=>{let c=n(s);if(c){if(i.has(c))return e.onDuplicate?.(c,s),o.logger?.debug(`Event dedup: dropping duplicate event ${c}`,{eventId:c}),o.skip();i.set(c,!0)}return await r()}}function N(e){let t=e.getSubtype??(i=>i.context?.subtype),n=new Set(e.denySubtypes);return async(i,s,o)=>{let r=t(i);return r&&n.has(r)?(e.onFiltered?.(r,i),s.logger?.debug(`Noise filter: dropping message with subtype "${r}"`,{subtype:r}),s.skip()):await o()}}function k(e){return async(t,n,i)=>{let s=e.getSenderId(t),o=e.agentId??n.agent.name;return s&&s===o?(e.onSelfMessage?.(s,t),n.logger?.debug(`Self filter: dropping self-message from ${s}`,{senderId:s,agentId:o}),n.skip()):await i()}}var S=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;get(t){let n=this.cache.get(t);return n!==void 0&&(this.cache.delete(t),this.cache.set(t,n)),n}set(t,n){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.maxSize){let i=this.cache.keys().next().value;i!==void 0&&this.cache.delete(i)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}},E=class{constructor(t,n,i){this.capacity=t;this.refillRate=n;this.refillInterval=i;this.tokens=t,this.lastRefill=Date.now()}capacity;refillRate;refillInterval;tokens;lastRefill;consume(t=1){return this.refill(),this.tokens>=t?(this.tokens-=t,!0):!1}refill(){let t=Date.now(),n=t-this.lastRefill,i=Math.floor(n/this.refillInterval*this.refillRate);i>0&&(this.tokens=Math.min(this.capacity,this.tokens+i),this.lastRefill=t)}getTokens(){return this.refill(),this.tokens}};function D(e){let t=e.tokensPerInterval??10,n=e.interval??6e4,i=e.maxBuckets??1e3,s=e.onExceeded??"skip",o=new S(i);return async(r,c,g)=>{let a=e.getKey(r),u=o.get(a);if(u||(u=new E(t,t,n),o.set(a,u)),!u.consume()){if(e.onRateLimited?.(a,r),c.logger?.warn(`Rate limit exceeded for key: ${a}`,{key:a}),s==="reject")throw new Error("Rate limit exceeded. Please try again later.");return c.skip()}return await g()}}function P(e={}){return async(t,n,i)=>{let s;if(e.resolveParticipant)s=await e.resolveParticipant(t);else if(typeof n.channel.resolveParticipant=="function")try{s=await n.channel.resolveParticipant(t)}catch(r){n.logger?.warn("Channel resolveParticipant threw; falling back",{error:r instanceof Error?r.message:"Unknown error"})}let o=s??t.participant;if(o){let r={...t,participant:o,context:{...t.context,_participant:o}};return e.onResolved?.(r,o),n.logger?.debug("Resolved participant",{participantId:o.id,participantKind:o.kind}),await i(r)}return await i()}}var T=require("crypto");function q(e){let t=e.context??{},n=t.channelType;return n==="im"||n==="private"||n==="dm"?"dm":t.threadId!==void 0?"thread":"channel"}var A=Symbol.for("toolpack:capture-history");function F(e){let t=e.captureAgentReplies??!0,n=e.getScope??q,i=e.getMessageId??(r=>r.context?.messageId??r.context?.eventId??(0,T.randomUUID)()),s=e.getMentions??(r=>r.context?.mentions??[]),o=async(r,c,g)=>{let a=r.conversationId;if(!a)return c.logger?.warn("[capture-history] Message has no conversationId \u2014 skipping capture"),await g();let u=r.participant;if(u){let d={id:i(r),conversationId:a,participant:u,content:r.message??"",timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,messageId:r.context?.messageId,mentions:s(r),channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(d),e.onCaptured?.(d),c.logger?.debug("[capture-history] Captured inbound message",{messageId:d.id,participantId:u.id,conversationId:a})}catch(p){c.logger?.warn("[capture-history] Failed to store inbound message",{error:p instanceof Error?p.message:String(p)})}}let l=await g();if(t&&!y(l)&&l.output!=null){let d={kind:"agent",id:c.agent.name,displayName:c.agent.name},p={id:(0,T.randomUUID)(),conversationId:a,participant:d,content:l.output,timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(p),e.onCaptured?.(p),c.logger?.debug("[capture-history] Captured agent reply",{messageId:p.id,agentId:c.agent.name,conversationId:a})}catch(m){c.logger?.warn("[capture-history] Failed to store agent reply",{error:m instanceof Error?m.message:String(m)})}}return l};return o[A]=!0,o}function J(e,t){let n=t.toLowerCase();if(!e.toLowerCase().includes(n))return!1;let s=[],o=/```[\s\S]*?```/g,r;for(;(r=o.exec(e))!==null;)s.push([r.index,r.index+r[0].length]);let c=/`[^`\n]*`/g;for(;(r=c.exec(e))!==null;){let d=r.index,p=d+r[0].length;s.some(([f,z])=>d>=f&&p<=z)||s.push([d,p])}if(s.length===0)return!1;s.sort((d,p)=>d[0]-p[0]);let g="",a=0;for(let[d,p]of s)d>a&&(g+=e.slice(a,d)),a=Math.max(a,p);return a<e.length&&(g+=e.slice(a)),g.toLowerCase().includes(n)?!1:s.some(([d,p])=>e.slice(d,p).toLowerCase().includes(n))}function M(e){return async(t,n,i)=>{let s=e.getMessageText(t)??"";if(e.isDirectMessage?.(t)){let p={...t,context:{...t.context,_addressCheck:"direct",_isDM:!0}};return e.onClassified?.("direct",t),await i(p)}let o="ambiguous",r=s.toLowerCase(),c=e.agentName.toLowerCase(),g=p=>p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=g(c),u=e.agentId?`|^@${g(e.agentId)}\\b`:"";if(new RegExp(`^(hey\\s+)?@?${a}\\b${u}`,"i").test(r))o="direct";else if(new RegExp(`\\b(my|our|the)\\s+${a}\\b`,"i").test(r))o="ambiguous";else if(J(s,e.agentName))o="ignore";else if(/^https?:\/\//.test(s))o="ignore";else if(e.getMentions){let p=e.getMentions(t),m=p.some(f=>f.toLowerCase()===c||f===e.agentId);m&&p.length>1?o="indirect":m&&(o="ambiguous")}else r.includes(c)?o="ambiguous":o="passive";let d={...t,context:{...t.context,_addressCheck:o}};return e.onClassified?.(o,t),n.logger?.debug(`Address check classified as: ${o}`,{result:o}),await i(d)}}function j(e){let t=e.classifierAgentName??"intent-classifier";return async(n,i,s)=>{let o=n.context?._addressCheck;if(o==="direct")return await s();if(o==="ignore"||o==="passive")return e.onClassified?.(o,n),i.skip();let r=e.getMessageText(n)??"";if(!r.trim())return await s();let c={message:r,agentName:e.agentName,agentId:e.agentId,senderName:e.getSenderName(n),channelName:e.getChannelName(n),isDirectMessage:e.isDirectMessage?.(n)??!1,recentContext:e.getRecentContext?.(n)};try{let a=(await i.delegateAndWait(t,{message:"classify",data:c,conversationId:n.conversationId})).output.trim();e.onClassified?.(a,n),i.logger?.debug(`Intent classified as: ${a}`,{classification:a});let u={...n,context:{...n.context,_intentClassification:a}};return a==="direct"?await s(u):i.skip()}catch(g){return i.logger?.error("Intent classification failed, allowing message",{error:g instanceof Error?g.message:"Unknown error"}),await s()}}}var C=class extends Error{constructor(n,i){super(`Maximum invocation depth exceeded: ${n} > ${i}`);this.currentDepth=n;this.maxDepth=i;this.name="DepthExceededError"}currentDepth;maxDepth};function L(e={}){let t=e.maxDepth??5;return async(n,i,s)=>{if(i.invocationDepth>t)throw e.onDepthExceeded?.(i.invocationDepth,t,n),i.logger?.error(`Depth guard: invocation depth ${i.invocationDepth} exceeds maximum ${t}`,{currentDepth:i.invocationDepth,maxDepth:t}),new C(i.invocationDepth,t);return await s()}}function $(e={}){let t=e.level??"debug",n=e.includeInputData??!1,i=e.includeResultOutput??!1;return async(s,o,r)=>{if(e.shouldTrace&&!e.shouldTrace(s))return await r();let c=t==="info"?o.logger?.info:o.logger?.debug;c?.("Interceptor entry",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:s.conversationId,intent:s.intent,input:n?s:void 0});let g=performance.now();try{let a=await r(),u=performance.now()-g;return y(a)?c?.("Interceptor exit: skipped",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:s.conversationId,durationMs:u.toFixed(2)}):c?.("Interceptor exit: success",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:s.conversationId,durationMs:u.toFixed(2),outputLength:a.output.length,result:i?a:void 0}),a}catch(a){let u=performance.now()-g;throw o.logger?.error("Interceptor exit: error",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:s.conversationId,durationMs:u.toFixed(2),error:a instanceof Error?a.message:"Unknown error",errorType:a?.constructor?.name}),a}}}0&&(module.exports={CAPTURE_INTERCEPTOR_MARKER,DepthExceededError,InvocationDepthExceededError,SKIP_SENTINEL,composeChain,createAddressCheckInterceptor,createCaptureInterceptor,createDepthGuardInterceptor,createEventDedupInterceptor,createIntentClassifierInterceptor,createNoiseFilterInterceptor,createParticipantResolverInterceptor,createRateLimitInterceptor,createSelfFilterInterceptor,createTracerInterceptor,executeChain,isSkipSentinel,skip});
1
+ "use strict";var T=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var V=(e,t)=>{for(var n in t)T(e,n,{get:t[n],enumerable:!0})},q=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of H(t))!W.call(e,i)&&i!==n&&T(e,i,{get:()=>t[i],enumerable:!(r=G(t,i))||r.enumerable});return e};var J=e=>q(T({},"__esModule",{value:!0}),e);var Y={};V(Y,{CAPTURE_INTERCEPTOR_MARKER:()=>R,DepthExceededError:()=>C,InvocationDepthExceededError:()=>x,OTelSpanStatusCode:()=>b,SKIP_SENTINEL:()=>y,composeChain:()=>B,createAddressCheckInterceptor:()=>L,createCaptureInterceptor:()=>j,createDepthGuardInterceptor:()=>_,createEventDedupInterceptor:()=>k,createIntentClassifierInterceptor:()=>$,createNoiseFilterInterceptor:()=>N,createOTelTracerInterceptor:()=>z,createParticipantResolverInterceptor:()=>M,createRateLimitInterceptor:()=>F,createSelfFilterInterceptor:()=>E,createTracerInterceptor:()=>K,executeChain:()=>U,isSkipSentinel:()=>h,skip:()=>A});module.exports=J(Y);var y=Symbol("interceptor-skip-sentinel");function h(e){return e===y}function A(){return y}var x=class extends Error{constructor(t,n){super(`Invocation depth ${t} exceeds maximum ${n}`),this.name="InvocationDepthExceededError"}};function B(e,t,n,r,i={}){let s=i.maxInvocationDepth??5;return{async execute(o){let d=(a=>({agent:t,channel:n,registry:r,invocationDepth:a,delegateAndWait:async(g,p)=>{let l=a+1;if(l>s)throw new x(l,s);if(!r)throw new Error(`Cannot delegate to "${g}": agent is running in standalone mode without a registry`);let I=r.getAgent(g);if(!I)throw new Error(`Agent "${g}" not found for delegation`);let f={message:p.message??"",intent:p.intent,data:p.data,context:p.context,conversationId:p.conversationId??o.conversationId??`delegation-${Date.now()}`};return await I.invokeAgent(f)},skip:A}))(0),c=async a=>{let g=a??o;return await t.invokeAgent(g)};for(let a=e.length-1;a>=0;a--){let g=e[a],p=c;c=async l=>await g(l??o,d,p)}return await c()}}}async function U(e,t){let n=await e.execute(t);return n===y?null:n}var w=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;has(t){return this.cache.has(t)}set(t,n){if(this.cache.has(t)&&this.cache.delete(t),this.cache.size>=this.maxSize){let r=this.cache.keys().next().value;r!==void 0&&this.cache.delete(r)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}};function k(e={}){let t=e.maxCacheSize??1e3,n=e.getEventId??(i=>i.context?.eventId),r=new w(t);return async(i,s,o)=>{let u=n(i);if(u){if(r.has(u))return e.onDuplicate?.(u,i),s.logger?.debug(`Event dedup: dropping duplicate event ${u}`,{eventId:u}),s.skip();r.set(u,!0)}return await o()}}function N(e){let t=e.getSubtype??(r=>r.context?.subtype),n=new Set(e.denySubtypes);return async(r,i,s)=>{let o=t(r);return o&&n.has(o)?(e.onFiltered?.(o,r),i.logger?.debug(`Noise filter: dropping message with subtype "${o}"`,{subtype:o}),i.skip()):await s()}}function E(e){return async(t,n,r)=>{let i=e.getSenderId(t),s=e.agentId??n.agent.name;return i&&i===s?(e.onSelfMessage?.(i,t),n.logger?.debug(`Self filter: dropping self-message from ${i}`,{senderId:i,agentId:s}),n.skip()):await r()}}var P=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;get(t){let n=this.cache.get(t);return n!==void 0&&(this.cache.delete(t),this.cache.set(t,n)),n}set(t,n){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.maxSize){let r=this.cache.keys().next().value;r!==void 0&&this.cache.delete(r)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}},D=class{constructor(t,n,r){this.capacity=t;this.refillRate=n;this.refillInterval=r;this.tokens=t,this.lastRefill=Date.now()}capacity;refillRate;refillInterval;tokens;lastRefill;consume(t=1){return this.refill(),this.tokens>=t?(this.tokens-=t,!0):!1}refill(){let t=Date.now(),n=t-this.lastRefill,r=Math.floor(n/this.refillInterval*this.refillRate);r>0&&(this.tokens=Math.min(this.capacity,this.tokens+r),this.lastRefill=t)}getTokens(){return this.refill(),this.tokens}};function F(e){let t=e.tokensPerInterval??10,n=e.interval??6e4,r=e.maxBuckets??1e3,i=e.onExceeded??"skip",s=new P(r);return async(o,u,d)=>{let c=e.getKey(o),a=s.get(c);if(a||(a=new D(t,t,n),s.set(c,a)),!a.consume()){if(e.onRateLimited?.(c,o),u.logger?.warn(`Rate limit exceeded for key: ${c}`,{key:c}),i==="reject")throw new Error("Rate limit exceeded. Please try again later.");return u.skip()}return await d()}}function M(e={}){return async(t,n,r)=>{let i;if(e.resolveParticipant)i=await e.resolveParticipant(t);else if(typeof n.channel.resolveParticipant=="function")try{i=await n.channel.resolveParticipant(t)}catch(o){n.logger?.warn("Channel resolveParticipant threw; falling back",{error:o instanceof Error?o.message:"Unknown error"})}let s=i??t.participant;if(s){let o={...t,participant:s,context:{...t.context,_participant:s}};return e.onResolved?.(o,s),n.logger?.debug("Resolved participant",{participantId:s.id,participantKind:s.kind}),await r(o)}return await r()}}var O=require("crypto");function Q(e){let t=e.context??{},n=t.channelType;return n==="im"||n==="private"||n==="dm"?"dm":t.threadId!==void 0?"thread":"channel"}var R=Symbol.for("toolpack:capture-history");function j(e){let t=e.captureAgentReplies??!0,n=e.getScope??Q,r=e.getMessageId??(o=>o.context?.messageId??o.context?.eventId??(0,O.randomUUID)()),i=e.getMentions??(o=>o.context?.mentions??[]),s=async(o,u,d)=>{let c=o.conversationId;if(!c)return u.logger?.warn("[capture-history] Message has no conversationId \u2014 skipping capture"),await d();let a=o.participant;if(a){let p={id:r(o),conversationId:c,participant:a,content:o.message??"",timestamp:new Date().toISOString(),scope:n(o),metadata:{channelType:o.context?.channelType,threadId:o.context?.threadId,messageId:o.context?.messageId,mentions:i(o),channelName:o.context?.channelName,channelId:o.context?.channelId}};try{await e.store.append(p),e.onCaptured?.(p),u.logger?.debug("[capture-history] Captured inbound message",{messageId:p.id,participantId:a.id,conversationId:c})}catch(l){u.logger?.warn("[capture-history] Failed to store inbound message",{error:l instanceof Error?l.message:String(l)})}}let g=await d();if(t&&!h(g)&&g.output!=null){let p={kind:"agent",id:u.agent.name,displayName:u.agent.name},l={id:(0,O.randomUUID)(),conversationId:c,participant:p,content:g.output,timestamp:new Date().toISOString(),scope:n(o),metadata:{channelType:o.context?.channelType,threadId:o.context?.threadId,channelName:o.context?.channelName,channelId:o.context?.channelId}};try{await e.store.append(l),e.onCaptured?.(l),u.logger?.debug("[capture-history] Captured agent reply",{messageId:l.id,agentId:u.agent.name,conversationId:c})}catch(I){u.logger?.warn("[capture-history] Failed to store agent reply",{error:I instanceof Error?I.message:String(I)})}}return g};return s[R]=!0,s}function X(e,t){let n=t.toLowerCase();if(!e.toLowerCase().includes(n))return!1;let i=[],s=/```[\s\S]*?```/g,o;for(;(o=s.exec(e))!==null;)i.push([o.index,o.index+o[0].length]);let u=/`[^`\n]*`/g;for(;(o=u.exec(e))!==null;){let p=o.index,l=p+o[0].length;i.some(([f,S])=>p>=f&&l<=S)||i.push([p,l])}if(i.length===0)return!1;i.sort((p,l)=>p[0]-l[0]);let d="",c=0;for(let[p,l]of i)p>c&&(d+=e.slice(c,p)),c=Math.max(c,l);return c<e.length&&(d+=e.slice(c)),d.toLowerCase().includes(n)?!1:i.some(([p,l])=>e.slice(p,l).toLowerCase().includes(n))}function L(e){return async(t,n,r)=>{let i=e.getMessageText(t)??"";if(e.isDirectMessage?.(t)){let l={...t,context:{...t.context,_addressCheck:"direct",_isDM:!0}};return e.onClassified?.("direct",t),await r(l)}let s="ambiguous",o=i.toLowerCase(),u=e.agentName.toLowerCase(),d=l=>l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=d(u),a=e.agentId?`|^@${d(e.agentId)}\\b`:"";if(new RegExp(`^(hey\\s+)?@?${c}\\b${a}`,"i").test(o))s="direct";else if(new RegExp(`\\b(my|our|the)\\s+${c}\\b`,"i").test(o))s="ambiguous";else if(X(i,e.agentName))s="ignore";else if(/^https?:\/\//.test(i))s="ignore";else if(e.getMentions){let l=e.getMentions(t),I=l.some(f=>f.toLowerCase()===u||f===e.agentId);I&&l.length>1?s="indirect":I&&(s="ambiguous")}else o.includes(u)?s="ambiguous":s="passive";let p={...t,context:{...t.context,_addressCheck:s}};return e.onClassified?.(s,t),n.logger?.debug(`Address check classified as: ${s}`,{result:s}),await r(p)}}function $(e){let t=e.classifierAgentName??"intent-classifier";return async(n,r,i)=>{let s=n.context?._addressCheck;if(s==="direct")return await i();if(s==="ignore"||s==="passive")return e.onClassified?.(s,n),r.skip();let o=e.getMessageText(n)??"";if(!o.trim())return await i();let u={message:o,agentName:e.agentName,agentId:e.agentId,senderName:e.getSenderName(n),channelName:e.getChannelName(n),isDirectMessage:e.isDirectMessage?.(n)??!1,recentContext:e.getRecentContext?.(n)};try{let c=(await r.delegateAndWait(t,{message:"classify",data:u,conversationId:n.conversationId})).output.trim();e.onClassified?.(c,n),r.logger?.debug(`Intent classified as: ${c}`,{classification:c});let a={...n,context:{...n.context,_intentClassification:c}};return c==="direct"?await i(a):r.skip()}catch(d){return r.logger?.error("Intent classification failed, allowing message",{error:d instanceof Error?d.message:"Unknown error"}),await i()}}}var C=class extends Error{constructor(n,r){super(`Maximum invocation depth exceeded: ${n} > ${r}`);this.currentDepth=n;this.maxDepth=r;this.name="DepthExceededError"}currentDepth;maxDepth};function _(e={}){let t=e.maxDepth??5;return async(n,r,i)=>{if(r.invocationDepth>t)throw e.onDepthExceeded?.(r.invocationDepth,t,n),r.logger?.error(`Depth guard: invocation depth ${r.invocationDepth} exceeds maximum ${t}`,{currentDepth:r.invocationDepth,maxDepth:t}),new C(r.invocationDepth,t);return await i()}}function K(e={}){let t=e.level??"debug",n=e.includeInputData??!1,r=e.includeResultOutput??!1;return async(i,s,o)=>{if(e.shouldTrace&&!e.shouldTrace(i))return await o();let u=t==="info"?s.logger?.info:s.logger?.debug;u?.("Interceptor entry",{agent:s.agent.name,channel:s.channel.name,depth:s.invocationDepth,conversationId:i.conversationId,intent:i.intent,input:n?i:void 0});let d=performance.now();try{let c=await o(),a=performance.now()-d;return h(c)?u?.("Interceptor exit: skipped",{agent:s.agent.name,channel:s.channel.name,depth:s.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2)}):u?.("Interceptor exit: success",{agent:s.agent.name,channel:s.channel.name,depth:s.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2),outputLength:c.output.length,result:r?c:void 0}),c}catch(c){let a=performance.now()-d;throw s.logger?.error("Interceptor exit: error",{agent:s.agent.name,channel:s.channel.name,depth:s.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2),error:c instanceof Error?c.message:"Unknown error",errorType:c?.constructor?.name}),c}}}var b=(r=>(r[r.UNSET=0]="UNSET",r[r.OK=1]="OK",r[r.ERROR=2]="ERROR",r))(b||{});function z(e={}){let{tracerProvider:t,tracerName:n="toolpack-agents",tracerVersion:r,recordSteps:i=!0,shouldTrace:s}=e,o=t?.getTracer(n,r);return async(u,d,c)=>{if(!o)return await c();if(s&&!s(u))return await c();let a=o.startSpan("agent.invocation");a.setAttribute("agent.name",d.agent.name),a.setAttribute("channel.name",d.channel.name??"unknown"),a.setAttribute("invocation.depth",d.invocationDepth),u.conversationId&&a.setAttribute("conversation.id",u.conversationId),u.intent&&a.setAttribute("agent.intent",u.intent);let g=performance.now();try{let p=await c(),l=performance.now()-g;if(a.setAttribute("duration.ms",Math.round(l)),h(p))a.setAttribute("result.skipped",!0),a.setStatus({code:1});else{if(a.setAttribute("result.output.length",p.output.length),i&&p.steps&&p.steps.length>0){a.setAttribute("steps.total",p.steps.length);let I=p.steps.filter(f=>f.status==="failed");I.length>0&&a.setAttribute("steps.failed",I.length),p.steps.forEach((f,S)=>{let v=`step.${S}`;a.setAttribute(`${v}.description`,f.description),a.setAttribute(`${v}.status`,f.status),f.result?.duration!==void 0&&a.setAttribute(`${v}.duration.ms`,f.result.duration),f.result?.toolsUsed&&f.result.toolsUsed.length>0&&a.setAttribute(`${v}.tools`,f.result.toolsUsed.join(","))})}a.setStatus({code:1})}return p}catch(p){let l=performance.now()-g;a.setAttribute("duration.ms",Math.round(l));let I=p instanceof Error?p:String(p);throw a.recordException(I),a.setStatus({code:2,message:p instanceof Error?p.message:String(p)}),p}finally{a.end()}}}0&&(module.exports={CAPTURE_INTERCEPTOR_MARKER,DepthExceededError,InvocationDepthExceededError,OTelSpanStatusCode,SKIP_SENTINEL,composeChain,createAddressCheckInterceptor,createCaptureInterceptor,createDepthGuardInterceptor,createEventDedupInterceptor,createIntentClassifierInterceptor,createNoiseFilterInterceptor,createOTelTracerInterceptor,createParticipantResolverInterceptor,createRateLimitInterceptor,createSelfFilterInterceptor,createTracerInterceptor,executeChain,isSkipSentinel,skip});
@@ -537,4 +537,91 @@ interface TracerConfig {
537
537
  */
538
538
  declare function createTracerInterceptor(config?: TracerConfig): Interceptor;
539
539
 
540
- export { type AddressCheckConfig, type AddressCheckResult, CAPTURE_INTERCEPTOR_MARKER, type CaptureHistoryConfig, type ComposedChain, DepthExceededError, type DepthGuardConfig, type EventDedupConfig, type IntentClassifierInterceptorConfig, Interceptor, InterceptorChainConfig, InterceptorResult, InvocationDepthExceededError, type NoiseFilterConfig, type ParticipantResolverConfig, type RateLimitConfig, type SelfFilterConfig, type TracerConfig, composeChain, createAddressCheckInterceptor, createCaptureInterceptor, createDepthGuardInterceptor, createEventDedupInterceptor, createIntentClassifierInterceptor, createNoiseFilterInterceptor, createParticipantResolverInterceptor, createRateLimitInterceptor, createSelfFilterInterceptor, createTracerInterceptor, executeChain };
540
+ /**
541
+ * OTel TracerProvider interface — mirrors @opentelemetry/api's TracerProvider
542
+ * without requiring the package as a hard dependency.
543
+ */
544
+ interface OTelTracerProvider {
545
+ getTracer(name: string, version?: string): OTelTracer;
546
+ }
547
+ interface OTelTracer {
548
+ startSpan(name: string, options?: OTelSpanOptions): OTelSpan;
549
+ }
550
+ interface OTelSpanOptions {
551
+ attributes?: Record<string, string | number | boolean>;
552
+ }
553
+ interface OTelSpan {
554
+ setAttribute(key: string, value: string | number | boolean): void;
555
+ setStatus(status: OTelSpanStatus): void;
556
+ recordException(error: Error | string): void;
557
+ end(): void;
558
+ }
559
+ interface OTelSpanStatus {
560
+ code: OTelSpanStatusCode;
561
+ message?: string;
562
+ }
563
+ declare enum OTelSpanStatusCode {
564
+ UNSET = 0,
565
+ OK = 1,
566
+ ERROR = 2
567
+ }
568
+ /**
569
+ * Configuration for the OTel tracer interceptor.
570
+ */
571
+ interface OTelTracerConfig {
572
+ /**
573
+ * An OTel-compatible TracerProvider (e.g. from @opentelemetry/sdk-node or any OTel-compatible backend).
574
+ * When omitted, the interceptor is a transparent no-op and adds zero overhead.
575
+ */
576
+ tracerProvider?: OTelTracerProvider;
577
+ /**
578
+ * Name used to identify the tracer in OTel (default: 'toolpack-agents').
579
+ */
580
+ tracerName?: string;
581
+ /**
582
+ * Version string attached to the tracer.
583
+ * When omitted, no version is passed to the OTel TracerProvider.
584
+ */
585
+ tracerVersion?: string;
586
+ /**
587
+ * Whether to record workflow step durations as span attributes (default: true).
588
+ */
589
+ recordSteps?: boolean;
590
+ /**
591
+ * Optional: filter which inputs to trace.
592
+ * Return false to skip tracing for a specific input.
593
+ */
594
+ shouldTrace?: (input: AgentInput) => boolean;
595
+ }
596
+ /**
597
+ * Creates an OTel-compatible tracer interceptor.
598
+ *
599
+ * Emits spans for:
600
+ * - Agent invocation (wraps the entire chain below it)
601
+ * - Each workflow step in the result (if recordSteps is true)
602
+ * - Errors thrown downstream
603
+ *
604
+ * Works with any OTel-compatible backend: Jaeger, Honeycomb, Datadog, OTLP, etc.
605
+ * When no tracerProvider is supplied it is a zero-cost transparent pass-through.
606
+ *
607
+ * @example
608
+ * ```ts
609
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-node';
610
+ *
611
+ * const provider = new NodeTracerProvider();
612
+ * provider.register();
613
+ *
614
+ * const registry = new AgentRegistry([
615
+ * {
616
+ * agent: MyAgent,
617
+ * channels: [slackChannel],
618
+ * interceptors: [
619
+ * createOTelTracerInterceptor({ tracerProvider: provider }),
620
+ * ],
621
+ * },
622
+ * ]);
623
+ * ```
624
+ */
625
+ declare function createOTelTracerInterceptor(config?: OTelTracerConfig): Interceptor;
626
+
627
+ export { type AddressCheckConfig, type AddressCheckResult, CAPTURE_INTERCEPTOR_MARKER, type CaptureHistoryConfig, type ComposedChain, DepthExceededError, type DepthGuardConfig, type EventDedupConfig, type IntentClassifierInterceptorConfig, Interceptor, InterceptorChainConfig, InterceptorResult, InvocationDepthExceededError, type NoiseFilterConfig, type OTelSpan, type OTelSpanOptions, type OTelSpanStatus, OTelSpanStatusCode, type OTelTracer, type OTelTracerConfig, type OTelTracerProvider, type ParticipantResolverConfig, type RateLimitConfig, type SelfFilterConfig, type TracerConfig, composeChain, createAddressCheckInterceptor, createCaptureInterceptor, createDepthGuardInterceptor, createEventDedupInterceptor, createIntentClassifierInterceptor, createNoiseFilterInterceptor, createOTelTracerInterceptor, createParticipantResolverInterceptor, createRateLimitInterceptor, createSelfFilterInterceptor, createTracerInterceptor, executeChain };
@@ -537,4 +537,91 @@ interface TracerConfig {
537
537
  */
538
538
  declare function createTracerInterceptor(config?: TracerConfig): Interceptor;
539
539
 
540
- export { type AddressCheckConfig, type AddressCheckResult, CAPTURE_INTERCEPTOR_MARKER, type CaptureHistoryConfig, type ComposedChain, DepthExceededError, type DepthGuardConfig, type EventDedupConfig, type IntentClassifierInterceptorConfig, Interceptor, InterceptorChainConfig, InterceptorResult, InvocationDepthExceededError, type NoiseFilterConfig, type ParticipantResolverConfig, type RateLimitConfig, type SelfFilterConfig, type TracerConfig, composeChain, createAddressCheckInterceptor, createCaptureInterceptor, createDepthGuardInterceptor, createEventDedupInterceptor, createIntentClassifierInterceptor, createNoiseFilterInterceptor, createParticipantResolverInterceptor, createRateLimitInterceptor, createSelfFilterInterceptor, createTracerInterceptor, executeChain };
540
+ /**
541
+ * OTel TracerProvider interface — mirrors @opentelemetry/api's TracerProvider
542
+ * without requiring the package as a hard dependency.
543
+ */
544
+ interface OTelTracerProvider {
545
+ getTracer(name: string, version?: string): OTelTracer;
546
+ }
547
+ interface OTelTracer {
548
+ startSpan(name: string, options?: OTelSpanOptions): OTelSpan;
549
+ }
550
+ interface OTelSpanOptions {
551
+ attributes?: Record<string, string | number | boolean>;
552
+ }
553
+ interface OTelSpan {
554
+ setAttribute(key: string, value: string | number | boolean): void;
555
+ setStatus(status: OTelSpanStatus): void;
556
+ recordException(error: Error | string): void;
557
+ end(): void;
558
+ }
559
+ interface OTelSpanStatus {
560
+ code: OTelSpanStatusCode;
561
+ message?: string;
562
+ }
563
+ declare enum OTelSpanStatusCode {
564
+ UNSET = 0,
565
+ OK = 1,
566
+ ERROR = 2
567
+ }
568
+ /**
569
+ * Configuration for the OTel tracer interceptor.
570
+ */
571
+ interface OTelTracerConfig {
572
+ /**
573
+ * An OTel-compatible TracerProvider (e.g. from @opentelemetry/sdk-node or any OTel-compatible backend).
574
+ * When omitted, the interceptor is a transparent no-op and adds zero overhead.
575
+ */
576
+ tracerProvider?: OTelTracerProvider;
577
+ /**
578
+ * Name used to identify the tracer in OTel (default: 'toolpack-agents').
579
+ */
580
+ tracerName?: string;
581
+ /**
582
+ * Version string attached to the tracer.
583
+ * When omitted, no version is passed to the OTel TracerProvider.
584
+ */
585
+ tracerVersion?: string;
586
+ /**
587
+ * Whether to record workflow step durations as span attributes (default: true).
588
+ */
589
+ recordSteps?: boolean;
590
+ /**
591
+ * Optional: filter which inputs to trace.
592
+ * Return false to skip tracing for a specific input.
593
+ */
594
+ shouldTrace?: (input: AgentInput) => boolean;
595
+ }
596
+ /**
597
+ * Creates an OTel-compatible tracer interceptor.
598
+ *
599
+ * Emits spans for:
600
+ * - Agent invocation (wraps the entire chain below it)
601
+ * - Each workflow step in the result (if recordSteps is true)
602
+ * - Errors thrown downstream
603
+ *
604
+ * Works with any OTel-compatible backend: Jaeger, Honeycomb, Datadog, OTLP, etc.
605
+ * When no tracerProvider is supplied it is a zero-cost transparent pass-through.
606
+ *
607
+ * @example
608
+ * ```ts
609
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-node';
610
+ *
611
+ * const provider = new NodeTracerProvider();
612
+ * provider.register();
613
+ *
614
+ * const registry = new AgentRegistry([
615
+ * {
616
+ * agent: MyAgent,
617
+ * channels: [slackChannel],
618
+ * interceptors: [
619
+ * createOTelTracerInterceptor({ tracerProvider: provider }),
620
+ * ],
621
+ * },
622
+ * ]);
623
+ * ```
624
+ */
625
+ declare function createOTelTracerInterceptor(config?: OTelTracerConfig): Interceptor;
626
+
627
+ export { type AddressCheckConfig, type AddressCheckResult, CAPTURE_INTERCEPTOR_MARKER, type CaptureHistoryConfig, type ComposedChain, DepthExceededError, type DepthGuardConfig, type EventDedupConfig, type IntentClassifierInterceptorConfig, Interceptor, InterceptorChainConfig, InterceptorResult, InvocationDepthExceededError, type NoiseFilterConfig, type OTelSpan, type OTelSpanOptions, type OTelSpanStatus, OTelSpanStatusCode, type OTelTracer, type OTelTracerConfig, type OTelTracerProvider, type ParticipantResolverConfig, type RateLimitConfig, type SelfFilterConfig, type TracerConfig, composeChain, createAddressCheckInterceptor, createCaptureInterceptor, createDepthGuardInterceptor, createEventDedupInterceptor, createIntentClassifierInterceptor, createNoiseFilterInterceptor, createOTelTracerInterceptor, createParticipantResolverInterceptor, createRateLimitInterceptor, createSelfFilterInterceptor, createTracerInterceptor, executeChain };
@@ -1 +1 @@
1
- var y=Symbol("interceptor-skip-sentinel");function C(e){return e===y}function A(){return y}var v=class extends Error{constructor(t,n){super(`Invocation depth ${t} exceeds maximum ${n}`),this.name="InvocationDepthExceededError"}};function K(e,t,n,s,i={}){let o=i.maxInvocationDepth??5;return{async execute(r){let g=(u=>({agent:t,channel:n,registry:s,invocationDepth:u,delegateAndWait:async(l,d)=>{let p=u+1;if(p>o)throw new v(p,o);if(!s)throw new Error(`Cannot delegate to "${l}": agent is running in standalone mode without a registry`);let f=s.getAgent(l);if(!f)throw new Error(`Agent "${l}" not found for delegation`);let h={message:d.message??"",intent:d.intent,data:d.data,context:d.context,conversationId:d.conversationId??r.conversationId??`delegation-${Date.now()}`};return await f.invokeAgent(h)},skip:A}))(0),a=async u=>{let l=u??r;return await t.invokeAgent(l)};for(let u=e.length-1;u>=0;u--){let l=e[u],d=a;a=async p=>await l(p??r,g,d)}return await a()}}}async function z(e,t){let n=await e.execute(t);return n===y?null:n}var R=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;has(t){return this.cache.has(t)}set(t,n){if(this.cache.has(t)&&this.cache.delete(t),this.cache.size>=this.maxSize){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}};function k(e={}){let t=e.maxCacheSize??1e3,n=e.getEventId??(i=>i.context?.eventId),s=new R(t);return async(i,o,r)=>{let c=n(i);if(c){if(s.has(c))return e.onDuplicate?.(c,i),o.logger?.debug(`Event dedup: dropping duplicate event ${c}`,{eventId:c}),o.skip();s.set(c,!0)}return await r()}}function S(e){let t=e.getSubtype??(s=>s.context?.subtype),n=new Set(e.denySubtypes);return async(s,i,o)=>{let r=t(s);return r&&n.has(r)?(e.onFiltered?.(r,s),i.logger?.debug(`Noise filter: dropping message with subtype "${r}"`,{subtype:r}),i.skip()):await o()}}function E(e){return async(t,n,s)=>{let i=e.getSenderId(t),o=e.agentId??n.agent.name;return i&&i===o?(e.onSelfMessage?.(i,t),n.logger?.debug(`Self filter: dropping self-message from ${i}`,{senderId:i,agentId:o}),n.skip()):await s()}}var w=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;get(t){let n=this.cache.get(t);return n!==void 0&&(this.cache.delete(t),this.cache.set(t,n)),n}set(t,n){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.maxSize){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}},b=class{constructor(t,n,s){this.capacity=t;this.refillRate=n;this.refillInterval=s;this.tokens=t,this.lastRefill=Date.now()}capacity;refillRate;refillInterval;tokens;lastRefill;consume(t=1){return this.refill(),this.tokens>=t?(this.tokens-=t,!0):!1}refill(){let t=Date.now(),n=t-this.lastRefill,s=Math.floor(n/this.refillInterval*this.refillRate);s>0&&(this.tokens=Math.min(this.capacity,this.tokens+s),this.lastRefill=t)}getTokens(){return this.refill(),this.tokens}};function D(e){let t=e.tokensPerInterval??10,n=e.interval??6e4,s=e.maxBuckets??1e3,i=e.onExceeded??"skip",o=new w(s);return async(r,c,g)=>{let a=e.getKey(r),u=o.get(a);if(u||(u=new b(t,t,n),o.set(a,u)),!u.consume()){if(e.onRateLimited?.(a,r),c.logger?.warn(`Rate limit exceeded for key: ${a}`,{key:a}),i==="reject")throw new Error("Rate limit exceeded. Please try again later.");return c.skip()}return await g()}}function P(e={}){return async(t,n,s)=>{let i;if(e.resolveParticipant)i=await e.resolveParticipant(t);else if(typeof n.channel.resolveParticipant=="function")try{i=await n.channel.resolveParticipant(t)}catch(r){n.logger?.warn("Channel resolveParticipant threw; falling back",{error:r instanceof Error?r.message:"Unknown error"})}let o=i??t.participant;if(o){let r={...t,participant:o,context:{...t.context,_participant:o}};return e.onResolved?.(r,o),n.logger?.debug("Resolved participant",{participantId:o.id,participantKind:o.kind}),await s(r)}return await s()}}import{randomUUID as T}from"crypto";function B(e){let t=e.context??{},n=t.channelType;return n==="im"||n==="private"||n==="dm"?"dm":t.threadId!==void 0?"thread":"channel"}var N=Symbol.for("toolpack:capture-history");function F(e){let t=e.captureAgentReplies??!0,n=e.getScope??B,s=e.getMessageId??(r=>r.context?.messageId??r.context?.eventId??T()),i=e.getMentions??(r=>r.context?.mentions??[]),o=async(r,c,g)=>{let a=r.conversationId;if(!a)return c.logger?.warn("[capture-history] Message has no conversationId \u2014 skipping capture"),await g();let u=r.participant;if(u){let d={id:s(r),conversationId:a,participant:u,content:r.message??"",timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,messageId:r.context?.messageId,mentions:i(r),channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(d),e.onCaptured?.(d),c.logger?.debug("[capture-history] Captured inbound message",{messageId:d.id,participantId:u.id,conversationId:a})}catch(p){c.logger?.warn("[capture-history] Failed to store inbound message",{error:p instanceof Error?p.message:String(p)})}}let l=await g();if(t&&!C(l)&&l.output!=null){let d={kind:"agent",id:c.agent.name,displayName:c.agent.name},p={id:T(),conversationId:a,participant:d,content:l.output,timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(p),e.onCaptured?.(p),c.logger?.debug("[capture-history] Captured agent reply",{messageId:p.id,agentId:c.agent.name,conversationId:a})}catch(f){c.logger?.warn("[capture-history] Failed to store agent reply",{error:f instanceof Error?f.message:String(f)})}}return l};return o[N]=!0,o}function O(e,t){let n=t.toLowerCase();if(!e.toLowerCase().includes(n))return!1;let i=[],o=/```[\s\S]*?```/g,r;for(;(r=o.exec(e))!==null;)i.push([r.index,r.index+r[0].length]);let c=/`[^`\n]*`/g;for(;(r=c.exec(e))!==null;){let d=r.index,p=d+r[0].length;i.some(([h,_])=>d>=h&&p<=_)||i.push([d,p])}if(i.length===0)return!1;i.sort((d,p)=>d[0]-p[0]);let g="",a=0;for(let[d,p]of i)d>a&&(g+=e.slice(a,d)),a=Math.max(a,p);return a<e.length&&(g+=e.slice(a)),g.toLowerCase().includes(n)?!1:i.some(([d,p])=>e.slice(d,p).toLowerCase().includes(n))}function M(e){return async(t,n,s)=>{let i=e.getMessageText(t)??"";if(e.isDirectMessage?.(t)){let p={...t,context:{...t.context,_addressCheck:"direct",_isDM:!0}};return e.onClassified?.("direct",t),await s(p)}let o="ambiguous",r=i.toLowerCase(),c=e.agentName.toLowerCase(),g=p=>p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=g(c),u=e.agentId?`|^@${g(e.agentId)}\\b`:"";if(new RegExp(`^(hey\\s+)?@?${a}\\b${u}`,"i").test(r))o="direct";else if(new RegExp(`\\b(my|our|the)\\s+${a}\\b`,"i").test(r))o="ambiguous";else if(O(i,e.agentName))o="ignore";else if(/^https?:\/\//.test(i))o="ignore";else if(e.getMentions){let p=e.getMentions(t),f=p.some(h=>h.toLowerCase()===c||h===e.agentId);f&&p.length>1?o="indirect":f&&(o="ambiguous")}else r.includes(c)?o="ambiguous":o="passive";let d={...t,context:{...t.context,_addressCheck:o}};return e.onClassified?.(o,t),n.logger?.debug(`Address check classified as: ${o}`,{result:o}),await s(d)}}function j(e){let t=e.classifierAgentName??"intent-classifier";return async(n,s,i)=>{let o=n.context?._addressCheck;if(o==="direct")return await i();if(o==="ignore"||o==="passive")return e.onClassified?.(o,n),s.skip();let r=e.getMessageText(n)??"";if(!r.trim())return await i();let c={message:r,agentName:e.agentName,agentId:e.agentId,senderName:e.getSenderName(n),channelName:e.getChannelName(n),isDirectMessage:e.isDirectMessage?.(n)??!1,recentContext:e.getRecentContext?.(n)};try{let a=(await s.delegateAndWait(t,{message:"classify",data:c,conversationId:n.conversationId})).output.trim();e.onClassified?.(a,n),s.logger?.debug(`Intent classified as: ${a}`,{classification:a});let u={...n,context:{...n.context,_intentClassification:a}};return a==="direct"?await i(u):s.skip()}catch(g){return s.logger?.error("Intent classification failed, allowing message",{error:g instanceof Error?g.message:"Unknown error"}),await i()}}}var x=class extends Error{constructor(n,s){super(`Maximum invocation depth exceeded: ${n} > ${s}`);this.currentDepth=n;this.maxDepth=s;this.name="DepthExceededError"}currentDepth;maxDepth};function L(e={}){let t=e.maxDepth??5;return async(n,s,i)=>{if(s.invocationDepth>t)throw e.onDepthExceeded?.(s.invocationDepth,t,n),s.logger?.error(`Depth guard: invocation depth ${s.invocationDepth} exceeds maximum ${t}`,{currentDepth:s.invocationDepth,maxDepth:t}),new x(s.invocationDepth,t);return await i()}}function $(e={}){let t=e.level??"debug",n=e.includeInputData??!1,s=e.includeResultOutput??!1;return async(i,o,r)=>{if(e.shouldTrace&&!e.shouldTrace(i))return await r();let c=t==="info"?o.logger?.info:o.logger?.debug;c?.("Interceptor entry",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,intent:i.intent,input:n?i:void 0});let g=performance.now();try{let a=await r(),u=performance.now()-g;return C(a)?c?.("Interceptor exit: skipped",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:u.toFixed(2)}):c?.("Interceptor exit: success",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:u.toFixed(2),outputLength:a.output.length,result:s?a:void 0}),a}catch(a){let u=performance.now()-g;throw o.logger?.error("Interceptor exit: error",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:u.toFixed(2),error:a instanceof Error?a.message:"Unknown error",errorType:a?.constructor?.name}),a}}}export{N as CAPTURE_INTERCEPTOR_MARKER,x as DepthExceededError,v as InvocationDepthExceededError,y as SKIP_SENTINEL,K as composeChain,M as createAddressCheckInterceptor,F as createCaptureInterceptor,L as createDepthGuardInterceptor,k as createEventDedupInterceptor,j as createIntentClassifierInterceptor,S as createNoiseFilterInterceptor,P as createParticipantResolverInterceptor,D as createRateLimitInterceptor,E as createSelfFilterInterceptor,$ as createTracerInterceptor,z as executeChain,C as isSkipSentinel,A as skip};
1
+ var C=Symbol("interceptor-skip-sentinel");function y(e){return e===C}function b(){return C}var A=class extends Error{constructor(t,n){super(`Invocation depth ${t} exceeds maximum ${n}`),this.name="InvocationDepthExceededError"}};function B(e,t,n,s,i={}){let o=i.maxInvocationDepth??5;return{async execute(r){let d=(a=>({agent:t,channel:n,registry:s,invocationDepth:a,delegateAndWait:async(g,p)=>{let l=a+1;if(l>o)throw new A(l,o);if(!s)throw new Error(`Cannot delegate to "${g}": agent is running in standalone mode without a registry`);let I=s.getAgent(g);if(!I)throw new Error(`Agent "${g}" not found for delegation`);let f={message:p.message??"",intent:p.intent,data:p.data,context:p.context,conversationId:p.conversationId??r.conversationId??`delegation-${Date.now()}`};return await I.invokeAgent(f)},skip:b}))(0),c=async a=>{let g=a??r;return await t.invokeAgent(g)};for(let a=e.length-1;a>=0;a--){let g=e[a],p=c;c=async l=>await g(l??r,d,p)}return await c()}}}async function U(e,t){let n=await e.execute(t);return n===C?null:n}var S=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;has(t){return this.cache.has(t)}set(t,n){if(this.cache.has(t)&&this.cache.delete(t),this.cache.size>=this.maxSize){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}};function E(e={}){let t=e.maxCacheSize??1e3,n=e.getEventId??(i=>i.context?.eventId),s=new S(t);return async(i,o,r)=>{let u=n(i);if(u){if(s.has(u))return e.onDuplicate?.(u,i),o.logger?.debug(`Event dedup: dropping duplicate event ${u}`,{eventId:u}),o.skip();s.set(u,!0)}return await r()}}function P(e){let t=e.getSubtype??(s=>s.context?.subtype),n=new Set(e.denySubtypes);return async(s,i,o)=>{let r=t(s);return r&&n.has(r)?(e.onFiltered?.(r,s),i.logger?.debug(`Noise filter: dropping message with subtype "${r}"`,{subtype:r}),i.skip()):await o()}}function D(e){return async(t,n,s)=>{let i=e.getSenderId(t),o=e.agentId??n.agent.name;return i&&i===o?(e.onSelfMessage?.(i,t),n.logger?.debug(`Self filter: dropping self-message from ${i}`,{senderId:i,agentId:o}),n.skip()):await s()}}var T=class{constructor(t){this.maxSize=t}maxSize;cache=new Map;get(t){let n=this.cache.get(t);return n!==void 0&&(this.cache.delete(t),this.cache.set(t,n)),n}set(t,n){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.maxSize){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(t,n)}clear(){this.cache.clear()}size(){return this.cache.size}},w=class{constructor(t,n,s){this.capacity=t;this.refillRate=n;this.refillInterval=s;this.tokens=t,this.lastRefill=Date.now()}capacity;refillRate;refillInterval;tokens;lastRefill;consume(t=1){return this.refill(),this.tokens>=t?(this.tokens-=t,!0):!1}refill(){let t=Date.now(),n=t-this.lastRefill,s=Math.floor(n/this.refillInterval*this.refillRate);s>0&&(this.tokens=Math.min(this.capacity,this.tokens+s),this.lastRefill=t)}getTokens(){return this.refill(),this.tokens}};function F(e){let t=e.tokensPerInterval??10,n=e.interval??6e4,s=e.maxBuckets??1e3,i=e.onExceeded??"skip",o=new T(s);return async(r,u,d)=>{let c=e.getKey(r),a=o.get(c);if(a||(a=new w(t,t,n),o.set(c,a)),!a.consume()){if(e.onRateLimited?.(c,r),u.logger?.warn(`Rate limit exceeded for key: ${c}`,{key:c}),i==="reject")throw new Error("Rate limit exceeded. Please try again later.");return u.skip()}return await d()}}function M(e={}){return async(t,n,s)=>{let i;if(e.resolveParticipant)i=await e.resolveParticipant(t);else if(typeof n.channel.resolveParticipant=="function")try{i=await n.channel.resolveParticipant(t)}catch(r){n.logger?.warn("Channel resolveParticipant threw; falling back",{error:r instanceof Error?r.message:"Unknown error"})}let o=i??t.participant;if(o){let r={...t,participant:o,context:{...t.context,_participant:o}};return e.onResolved?.(r,o),n.logger?.debug("Resolved participant",{participantId:o.id,participantKind:o.kind}),await s(r)}return await s()}}import{randomUUID as O}from"crypto";function G(e){let t=e.context??{},n=t.channelType;return n==="im"||n==="private"||n==="dm"?"dm":t.threadId!==void 0?"thread":"channel"}var k=Symbol.for("toolpack:capture-history");function j(e){let t=e.captureAgentReplies??!0,n=e.getScope??G,s=e.getMessageId??(r=>r.context?.messageId??r.context?.eventId??O()),i=e.getMentions??(r=>r.context?.mentions??[]),o=async(r,u,d)=>{let c=r.conversationId;if(!c)return u.logger?.warn("[capture-history] Message has no conversationId \u2014 skipping capture"),await d();let a=r.participant;if(a){let p={id:s(r),conversationId:c,participant:a,content:r.message??"",timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,messageId:r.context?.messageId,mentions:i(r),channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(p),e.onCaptured?.(p),u.logger?.debug("[capture-history] Captured inbound message",{messageId:p.id,participantId:a.id,conversationId:c})}catch(l){u.logger?.warn("[capture-history] Failed to store inbound message",{error:l instanceof Error?l.message:String(l)})}}let g=await d();if(t&&!y(g)&&g.output!=null){let p={kind:"agent",id:u.agent.name,displayName:u.agent.name},l={id:O(),conversationId:c,participant:p,content:g.output,timestamp:new Date().toISOString(),scope:n(r),metadata:{channelType:r.context?.channelType,threadId:r.context?.threadId,channelName:r.context?.channelName,channelId:r.context?.channelId}};try{await e.store.append(l),e.onCaptured?.(l),u.logger?.debug("[capture-history] Captured agent reply",{messageId:l.id,agentId:u.agent.name,conversationId:c})}catch(I){u.logger?.warn("[capture-history] Failed to store agent reply",{error:I instanceof Error?I.message:String(I)})}}return g};return o[k]=!0,o}function H(e,t){let n=t.toLowerCase();if(!e.toLowerCase().includes(n))return!1;let i=[],o=/```[\s\S]*?```/g,r;for(;(r=o.exec(e))!==null;)i.push([r.index,r.index+r[0].length]);let u=/`[^`\n]*`/g;for(;(r=u.exec(e))!==null;){let p=r.index,l=p+r[0].length;i.some(([f,R])=>p>=f&&l<=R)||i.push([p,l])}if(i.length===0)return!1;i.sort((p,l)=>p[0]-l[0]);let d="",c=0;for(let[p,l]of i)p>c&&(d+=e.slice(c,p)),c=Math.max(c,l);return c<e.length&&(d+=e.slice(c)),d.toLowerCase().includes(n)?!1:i.some(([p,l])=>e.slice(p,l).toLowerCase().includes(n))}function L(e){return async(t,n,s)=>{let i=e.getMessageText(t)??"";if(e.isDirectMessage?.(t)){let l={...t,context:{...t.context,_addressCheck:"direct",_isDM:!0}};return e.onClassified?.("direct",t),await s(l)}let o="ambiguous",r=i.toLowerCase(),u=e.agentName.toLowerCase(),d=l=>l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=d(u),a=e.agentId?`|^@${d(e.agentId)}\\b`:"";if(new RegExp(`^(hey\\s+)?@?${c}\\b${a}`,"i").test(r))o="direct";else if(new RegExp(`\\b(my|our|the)\\s+${c}\\b`,"i").test(r))o="ambiguous";else if(H(i,e.agentName))o="ignore";else if(/^https?:\/\//.test(i))o="ignore";else if(e.getMentions){let l=e.getMentions(t),I=l.some(f=>f.toLowerCase()===u||f===e.agentId);I&&l.length>1?o="indirect":I&&(o="ambiguous")}else r.includes(u)?o="ambiguous":o="passive";let p={...t,context:{...t.context,_addressCheck:o}};return e.onClassified?.(o,t),n.logger?.debug(`Address check classified as: ${o}`,{result:o}),await s(p)}}function $(e){let t=e.classifierAgentName??"intent-classifier";return async(n,s,i)=>{let o=n.context?._addressCheck;if(o==="direct")return await i();if(o==="ignore"||o==="passive")return e.onClassified?.(o,n),s.skip();let r=e.getMessageText(n)??"";if(!r.trim())return await i();let u={message:r,agentName:e.agentName,agentId:e.agentId,senderName:e.getSenderName(n),channelName:e.getChannelName(n),isDirectMessage:e.isDirectMessage?.(n)??!1,recentContext:e.getRecentContext?.(n)};try{let c=(await s.delegateAndWait(t,{message:"classify",data:u,conversationId:n.conversationId})).output.trim();e.onClassified?.(c,n),s.logger?.debug(`Intent classified as: ${c}`,{classification:c});let a={...n,context:{...n.context,_intentClassification:c}};return c==="direct"?await i(a):s.skip()}catch(d){return s.logger?.error("Intent classification failed, allowing message",{error:d instanceof Error?d.message:"Unknown error"}),await i()}}}var x=class extends Error{constructor(n,s){super(`Maximum invocation depth exceeded: ${n} > ${s}`);this.currentDepth=n;this.maxDepth=s;this.name="DepthExceededError"}currentDepth;maxDepth};function _(e={}){let t=e.maxDepth??5;return async(n,s,i)=>{if(s.invocationDepth>t)throw e.onDepthExceeded?.(s.invocationDepth,t,n),s.logger?.error(`Depth guard: invocation depth ${s.invocationDepth} exceeds maximum ${t}`,{currentDepth:s.invocationDepth,maxDepth:t}),new x(s.invocationDepth,t);return await i()}}function K(e={}){let t=e.level??"debug",n=e.includeInputData??!1,s=e.includeResultOutput??!1;return async(i,o,r)=>{if(e.shouldTrace&&!e.shouldTrace(i))return await r();let u=t==="info"?o.logger?.info:o.logger?.debug;u?.("Interceptor entry",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,intent:i.intent,input:n?i:void 0});let d=performance.now();try{let c=await r(),a=performance.now()-d;return y(c)?u?.("Interceptor exit: skipped",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2)}):u?.("Interceptor exit: success",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2),outputLength:c.output.length,result:s?c:void 0}),c}catch(c){let a=performance.now()-d;throw o.logger?.error("Interceptor exit: error",{agent:o.agent.name,channel:o.channel.name,depth:o.invocationDepth,conversationId:i.conversationId,durationMs:a.toFixed(2),error:c instanceof Error?c.message:"Unknown error",errorType:c?.constructor?.name}),c}}}var N=(s=>(s[s.UNSET=0]="UNSET",s[s.OK=1]="OK",s[s.ERROR=2]="ERROR",s))(N||{});function z(e={}){let{tracerProvider:t,tracerName:n="toolpack-agents",tracerVersion:s,recordSteps:i=!0,shouldTrace:o}=e,r=t?.getTracer(n,s);return async(u,d,c)=>{if(!r)return await c();if(o&&!o(u))return await c();let a=r.startSpan("agent.invocation");a.setAttribute("agent.name",d.agent.name),a.setAttribute("channel.name",d.channel.name??"unknown"),a.setAttribute("invocation.depth",d.invocationDepth),u.conversationId&&a.setAttribute("conversation.id",u.conversationId),u.intent&&a.setAttribute("agent.intent",u.intent);let g=performance.now();try{let p=await c(),l=performance.now()-g;if(a.setAttribute("duration.ms",Math.round(l)),y(p))a.setAttribute("result.skipped",!0),a.setStatus({code:1});else{if(a.setAttribute("result.output.length",p.output.length),i&&p.steps&&p.steps.length>0){a.setAttribute("steps.total",p.steps.length);let I=p.steps.filter(f=>f.status==="failed");I.length>0&&a.setAttribute("steps.failed",I.length),p.steps.forEach((f,R)=>{let v=`step.${R}`;a.setAttribute(`${v}.description`,f.description),a.setAttribute(`${v}.status`,f.status),f.result?.duration!==void 0&&a.setAttribute(`${v}.duration.ms`,f.result.duration),f.result?.toolsUsed&&f.result.toolsUsed.length>0&&a.setAttribute(`${v}.tools`,f.result.toolsUsed.join(","))})}a.setStatus({code:1})}return p}catch(p){let l=performance.now()-g;a.setAttribute("duration.ms",Math.round(l));let I=p instanceof Error?p:String(p);throw a.recordException(I),a.setStatus({code:2,message:p instanceof Error?p.message:String(p)}),p}finally{a.end()}}}export{k as CAPTURE_INTERCEPTOR_MARKER,x as DepthExceededError,A as InvocationDepthExceededError,N as OTelSpanStatusCode,C as SKIP_SENTINEL,B as composeChain,L as createAddressCheckInterceptor,j as createCaptureInterceptor,_ as createDepthGuardInterceptor,E as createEventDedupInterceptor,$ as createIntentClassifierInterceptor,P as createNoiseFilterInterceptor,z as createOTelTracerInterceptor,M as createParticipantResolverInterceptor,F as createRateLimitInterceptor,D as createSelfFilterInterceptor,K as createTracerInterceptor,U as executeChain,y as isSkipSentinel,b as skip};
@@ -1,3 +1,17 @@
1
- "use strict";var C=Object.create;var l=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var T=(o,e)=>{for(var t in e)l(o,t,{get:e[t],enumerable:!0})},v=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of b(e))!R.call(o,i)&&i!==t&&l(o,i,{get:()=>e[i],enumerable:!(r=_(e,i))||r.enumerable});return o};var h=(o,e,t)=>(t=o!=null?C(x(o)):{},v(e||!o||!o.__esModule?l(t,"default",{value:o,enumerable:!0}):t,o)),N=o=>v(l({},"__esModule",{value:!0}),o);var $={};T($,{MockChannel:()=>p,MockKnowledge:()=>d,captureEvents:()=>M,createMockKnowledge:()=>k,createMockKnowledgeSync:()=>f,createMockToolpackSequence:()=>A,createMockToolpackSimple:()=>E,createTestAgent:()=>w,registerEventMatchers:()=>y});module.exports=N($);var p=class{name="mock-channel";isTriggerChannel=!1;_handler;_outputs=[];_inputs=[];_listening=!1;get outputs(){return[...this._outputs]}get lastOutput(){return this._outputs[this._outputs.length-1]}get inputs(){return[...this._inputs]}get lastInput(){return this._inputs[this._inputs.length-1]}get receivedCount(){return this._inputs.length}get sentCount(){return this._outputs.length}get isListening(){return this._listening}onMessage(e){this._handler=e}listen(){this._listening=!0}stop(){this._listening=!1}async send(e){this._outputs.push(e)}normalize(e){let t=e;return{intent:t.intent,message:t.message,data:t.data,context:t.context||{},conversationId:t.conversationId||"test-conversation-1"}}async receive(e){if(!this._handler)throw new Error("MockChannel: no message handler registered. Call onMessage() first or ensure channel is registered with AgentRegistry.");let t=this.normalize(e);this._inputs.push(t),await this._handler(t)}async receiveMessage(e,t="test-conversation-1",r,i){await this.receive({message:e,conversationId:t,intent:r,context:i})}clear(){this._inputs=[],this._outputs=[]}assertOutputContains(e){if(!this._outputs.some(r=>r.output.includes(e)))throw new Error(`MockChannel: no output containing "${e}" found. Outputs: ${JSON.stringify(this._outputs.map(r=>r.output))}`)}assertLastOutput(e){let t=this.lastOutput;if(!t)throw new Error(`MockChannel: no output sent. Expected: "${e}"`);if(t.output!==e)throw new Error(`MockChannel: last output mismatch.
1
+ "use strict";var B=Object.create;var E=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var J=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var Q=(s,e)=>{for(var t in e)E(s,t,{get:e[t],enumerable:!0})},_=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of V(e))!F.call(s,r)&&r!==t&&E(s,r,{get:()=>e[r],enumerable:!(n=K(e,r))||n.enumerable});return s};var O=(s,e,t)=>(t=s!=null?B(J(s)):{},_(e||!s||!s.__esModule?E(t,"default",{value:s,enumerable:!0}):t,s)),z=s=>_(E({},"__esModule",{value:!0}),s);var G={};Q(G,{ContainsScorer:()=>A,CustomScorer:()=>b,EvalDataset:()=>k,EvalRunner:()=>R,ExactMatchScorer:()=>y,LLMJudgeScorer:()=>C,MockChannel:()=>v,MockKnowledge:()=>f,captureEvents:()=>L,compareEvalRuns:()=>j,createMockKnowledge:()=>I,createMockKnowledgeSync:()=>$,createMockToolpackSequence:()=>P,createMockToolpackSimple:()=>N,createTestAgent:()=>T,formatEvalReport:()=>D,registerEventMatchers:()=>q});module.exports=z(G);var v=class{name="mock-channel";isTriggerChannel=!1;_handler;_outputs=[];_inputs=[];_listening=!1;get outputs(){return[...this._outputs]}get lastOutput(){return this._outputs[this._outputs.length-1]}get inputs(){return[...this._inputs]}get lastInput(){return this._inputs[this._inputs.length-1]}get receivedCount(){return this._inputs.length}get sentCount(){return this._outputs.length}get isListening(){return this._listening}onMessage(e){this._handler=e}listen(){this._listening=!0}stop(){this._listening=!1}async send(e){this._outputs.push(e)}normalize(e){let t=e;return{intent:t.intent,message:t.message,data:t.data,context:t.context||{},conversationId:t.conversationId||"test-conversation-1"}}async receive(e){if(!this._handler)throw new Error("MockChannel: no message handler registered. Call onMessage() first or ensure channel is registered with AgentRegistry.");let t=this.normalize(e);this._inputs.push(t),await this._handler(t)}async receiveMessage(e,t="test-conversation-1",n,r){await this.receive({message:e,conversationId:t,intent:n,context:r})}clear(){this._inputs=[],this._outputs=[]}assertOutputContains(e){if(!this._outputs.some(n=>n.output.includes(e)))throw new Error(`MockChannel: no output containing "${e}" found. Outputs: ${JSON.stringify(this._outputs.map(n=>n.output))}`)}assertLastOutput(e){let t=this.lastOutput;if(!t)throw new Error(`MockChannel: no output sent. Expected: "${e}"`);if(t.output!==e)throw new Error(`MockChannel: last output mismatch.
2
2
  Expected: "${e}"
3
- Actual: "${t.output}"`)}};async function k(o={}){let{Knowledge:e}=await import("@toolpack-sdk/knowledge"),{MemoryProvider:t}=await import("@toolpack-sdk/knowledge"),r=o.dimensions??384,i={dimensions:r,async embed(s){let a=[],u=0;for(let c=0;c<s.length;c++)u=(u+s.charCodeAt(c))%1e3;for(let c=0;c<r;c++){let g=Math.sin(u*(c+1))*.5+.5;a.push(g)}return a},async embedBatch(s){return Promise.all(s.map(a=>this.embed(a)))}},n=new t;if(await n.validateDimensions(r),o.initialChunks&&o.initialChunks.length>0){let s=[];for(let a of o.initialChunks){let u=await i.embed(a.content);s.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:a.content,metadata:a.metadata||{},vector:u})}await n.add(s)}return e.create({provider:n,embedder:i,sources:[],description:o.description??"Mock knowledge base for testing",reSync:!1})}function f(o={}){let e=o.dimensions??384,t=[],r=i=>{let n=[],s=0;for(let a=0;a<i.length;a++)s=(s+i.charCodeAt(a))%1e3;for(let a=0;a<e;a++){let u=Math.sin(s*(a+1))*.5+.5;n.push(u)}return n};if(o.initialChunks)for(let i of o.initialChunks)t.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:i.content,metadata:i.metadata||{},vector:r(i.content)});return new d(t,r,o.description)}var d=class{chunks;generateVector;_description;constructor(e=[],t,r="Mock knowledge base"){this.chunks=[...e],this.generateVector=t,this._description=r}async query(e,t){let r=t?.limit??10,i=t?.filter,n=e.toLowerCase().split(/\s+/);return this.chunks.filter(a=>{if(i){for(let[u,c]of Object.entries(i))if(a.metadata[u]!==c)return!1}return!0}).map(a=>{let u=a.content.toLowerCase(),c=0;for(let g of n)u.includes(g)&&(c+=.3,new RegExp(`\\b${g}\\b`).test(u)&&(c+=.2));return c=Math.min(c,1),{chunk:{id:a.id,content:a.content,metadata:t?.includeMetadata===!1?{}:a.metadata,vector:t?.includeVectors?a.vector:void 0},score:c,distance:1-c}}).filter(a=>a.score>0).sort((a,u)=>u.score-a.score).slice(0,r)}async add(e,t){let r=`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.chunks.push({id:r,content:e,metadata:t||{},vector:this.generateVector(e)}),r}getAllChunks(){return[...this.chunks]}clear(){this.chunks=[]}toTool(){return{name:"knowledge_search",displayName:"Knowledge Search",description:this._description,category:"search",cacheable:!1,parameters:{type:"object",properties:{query:{type:"string",description:"Search query to find relevant information"},limit:{type:"number",description:"Maximum number of results to return (default: 10)"},threshold:{type:"number",description:"Minimum similarity threshold 0-1 (default: 0.7)"},filter:{type:"object",description:"Optional metadata filters"}},required:["query"]},execute:async e=>(await this.query(e.query,{limit:e.limit,filter:e.filter})).map(r=>({content:r.chunk.content,score:r.score,metadata:r.chunk.metadata}))}}};function w(o,e={}){let t=[...e.mockResponses??[]],r=e.defaultResponse??"Mock AI response",i=O(t,r,e.provider,e.model),n=new o({toolpack:i}),s=new p;return s.onMessage(async u=>{n._triggeringChannel=s.name,n._conversationId=u.conversationId,n._isTriggerChannel=!1;let c=await n.invokeAgent(u);await s.send({output:c.output,metadata:c.metadata})}),s.listen(),{agent:n,channel:s,toolpack:i,addMockResponse:u=>{t.push(u)}}}function O(o,e,t="openai",r){return{generate:async(i,n)=>{let u=i.messages.filter(c=>c.role==="user").pop()?.content??"";for(let c of o)if(typeof c.trigger=="string"){if(u.toLowerCase().includes(c.trigger.toLowerCase()))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}}}else if(c.trigger instanceof RegExp&&c.trigger.test(u))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}};return{content:e,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{},get provider(){return t},get model(){return r||"gpt-4"}}}function E(o="Mock AI response"){return{generate:async()=>({content:o,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}),setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function A(o){let e=0;return{generate:async()=>{let t=o[e]??"No more mock responses";return e++,{content:t,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function M(o){let e=[],t=[],r=n=>s=>{e.push({name:n,data:s,timestamp:Date.now()})},i=["agent:start","agent:complete","agent:error"];for(let n of i){let s=r(n);o.on(n,s),t.push({event:n,handler:s})}return{get events(){return[...e]},get count(){return e.length},clear(){e.length=0},stop(){for(let{event:n,handler:s}of t)o.off(n,s);t.length=0},hasEvent(n){return e.some(s=>s.name===n)},getEvents(n){return e.filter(s=>s.name===n)},getFirstEvent(n){return e.find(s=>s.name===n)},getLastEvent(n){let s=e.filter(a=>a.name===n);return s[s.length-1]},assertEvent(n){if(!this.hasEvent(n)){let s=e.map(a=>a.name).join(", ")||"(none)";throw new Error(`captureEvents: expected event "${n}" was not captured. Captured events: ${s}`)}},assertNoEvent(n){if(this.hasEvent(n)){let s=e.filter(a=>a.name===n).length;throw new Error(`captureEvents: unexpected event "${n}" was captured ${s} time(s)`)}}}}function y(o){o.extend({toContainEvent(...e){let t=e[0],r=e[1],i=t.hasEvent(r);return{message:()=>i?`expected events to NOT contain "${r}"`:`expected events to contain "${r}". Captured events: ${t.events.map(n=>n.name).join(", ")||"(none)"}`,pass:i}},toContainEventTimes(...e){let t=e[0],r=e[1],i=e[2],n=t.getEvents(r).length,s=n===i;return{message:()=>s?`expected event "${r}" to NOT be captured ${i} time(s), but it was`:`expected event "${r}" to be captured ${i} time(s), but it was captured ${n} time(s)`,pass:s}}})}0&&(module.exports={MockChannel,MockKnowledge,captureEvents,createMockKnowledge,createMockKnowledgeSync,createMockToolpackSequence,createMockToolpackSimple,createTestAgent,registerEventMatchers});
3
+ Actual: "${t.output}"`)}};async function I(s={}){let{Knowledge:e}=await import("@toolpack-sdk/knowledge"),{MemoryProvider:t}=await import("@toolpack-sdk/knowledge"),n=s.dimensions??384,r={dimensions:n,async embed(o){let i=[],u=0;for(let c=0;c<o.length;c++)u=(u+o.charCodeAt(c))%1e3;for(let c=0;c<n;c++){let l=Math.sin(u*(c+1))*.5+.5;i.push(l)}return i},async embedBatch(o){return Promise.all(o.map(i=>this.embed(i)))}},a=new t;if(await a.validateDimensions(n),s.initialChunks&&s.initialChunks.length>0){let o=[];for(let i of s.initialChunks){let u=await r.embed(i.content);o.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:i.content,metadata:i.metadata||{},vector:u})}await a.add(o)}return e.create({provider:a,embedder:r,sources:[],description:s.description??"Mock knowledge base for testing",reSync:!1})}function $(s={}){let e=s.dimensions??384,t=[],n=r=>{let a=[],o=0;for(let i=0;i<r.length;i++)o=(o+r.charCodeAt(i))%1e3;for(let i=0;i<e;i++){let u=Math.sin(o*(i+1))*.5+.5;a.push(u)}return a};if(s.initialChunks)for(let r of s.initialChunks)t.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:r.content,metadata:r.metadata||{},vector:n(r.content)});return new f(t,n,s.description)}var f=class{chunks;generateVector;_description;constructor(e=[],t,n="Mock knowledge base"){this.chunks=[...e],this.generateVector=t,this._description=n}async query(e,t){let n=t?.limit??10,r=t?.filter,a=e.toLowerCase().split(/\s+/);return this.chunks.filter(i=>{if(r){for(let[u,c]of Object.entries(r))if(i.metadata[u]!==c)return!1}return!0}).map(i=>{let u=i.content.toLowerCase(),c=0;for(let l of a)u.includes(l)&&(c+=.3,new RegExp(`\\b${l}\\b`).test(u)&&(c+=.2));return c=Math.min(c,1),{chunk:{id:i.id,content:i.content,metadata:t?.includeMetadata===!1?{}:i.metadata,vector:t?.includeVectors?i.vector:void 0},score:c,distance:1-c}}).filter(i=>i.score>0).sort((i,u)=>u.score-i.score).slice(0,n)}async add(e,t){let n=`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.chunks.push({id:n,content:e,metadata:t||{},vector:this.generateVector(e)}),n}getAllChunks(){return[...this.chunks]}clear(){this.chunks=[]}toTool(){return{name:"knowledge_search",displayName:"Knowledge Search",description:this._description,category:"search",cacheable:!1,parameters:{type:"object",properties:{query:{type:"string",description:"Search query to find relevant information"},limit:{type:"number",description:"Maximum number of results to return (default: 10)"},threshold:{type:"number",description:"Minimum similarity threshold 0-1 (default: 0.7)"},filter:{type:"object",description:"Optional metadata filters"}},required:["query"]},execute:async e=>(await this.query(e.query,{limit:e.limit,filter:e.filter})).map(n=>({content:n.chunk.content,score:n.score,metadata:n.chunk.metadata}))}}};function T(s,e={}){let t=[...e.mockResponses??[]],n=e.defaultResponse??"Mock AI response",r=U(t,n,e.provider,e.model),a=new s({toolpack:r}),o=new v;return o.onMessage(async u=>{a._triggeringChannel=o.name,a._conversationId=u.conversationId,a._isTriggerChannel=!1;let c=await a.invokeAgent(u);await o.send({output:c.output,metadata:c.metadata})}),o.listen(),{agent:a,channel:o,toolpack:r,addMockResponse:u=>{t.push(u)}}}function U(s,e,t="openai",n){return{generate:async(r,a)=>{let u=r.messages.filter(c=>c.role==="user").pop()?.content??"";for(let c of s)if(typeof c.trigger=="string"){if(u.toLowerCase().includes(c.trigger.toLowerCase()))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}}}else if(c.trigger instanceof RegExp&&c.trigger.test(u))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}};return{content:e,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{},get provider(){return t},get model(){return n||"gpt-4"}}}function N(s="Mock AI response"){return{generate:async()=>({content:s,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}),setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function P(s){let e=0;return{generate:async()=>{let t=s[e]??"No more mock responses";return e++,{content:t,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}var w=require("fs"),k=class s{_cases;constructor(e=[]){this._cases=[...e]}get cases(){return[...this._cases]}get size(){return this._cases.length}get(e){return this._cases.find(t=>t.id===e)}add(...e){let t=new Set(this._cases.map(n=>n.id));for(let n of e){if(t.has(n.id))throw new Error(`EvalDataset: case with id "${n.id}" already exists.`);t.add(n.id)}return this._cases.push(...e),this}remove(e){let t=this._cases.length;return this._cases=this._cases.filter(n=>n.id!==e),this._cases.length<t}filter(e){return new s(this._cases.filter(e))}toJSON(){return[...this._cases]}save(e){(0,w.writeFileSync)(e,JSON.stringify(this._cases,null,2),"utf-8")}static load(e){let t=(0,w.readFileSync)(e,"utf-8"),n=JSON.parse(t);return new s(n)}static from(e){return new s(e)}};var R=class{agent;constructor(e){this.agent=e}async run(e,t={}){let n=t.runId??new Date().toISOString(),r=Math.max(1,t.concurrency??1),a=new Date().toISOString(),o=Date.now(),i=e.cases,u=[];for(let c=0;c<i.length;c+=r){let l=i.slice(c,c+r),g=await Promise.all(l.map(async p=>{let S=Date.now();try{let h=await this.agent.invokeAgent({message:p.input.message,intent:p.input.intent,conversationId:p.input.conversationId,context:p.input.context});return{evalCase:p,actualOutput:h.output,durationMs:Date.now()-S}}catch(h){return{evalCase:p,actualOutput:"",durationMs:Date.now()-S,error:h instanceof Error?h.message:String(h)}}}));u.push(...g)}return{runId:n,startedAt:a,completedAt:new Date().toISOString(),totalDurationMs:Date.now()-o,results:u}}};function x(s,e){let t=e.filter(r=>r.verdict==="pass").length,n=e.length-t;return{run:s,scoredResults:e,passCount:t,failCount:n,passRate:e.length===0?0:t/e.length}}function d(s,e,t){let n={caseResult:s,verdict:e};return t!==void 0&&(n.explanation=t),n}var y=class{trim;caseInsensitive;constructor(e={}){this.trim=e.trim??!0,this.caseInsensitive=e.caseInsensitive??!1}async score(e){let t=e.results.map(n=>{if(n.error)return d(n,"fail",`Agent threw: ${n.error}`);let r=n.actualOutput,a=n.evalCase.expectedOutput;return this.trim&&(r=r.trim(),a=a.trim()),this.caseInsensitive&&(r=r.toLowerCase(),a=a.toLowerCase()),d(n,r===a?"pass":"fail")});return x(e,t)}},A=class{caseInsensitive;constructor(e={}){this.caseInsensitive=e.caseInsensitive??!0}async score(e){let t=e.results.map(n=>{if(n.error)return d(n,"fail",`Agent threw: ${n.error}`);let r=n.actualOutput,a=n.evalCase.expectedOutput;this.caseInsensitive&&(r=r.toLowerCase(),a=a.toLowerCase());let o=r.includes(a);return d(n,o?"pass":"fail")});return x(e,t)}},Y=`You are an impartial evaluator assessing whether an AI agent's answer is correct.
4
+
5
+ Question / Task:
6
+ {{question}}
7
+
8
+ Expected answer:
9
+ {{expected}}
10
+
11
+ Actual answer:
12
+ {{actual}}
13
+
14
+ Is the actual answer correct or equivalent to the expected answer?
15
+ Respond with ONLY "pass" or "fail" on the first line, then optionally a one-sentence explanation.`,C=class{judgeAgent;promptTemplate;constructor(e,t={}){this.judgeAgent=e,this.promptTemplate=t.promptTemplate??Y}async score(e){let t=[];for(let n of e.results){if(n.error){t.push(d(n,"fail",`Agent threw: ${n.error}`));continue}let r=this.promptTemplate.replace("{{question}}",n.evalCase.input.message).replace("{{expected}}",n.evalCase.expectedOutput).replace("{{actual}}",n.actualOutput);try{let o=(await this.judgeAgent.invokeAgent({message:r})).output.trim().split(`
16
+ `),i=o[0].toLowerCase().startsWith("pass")?"pass":"fail",u=o.slice(1).join(" ").trim()||void 0;t.push(d(n,i,u))}catch(a){t.push(d(n,"fail",`Judge threw: ${a instanceof Error?a.message:String(a)}`))}}return x(e,t)}},b=class{fn;constructor(e){this.fn=e}async score(e){let t=[];for(let n of e.results){if(n.error){t.push(d(n,"fail",`Agent threw: ${n.error}`));continue}try{let{verdict:r,explanation:a}=await this.fn(n);t.push(d(n,r,a))}catch(r){t.push(d(n,"fail",`Scorer threw: ${r instanceof Error?r.message:String(r)}`))}}return x(e,t)}};function j(s,e){let t=new Map(s.scoredResults.map(l=>[l.caseResult.evalCase.id,l])),n=new Map(e.scoredResults.map(l=>[l.caseResult.evalCase.id,l])),r=[],a=[],o=[],i=[],u=new Set([...t.keys(),...n.keys()]);for(let l of u){let g=t.get(l),p=n.get(l);!g||!p||(g.verdict==="pass"&&p.verdict==="fail"?r.push({caseId:l,baselineOutput:g.caseResult.actualOutput,candidateOutput:p.caseResult.actualOutput}):g.verdict==="fail"&&p.verdict==="pass"?a.push({caseId:l,baselineOutput:g.caseResult.actualOutput,candidateOutput:p.caseResult.actualOutput}):g.verdict==="pass"&&p.verdict==="pass"?o.push(l):i.push(l))}let c=e.passRate-s.passRate;return{baselineRunId:s.run.runId,candidateRunId:e.run.runId,baselinePassRate:s.passRate,candidatePassRate:e.passRate,delta:c,regressions:r,improvements:a,stablePasses:o,stableFails:i}}function D(s){let e=[],t=s.delta>=0?"+":"",n=r=>`${(r*100).toFixed(1)}%`;if(e.push(`Eval Report: ${s.baselineRunId} \u2192 ${s.candidateRunId}`),e.push(`Pass rate: ${n(s.baselinePassRate)} \u2192 ${n(s.candidatePassRate)} (\u0394${t}${n(s.delta)})`),e.push(""),s.regressions.length>0){e.push(`Regressions (${s.regressions.length}):`);for(let r of s.regressions)e.push(` \u2717 ${r.caseId}`),e.push(` baseline: ${M(r.baselineOutput)}`),e.push(` candidate: ${M(r.candidateOutput)}`);e.push("")}if(s.improvements.length>0){e.push(`Improvements (${s.improvements.length}):`);for(let r of s.improvements)e.push(` \u2713 ${r.caseId}`),e.push(` baseline: ${M(r.baselineOutput)}`),e.push(` candidate: ${M(r.candidateOutput)}`);e.push("")}return e.push(`Stable passes: ${s.stablePasses.length} | Stable fails: ${s.stableFails.length}`),e.join(`
17
+ `)}function M(s,e=80){let t=s.replace(/\n/g," ");return t.length>e?`${t.slice(0,e)}\u2026`:t}function L(s){let e=[],t=[],n=a=>o=>{e.push({name:a,data:o,timestamp:Date.now()})},r=["agent:start","agent:complete","agent:error"];for(let a of r){let o=n(a);s.on(a,o),t.push({event:a,handler:o})}return{get events(){return[...e]},get count(){return e.length},clear(){e.length=0},stop(){for(let{event:a,handler:o}of t)s.off(a,o);t.length=0},hasEvent(a){return e.some(o=>o.name===a)},getEvents(a){return e.filter(o=>o.name===a)},getFirstEvent(a){return e.find(o=>o.name===a)},getLastEvent(a){let o=e.filter(i=>i.name===a);return o[o.length-1]},assertEvent(a){if(!this.hasEvent(a)){let o=e.map(i=>i.name).join(", ")||"(none)";throw new Error(`captureEvents: expected event "${a}" was not captured. Captured events: ${o}`)}},assertNoEvent(a){if(this.hasEvent(a)){let o=e.filter(i=>i.name===a).length;throw new Error(`captureEvents: unexpected event "${a}" was captured ${o} time(s)`)}}}}function q(s){s.extend({toContainEvent(...e){let t=e[0],n=e[1],r=t.hasEvent(n);return{message:()=>r?`expected events to NOT contain "${n}"`:`expected events to contain "${n}". Captured events: ${t.events.map(a=>a.name).join(", ")||"(none)"}`,pass:r}},toContainEventTimes(...e){let t=e[0],n=e[1],r=e[2],a=t.getEvents(n).length,o=a===r;return{message:()=>o?`expected event "${n}" to NOT be captured ${r} time(s), but it was`:`expected event "${n}" to be captured ${r} time(s), but it was captured ${a} time(s)`,pass:o}}})}0&&(module.exports={ContainsScorer,CustomScorer,EvalDataset,EvalRunner,ExactMatchScorer,LLMJudgeScorer,MockChannel,MockKnowledge,captureEvents,compareEvalRuns,createMockKnowledge,createMockKnowledgeSync,createMockToolpackSequence,createMockToolpackSimple,createTestAgent,formatEvalReport,registerEventMatchers});
@@ -2,6 +2,7 @@ import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgen
2
2
  import { Chunk, QueryOptions, QueryResult, Knowledge } from '@toolpack-sdk/knowledge';
3
3
  import { Toolpack } from 'toolpack-sdk';
4
4
  import { B as BaseAgent } from '../base-agent-DPdK4Pnl.cjs';
5
+ export { C as ContainsScorer, a as CustomScorer, E as EvalCase, b as EvalCaseResult, c as EvalDataset, d as EvalImprovement, e as EvalRegression, f as EvalReport, g as EvalRun, h as EvalRunner, i as EvalRunnerOptions, j as EvalScoredResult, k as EvalScoredRun, l as EvalScorer, m as EvalVerdict, n as ExactMatchScorer, L as LLMJudgeScorer, o as LLMJudgeScorerOptions, p as compareEvalRuns, q as formatEvalReport } from '../eval-report-BCGixIYd.cjs';
5
6
  import 'events';
6
7
 
7
8
  /**
@@ -2,6 +2,7 @@ import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgen
2
2
  import { Chunk, QueryOptions, QueryResult, Knowledge } from '@toolpack-sdk/knowledge';
3
3
  import { Toolpack } from 'toolpack-sdk';
4
4
  import { B as BaseAgent } from '../base-agent-nU8pr4nu.js';
5
+ export { C as ContainsScorer, a as CustomScorer, E as EvalCase, b as EvalCaseResult, c as EvalDataset, d as EvalImprovement, e as EvalRegression, f as EvalReport, g as EvalRun, h as EvalRunner, i as EvalRunnerOptions, j as EvalScoredResult, k as EvalScoredRun, l as EvalScorer, m as EvalVerdict, n as ExactMatchScorer, L as LLMJudgeScorer, o as LLMJudgeScorerOptions, p as compareEvalRuns, q as formatEvalReport } from '../eval-report-CpdAMa2b.js';
5
6
  import 'events';
6
7
 
7
8
  /**
@@ -1,3 +1,17 @@
1
- var p=class{name="mock-channel";isTriggerChannel=!1;_handler;_outputs=[];_inputs=[];_listening=!1;get outputs(){return[...this._outputs]}get lastOutput(){return this._outputs[this._outputs.length-1]}get inputs(){return[...this._inputs]}get lastInput(){return this._inputs[this._inputs.length-1]}get receivedCount(){return this._inputs.length}get sentCount(){return this._outputs.length}get isListening(){return this._listening}onMessage(e){this._handler=e}listen(){this._listening=!0}stop(){this._listening=!1}async send(e){this._outputs.push(e)}normalize(e){let t=e;return{intent:t.intent,message:t.message,data:t.data,context:t.context||{},conversationId:t.conversationId||"test-conversation-1"}}async receive(e){if(!this._handler)throw new Error("MockChannel: no message handler registered. Call onMessage() first or ensure channel is registered with AgentRegistry.");let t=this.normalize(e);this._inputs.push(t),await this._handler(t)}async receiveMessage(e,t="test-conversation-1",o,i){await this.receive({message:e,conversationId:t,intent:o,context:i})}clear(){this._inputs=[],this._outputs=[]}assertOutputContains(e){if(!this._outputs.some(o=>o.output.includes(e)))throw new Error(`MockChannel: no output containing "${e}" found. Outputs: ${JSON.stringify(this._outputs.map(o=>o.output))}`)}assertLastOutput(e){let t=this.lastOutput;if(!t)throw new Error(`MockChannel: no output sent. Expected: "${e}"`);if(t.output!==e)throw new Error(`MockChannel: last output mismatch.
1
+ var f=class{name="mock-channel";isTriggerChannel=!1;_handler;_outputs=[];_inputs=[];_listening=!1;get outputs(){return[...this._outputs]}get lastOutput(){return this._outputs[this._outputs.length-1]}get inputs(){return[...this._inputs]}get lastInput(){return this._inputs[this._inputs.length-1]}get receivedCount(){return this._inputs.length}get sentCount(){return this._outputs.length}get isListening(){return this._listening}onMessage(e){this._handler=e}listen(){this._listening=!0}stop(){this._listening=!1}async send(e){this._outputs.push(e)}normalize(e){let n=e;return{intent:n.intent,message:n.message,data:n.data,context:n.context||{},conversationId:n.conversationId||"test-conversation-1"}}async receive(e){if(!this._handler)throw new Error("MockChannel: no message handler registered. Call onMessage() first or ensure channel is registered with AgentRegistry.");let n=this.normalize(e);this._inputs.push(n),await this._handler(n)}async receiveMessage(e,n="test-conversation-1",t,r){await this.receive({message:e,conversationId:n,intent:t,context:r})}clear(){this._inputs=[],this._outputs=[]}assertOutputContains(e){if(!this._outputs.some(t=>t.output.includes(e)))throw new Error(`MockChannel: no output containing "${e}" found. Outputs: ${JSON.stringify(this._outputs.map(t=>t.output))}`)}assertLastOutput(e){let n=this.lastOutput;if(!n)throw new Error(`MockChannel: no output sent. Expected: "${e}"`);if(n.output!==e)throw new Error(`MockChannel: last output mismatch.
2
2
  Expected: "${e}"
3
- Actual: "${t.output}"`)}};async function v(c={}){let{Knowledge:e}=await import("@toolpack-sdk/knowledge"),{MemoryProvider:t}=await import("@toolpack-sdk/knowledge"),o=c.dimensions??384,i={dimensions:o,async embed(s){let r=[],u=0;for(let a=0;a<s.length;a++)u=(u+s.charCodeAt(a))%1e3;for(let a=0;a<o;a++){let d=Math.sin(u*(a+1))*.5+.5;r.push(d)}return r},async embedBatch(s){return Promise.all(s.map(r=>this.embed(r)))}},n=new t;if(await n.validateDimensions(o),c.initialChunks&&c.initialChunks.length>0){let s=[];for(let r of c.initialChunks){let u=await i.embed(r.content);s.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:r.content,metadata:r.metadata||{},vector:u})}await n.add(s)}return e.create({provider:n,embedder:i,sources:[],description:c.description??"Mock knowledge base for testing",reSync:!1})}function h(c={}){let e=c.dimensions??384,t=[],o=i=>{let n=[],s=0;for(let r=0;r<i.length;r++)s=(s+i.charCodeAt(r))%1e3;for(let r=0;r<e;r++){let u=Math.sin(s*(r+1))*.5+.5;n.push(u)}return n};if(c.initialChunks)for(let i of c.initialChunks)t.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:i.content,metadata:i.metadata||{},vector:o(i.content)});return new m(t,o,c.description)}var m=class{chunks;generateVector;_description;constructor(e=[],t,o="Mock knowledge base"){this.chunks=[...e],this.generateVector=t,this._description=o}async query(e,t){let o=t?.limit??10,i=t?.filter,n=e.toLowerCase().split(/\s+/);return this.chunks.filter(r=>{if(i){for(let[u,a]of Object.entries(i))if(r.metadata[u]!==a)return!1}return!0}).map(r=>{let u=r.content.toLowerCase(),a=0;for(let d of n)u.includes(d)&&(a+=.3,new RegExp(`\\b${d}\\b`).test(u)&&(a+=.2));return a=Math.min(a,1),{chunk:{id:r.id,content:r.content,metadata:t?.includeMetadata===!1?{}:r.metadata,vector:t?.includeVectors?r.vector:void 0},score:a,distance:1-a}}).filter(r=>r.score>0).sort((r,u)=>u.score-r.score).slice(0,o)}async add(e,t){let o=`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.chunks.push({id:o,content:e,metadata:t||{},vector:this.generateVector(e)}),o}getAllChunks(){return[...this.chunks]}clear(){this.chunks=[]}toTool(){return{name:"knowledge_search",displayName:"Knowledge Search",description:this._description,category:"search",cacheable:!1,parameters:{type:"object",properties:{query:{type:"string",description:"Search query to find relevant information"},limit:{type:"number",description:"Maximum number of results to return (default: 10)"},threshold:{type:"number",description:"Minimum similarity threshold 0-1 (default: 0.7)"},filter:{type:"object",description:"Optional metadata filters"}},required:["query"]},execute:async e=>(await this.query(e.query,{limit:e.limit,filter:e.filter})).map(o=>({content:o.chunk.content,score:o.score,metadata:o.chunk.metadata}))}}};function k(c,e={}){let t=[...e.mockResponses??[]],o=e.defaultResponse??"Mock AI response",i=f(t,o,e.provider,e.model),n=new c({toolpack:i}),s=new p;return s.onMessage(async u=>{n._triggeringChannel=s.name,n._conversationId=u.conversationId,n._isTriggerChannel=!1;let a=await n.invokeAgent(u);await s.send({output:a.output,metadata:a.metadata})}),s.listen(),{agent:n,channel:s,toolpack:i,addMockResponse:u=>{t.push(u)}}}function f(c,e,t="openai",o){return{generate:async(i,n)=>{let u=i.messages.filter(a=>a.role==="user").pop()?.content??"";for(let a of c)if(typeof a.trigger=="string"){if(u.toLowerCase().includes(a.trigger.toLowerCase()))return{content:a.response,usage:a.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}}}else if(a.trigger instanceof RegExp&&a.trigger.test(u))return{content:a.response,usage:a.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}};return{content:e,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{},get provider(){return t},get model(){return o||"gpt-4"}}}function w(c="Mock AI response"){return{generate:async()=>({content:c,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}),setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function E(c){let e=0;return{generate:async()=>{let t=c[e]??"No more mock responses";return e++,{content:t,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function A(c){let e=[],t=[],o=n=>s=>{e.push({name:n,data:s,timestamp:Date.now()})},i=["agent:start","agent:complete","agent:error"];for(let n of i){let s=o(n);c.on(n,s),t.push({event:n,handler:s})}return{get events(){return[...e]},get count(){return e.length},clear(){e.length=0},stop(){for(let{event:n,handler:s}of t)c.off(n,s);t.length=0},hasEvent(n){return e.some(s=>s.name===n)},getEvents(n){return e.filter(s=>s.name===n)},getFirstEvent(n){return e.find(s=>s.name===n)},getLastEvent(n){let s=e.filter(r=>r.name===n);return s[s.length-1]},assertEvent(n){if(!this.hasEvent(n)){let s=e.map(r=>r.name).join(", ")||"(none)";throw new Error(`captureEvents: expected event "${n}" was not captured. Captured events: ${s}`)}},assertNoEvent(n){if(this.hasEvent(n)){let s=e.filter(r=>r.name===n).length;throw new Error(`captureEvents: unexpected event "${n}" was captured ${s} time(s)`)}}}}function M(c){c.extend({toContainEvent(...e){let t=e[0],o=e[1],i=t.hasEvent(o);return{message:()=>i?`expected events to NOT contain "${o}"`:`expected events to contain "${o}". Captured events: ${t.events.map(n=>n.name).join(", ")||"(none)"}`,pass:i}},toContainEventTimes(...e){let t=e[0],o=e[1],i=e[2],n=t.getEvents(o).length,s=n===i;return{message:()=>s?`expected event "${o}" to NOT be captured ${i} time(s), but it was`:`expected event "${o}" to be captured ${i} time(s), but it was captured ${n} time(s)`,pass:s}}})}export{p as MockChannel,m as MockKnowledge,A as captureEvents,v as createMockKnowledge,h as createMockKnowledgeSync,E as createMockToolpackSequence,w as createMockToolpackSimple,k as createTestAgent,M as registerEventMatchers};
3
+ Actual: "${n.output}"`)}};async function S(a={}){let{Knowledge:e}=await import("@toolpack-sdk/knowledge"),{MemoryProvider:n}=await import("@toolpack-sdk/knowledge"),t=a.dimensions??384,r={dimensions:t,async embed(o){let i=[],u=0;for(let c=0;c<o.length;c++)u=(u+o.charCodeAt(c))%1e3;for(let c=0;c<t;c++){let l=Math.sin(u*(c+1))*.5+.5;i.push(l)}return i},async embedBatch(o){return Promise.all(o.map(i=>this.embed(i)))}},s=new n;if(await s.validateDimensions(t),a.initialChunks&&a.initialChunks.length>0){let o=[];for(let i of a.initialChunks){let u=await r.embed(i.content);o.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:i.content,metadata:i.metadata||{},vector:u})}await s.add(o)}return e.create({provider:s,embedder:r,sources:[],description:a.description??"Mock knowledge base for testing",reSync:!1})}function _(a={}){let e=a.dimensions??384,n=[],t=r=>{let s=[],o=0;for(let i=0;i<r.length;i++)o=(o+r.charCodeAt(i))%1e3;for(let i=0;i<e;i++){let u=Math.sin(o*(i+1))*.5+.5;s.push(u)}return s};if(a.initialChunks)for(let r of a.initialChunks)n.push({id:`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`,content:r.content,metadata:r.metadata||{},vector:t(r.content)});return new E(n,t,a.description)}var E=class{chunks;generateVector;_description;constructor(e=[],n,t="Mock knowledge base"){this.chunks=[...e],this.generateVector=n,this._description=t}async query(e,n){let t=n?.limit??10,r=n?.filter,s=e.toLowerCase().split(/\s+/);return this.chunks.filter(i=>{if(r){for(let[u,c]of Object.entries(r))if(i.metadata[u]!==c)return!1}return!0}).map(i=>{let u=i.content.toLowerCase(),c=0;for(let l of s)u.includes(l)&&(c+=.3,new RegExp(`\\b${l}\\b`).test(u)&&(c+=.2));return c=Math.min(c,1),{chunk:{id:i.id,content:i.content,metadata:n?.includeMetadata===!1?{}:i.metadata,vector:n?.includeVectors?i.vector:void 0},score:c,distance:1-c}}).filter(i=>i.score>0).sort((i,u)=>u.score-i.score).slice(0,t)}async add(e,n){let t=`mock-${Date.now()}-${Math.random().toString(36).slice(2)}`;return this.chunks.push({id:t,content:e,metadata:n||{},vector:this.generateVector(e)}),t}getAllChunks(){return[...this.chunks]}clear(){this.chunks=[]}toTool(){return{name:"knowledge_search",displayName:"Knowledge Search",description:this._description,category:"search",cacheable:!1,parameters:{type:"object",properties:{query:{type:"string",description:"Search query to find relevant information"},limit:{type:"number",description:"Maximum number of results to return (default: 10)"},threshold:{type:"number",description:"Minimum similarity threshold 0-1 (default: 0.7)"},filter:{type:"object",description:"Optional metadata filters"}},required:["query"]},execute:async e=>(await this.query(e.query,{limit:e.limit,filter:e.filter})).map(t=>({content:t.chunk.content,score:t.score,metadata:t.chunk.metadata}))}}};function O(a,e={}){let n=[...e.mockResponses??[]],t=e.defaultResponse??"Mock AI response",r=I(n,t,e.provider,e.model),s=new a({toolpack:r}),o=new f;return o.onMessage(async u=>{s._triggeringChannel=o.name,s._conversationId=u.conversationId,s._isTriggerChannel=!1;let c=await s.invokeAgent(u);await o.send({output:c.output,metadata:c.metadata})}),o.listen(),{agent:s,channel:o,toolpack:r,addMockResponse:u=>{n.push(u)}}}function I(a,e,n="openai",t){return{generate:async(r,s)=>{let u=r.messages.filter(c=>c.role==="user").pop()?.content??"";for(let c of a)if(typeof c.trigger=="string"){if(u.toLowerCase().includes(c.trigger.toLowerCase()))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}}}else if(c.trigger instanceof RegExp&&c.trigger.test(u))return{content:c.response,usage:c.usage??{prompt_tokens:10,completion_tokens:5,total_tokens:15}};return{content:e,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{},get provider(){return n},get model(){return t||"gpt-4"}}}function $(a="Mock AI response"){return{generate:async()=>({content:a,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}),setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}function T(a){let e=0;return{generate:async()=>{let n=a[e]??"No more mock responses";return e++,{content:n,usage:{prompt_tokens:10,completion_tokens:5,total_tokens:15}}},setMode:()=>{},registerMode:()=>{},setProvider:()=>{},setModel:()=>{}}}import{readFileSync as N,writeFileSync as P}from"fs";var R=class a{_cases;constructor(e=[]){this._cases=[...e]}get cases(){return[...this._cases]}get size(){return this._cases.length}get(e){return this._cases.find(n=>n.id===e)}add(...e){let n=new Set(this._cases.map(t=>t.id));for(let t of e){if(n.has(t.id))throw new Error(`EvalDataset: case with id "${t.id}" already exists.`);n.add(t.id)}return this._cases.push(...e),this}remove(e){let n=this._cases.length;return this._cases=this._cases.filter(t=>t.id!==e),this._cases.length<n}filter(e){return new a(this._cases.filter(e))}toJSON(){return[...this._cases]}save(e){P(e,JSON.stringify(this._cases,null,2),"utf-8")}static load(e){let n=N(e,"utf-8"),t=JSON.parse(n);return new a(t)}static from(e){return new a(e)}};var y=class{agent;constructor(e){this.agent=e}async run(e,n={}){let t=n.runId??new Date().toISOString(),r=Math.max(1,n.concurrency??1),s=new Date().toISOString(),o=Date.now(),i=e.cases,u=[];for(let c=0;c<i.length;c+=r){let l=i.slice(c,c+r),g=await Promise.all(l.map(async p=>{let M=Date.now();try{let h=await this.agent.invokeAgent({message:p.input.message,intent:p.input.intent,conversationId:p.input.conversationId,context:p.input.context});return{evalCase:p,actualOutput:h.output,durationMs:Date.now()-M}}catch(h){return{evalCase:p,actualOutput:"",durationMs:Date.now()-M,error:h instanceof Error?h.message:String(h)}}}));u.push(...g)}return{runId:t,startedAt:s,completedAt:new Date().toISOString(),totalDurationMs:Date.now()-o,results:u}}};function k(a,e){let n=e.filter(r=>r.verdict==="pass").length,t=e.length-n;return{run:a,scoredResults:e,passCount:n,failCount:t,passRate:e.length===0?0:n/e.length}}function d(a,e,n){let t={caseResult:a,verdict:e};return n!==void 0&&(t.explanation=n),t}var A=class{trim;caseInsensitive;constructor(e={}){this.trim=e.trim??!0,this.caseInsensitive=e.caseInsensitive??!1}async score(e){let n=e.results.map(t=>{if(t.error)return d(t,"fail",`Agent threw: ${t.error}`);let r=t.actualOutput,s=t.evalCase.expectedOutput;return this.trim&&(r=r.trim(),s=s.trim()),this.caseInsensitive&&(r=r.toLowerCase(),s=s.toLowerCase()),d(t,r===s?"pass":"fail")});return k(e,n)}},C=class{caseInsensitive;constructor(e={}){this.caseInsensitive=e.caseInsensitive??!0}async score(e){let n=e.results.map(t=>{if(t.error)return d(t,"fail",`Agent threw: ${t.error}`);let r=t.actualOutput,s=t.evalCase.expectedOutput;this.caseInsensitive&&(r=r.toLowerCase(),s=s.toLowerCase());let o=r.includes(s);return d(t,o?"pass":"fail")});return k(e,n)}},j=`You are an impartial evaluator assessing whether an AI agent's answer is correct.
4
+
5
+ Question / Task:
6
+ {{question}}
7
+
8
+ Expected answer:
9
+ {{expected}}
10
+
11
+ Actual answer:
12
+ {{actual}}
13
+
14
+ Is the actual answer correct or equivalent to the expected answer?
15
+ Respond with ONLY "pass" or "fail" on the first line, then optionally a one-sentence explanation.`,b=class{judgeAgent;promptTemplate;constructor(e,n={}){this.judgeAgent=e,this.promptTemplate=n.promptTemplate??j}async score(e){let n=[];for(let t of e.results){if(t.error){n.push(d(t,"fail",`Agent threw: ${t.error}`));continue}let r=this.promptTemplate.replace("{{question}}",t.evalCase.input.message).replace("{{expected}}",t.evalCase.expectedOutput).replace("{{actual}}",t.actualOutput);try{let o=(await this.judgeAgent.invokeAgent({message:r})).output.trim().split(`
16
+ `),i=o[0].toLowerCase().startsWith("pass")?"pass":"fail",u=o.slice(1).join(" ").trim()||void 0;n.push(d(t,i,u))}catch(s){n.push(d(t,"fail",`Judge threw: ${s instanceof Error?s.message:String(s)}`))}}return k(e,n)}},x=class{fn;constructor(e){this.fn=e}async score(e){let n=[];for(let t of e.results){if(t.error){n.push(d(t,"fail",`Agent threw: ${t.error}`));continue}try{let{verdict:r,explanation:s}=await this.fn(t);n.push(d(t,r,s))}catch(r){n.push(d(t,"fail",`Scorer threw: ${r instanceof Error?r.message:String(r)}`))}}return k(e,n)}};function D(a,e){let n=new Map(a.scoredResults.map(l=>[l.caseResult.evalCase.id,l])),t=new Map(e.scoredResults.map(l=>[l.caseResult.evalCase.id,l])),r=[],s=[],o=[],i=[],u=new Set([...n.keys(),...t.keys()]);for(let l of u){let g=n.get(l),p=t.get(l);!g||!p||(g.verdict==="pass"&&p.verdict==="fail"?r.push({caseId:l,baselineOutput:g.caseResult.actualOutput,candidateOutput:p.caseResult.actualOutput}):g.verdict==="fail"&&p.verdict==="pass"?s.push({caseId:l,baselineOutput:g.caseResult.actualOutput,candidateOutput:p.caseResult.actualOutput}):g.verdict==="pass"&&p.verdict==="pass"?o.push(l):i.push(l))}let c=e.passRate-a.passRate;return{baselineRunId:a.run.runId,candidateRunId:e.run.runId,baselinePassRate:a.passRate,candidatePassRate:e.passRate,delta:c,regressions:r,improvements:s,stablePasses:o,stableFails:i}}function L(a){let e=[],n=a.delta>=0?"+":"",t=r=>`${(r*100).toFixed(1)}%`;if(e.push(`Eval Report: ${a.baselineRunId} \u2192 ${a.candidateRunId}`),e.push(`Pass rate: ${t(a.baselinePassRate)} \u2192 ${t(a.candidatePassRate)} (\u0394${n}${t(a.delta)})`),e.push(""),a.regressions.length>0){e.push(`Regressions (${a.regressions.length}):`);for(let r of a.regressions)e.push(` \u2717 ${r.caseId}`),e.push(` baseline: ${w(r.baselineOutput)}`),e.push(` candidate: ${w(r.candidateOutput)}`);e.push("")}if(a.improvements.length>0){e.push(`Improvements (${a.improvements.length}):`);for(let r of a.improvements)e.push(` \u2713 ${r.caseId}`),e.push(` baseline: ${w(r.baselineOutput)}`),e.push(` candidate: ${w(r.candidateOutput)}`);e.push("")}return e.push(`Stable passes: ${a.stablePasses.length} | Stable fails: ${a.stableFails.length}`),e.join(`
17
+ `)}function w(a,e=80){let n=a.replace(/\n/g," ");return n.length>e?`${n.slice(0,e)}\u2026`:n}function q(a){let e=[],n=[],t=s=>o=>{e.push({name:s,data:o,timestamp:Date.now()})},r=["agent:start","agent:complete","agent:error"];for(let s of r){let o=t(s);a.on(s,o),n.push({event:s,handler:o})}return{get events(){return[...e]},get count(){return e.length},clear(){e.length=0},stop(){for(let{event:s,handler:o}of n)a.off(s,o);n.length=0},hasEvent(s){return e.some(o=>o.name===s)},getEvents(s){return e.filter(o=>o.name===s)},getFirstEvent(s){return e.find(o=>o.name===s)},getLastEvent(s){let o=e.filter(i=>i.name===s);return o[o.length-1]},assertEvent(s){if(!this.hasEvent(s)){let o=e.map(i=>i.name).join(", ")||"(none)";throw new Error(`captureEvents: expected event "${s}" was not captured. Captured events: ${o}`)}},assertNoEvent(s){if(this.hasEvent(s)){let o=e.filter(i=>i.name===s).length;throw new Error(`captureEvents: unexpected event "${s}" was captured ${o} time(s)`)}}}}function B(a){a.extend({toContainEvent(...e){let n=e[0],t=e[1],r=n.hasEvent(t);return{message:()=>r?`expected events to NOT contain "${t}"`:`expected events to contain "${t}". Captured events: ${n.events.map(s=>s.name).join(", ")||"(none)"}`,pass:r}},toContainEventTimes(...e){let n=e[0],t=e[1],r=e[2],s=n.getEvents(t).length,o=s===r;return{message:()=>o?`expected event "${t}" to NOT be captured ${r} time(s), but it was`:`expected event "${t}" to be captured ${r} time(s), but it was captured ${s} time(s)`,pass:o}}})}export{C as ContainsScorer,x as CustomScorer,R as EvalDataset,y as EvalRunner,A as ExactMatchScorer,b as LLMJudgeScorer,f as MockChannel,E as MockKnowledge,q as captureEvents,D as compareEvalRuns,S as createMockKnowledge,_ as createMockKnowledgeSync,T as createMockToolpackSequence,$ as createMockToolpackSimple,O as createTestAgent,L as formatEvalReport,B as registerEventMatchers};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@toolpack-sdk/agents",
3
- "version": "2.1.0",
4
- "description": "Agent layer for the Toolpack SDK - build, compose, and deploy AI agents with a consistent, extensible pattern",
3
+ "version": "2.2.0",
4
+ "description": "Production AI agents for Toolpack SDK 8 channel integrations (Slack, Discord, Telegram, SMS, Email, Webhook, Scheduled, MCP), AgentMind persistent cognitive layer (goals, beliefs, reflections), interceptors, evals, and multi-agent coordination",
5
5
  "engines": {
6
6
  "node": ">=20"
7
7
  },
@@ -59,15 +59,20 @@
59
59
  "publish:npm": "npm run build && npm run test && npm publish"
60
60
  },
61
61
  "keywords": [
62
+ "ai-agent",
63
+ "production-ai",
64
+ "agent-mind",
65
+ "cognitive-layer",
62
66
  "ai",
63
67
  "llm",
64
- "agent",
65
- "ai-agent",
66
- "slack",
67
- "telegram",
68
+ "slack-bot",
69
+ "discord-bot",
70
+ "telegram-bot",
71
+ "sms",
72
+ "email-agent",
68
73
  "webhook",
69
- "cron",
70
74
  "scheduler",
75
+ "multi-agent",
71
76
  "typescript",
72
77
  "sdk",
73
78
  "toolpack"
@@ -83,14 +88,18 @@
83
88
  "url": "https://github.com/toolpack-ai/toolpack-sdk/issues"
84
89
  },
85
90
  "peerDependencies": {
86
- "@toolpack-sdk/knowledge": "^2.0.0",
91
+ "@opentelemetry/api": "^1.x",
92
+ "@toolpack-sdk/knowledge": "^2.2.0",
87
93
  "better-sqlite3": "^12.6.2",
88
94
  "discord.js": "^14.x",
89
95
  "nodemailer": "^6.x",
90
- "toolpack-sdk": "^2.0.0",
96
+ "toolpack-sdk": "^2.2.0",
91
97
  "twilio": "^5.x"
92
98
  },
93
99
  "peerDependenciesMeta": {
100
+ "@opentelemetry/api": {
101
+ "optional": true
102
+ },
94
103
  "@toolpack-sdk/knowledge": {
95
104
  "optional": true
96
105
  },