@toolpack-sdk/agents 2.1.1 → 2.3.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.
- package/README.md +72 -4
- package/dist/{base-agent-DPdK4Pnl.d.cts → base-agent-65162dq7.d.cts} +1 -1
- package/dist/{base-agent-nU8pr4nu.d.ts → base-agent-DzspMyaG.d.ts} +1 -1
- package/dist/capabilities/index.cjs +2 -2
- package/dist/capabilities/index.d.cts +3 -3
- package/dist/capabilities/index.d.ts +3 -3
- package/dist/capabilities/index.js +3 -3
- package/dist/channels/index.cjs +2 -2
- package/dist/channels/index.d.cts +2 -2
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2 -2
- package/dist/eval-report-BUD6NRiP.d.cts +343 -0
- package/dist/eval-report-C6dSvR3Y.d.ts +343 -0
- package/dist/{index-Du6S0eG7.d.cts → index-BxUlu-qG.d.ts} +76 -2
- package/dist/{index-o8Lbzv5N.d.ts → index-DrigwC1A.d.cts} +76 -2
- package/dist/index.cjs +40 -26
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +40 -26
- package/dist/{intent-classifier-agent-DxyfJWcm.d.cts → intent-classifier-agent-D0rWtviD.d.cts} +2 -2
- package/dist/{intent-classifier-agent-0JZDlhpk.d.ts → intent-classifier-agent-mmNoAozf.d.ts} +2 -2
- package/dist/interceptors/index.cjs +1 -1
- package/dist/interceptors/index.d.cts +92 -5
- package/dist/interceptors/index.d.ts +92 -5
- package/dist/interceptors/index.js +1 -1
- package/dist/testing/index.cjs +16 -2
- package/dist/testing/index.d.cts +3 -2
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +16 -2
- package/dist/{types-TB6yypig.d.cts → types-C3eW-auY.d.cts} +6 -8
- package/dist/{types-TB6yypig.d.ts → types-C3eW-auY.d.ts} +6 -8
- package/package.json +18 -9
package/dist/{intent-classifier-agent-DxyfJWcm.d.cts → intent-classifier-agent-D0rWtviD.d.cts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseAgentOptions, A as AgentInput, a as AgentResult } from './types-
|
|
2
|
-
import { B as BaseAgent } from './base-agent-
|
|
1
|
+
import { B as BaseAgentOptions, A as AgentInput, a as AgentResult } from './types-C3eW-auY.cjs';
|
|
2
|
+
import { B as BaseAgent } from './base-agent-65162dq7.cjs';
|
|
3
3
|
import { ModeConfig } from 'toolpack-sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/{intent-classifier-agent-0JZDlhpk.d.ts → intent-classifier-agent-mmNoAozf.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseAgentOptions, A as AgentInput, a as AgentResult } from './types-
|
|
2
|
-
import { B as BaseAgent } from './base-agent-
|
|
1
|
+
import { B as BaseAgentOptions, A as AgentInput, a as AgentResult } from './types-C3eW-auY.js';
|
|
2
|
+
import { B as BaseAgent } from './base-agent-DzspMyaG.js';
|
|
3
3
|
import { ModeConfig } from 'toolpack-sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -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});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { A as AgentInput, i as InterceptorResult, I as Interceptor, f as AgentInstance, C as ChannelInterface, c as IAgentRegistry, g as InterceptorChainConfig, a as AgentResult } from '../types-
|
|
2
|
-
export { h as InterceptorContext, N as NextFunction, S as SKIP_SENTINEL, j as isSkipSentinel, s as skip } from '../types-
|
|
1
|
+
import { A as AgentInput, i as InterceptorResult, I as Interceptor, f as AgentInstance, C as ChannelInterface, c as IAgentRegistry, g as InterceptorChainConfig, a as AgentResult } from '../types-C3eW-auY.cjs';
|
|
2
|
+
export { h as InterceptorContext, N as NextFunction, S as SKIP_SENTINEL, j as isSkipSentinel, s as skip } from '../types-C3eW-auY.cjs';
|
|
3
3
|
import { Participant, ConversationStore, ConversationScope, StoredMessage } from 'toolpack-sdk';
|
|
4
|
-
import { I as IntentClassification } from '../intent-classifier-agent-
|
|
4
|
+
import { I as IntentClassification } from '../intent-classifier-agent-D0rWtviD.cjs';
|
|
5
5
|
import 'events';
|
|
6
|
-
import '../base-agent-
|
|
6
|
+
import '../base-agent-65162dq7.cjs';
|
|
7
7
|
import '@toolpack-sdk/knowledge';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -537,4 +537,91 @@ interface TracerConfig {
|
|
|
537
537
|
*/
|
|
538
538
|
declare function createTracerInterceptor(config?: TracerConfig): Interceptor;
|
|
539
539
|
|
|
540
|
-
|
|
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,9 +1,9 @@
|
|
|
1
|
-
import { A as AgentInput, i as InterceptorResult, I as Interceptor, f as AgentInstance, C as ChannelInterface, c as IAgentRegistry, g as InterceptorChainConfig, a as AgentResult } from '../types-
|
|
2
|
-
export { h as InterceptorContext, N as NextFunction, S as SKIP_SENTINEL, j as isSkipSentinel, s as skip } from '../types-
|
|
1
|
+
import { A as AgentInput, i as InterceptorResult, I as Interceptor, f as AgentInstance, C as ChannelInterface, c as IAgentRegistry, g as InterceptorChainConfig, a as AgentResult } from '../types-C3eW-auY.js';
|
|
2
|
+
export { h as InterceptorContext, N as NextFunction, S as SKIP_SENTINEL, j as isSkipSentinel, s as skip } from '../types-C3eW-auY.js';
|
|
3
3
|
import { Participant, ConversationStore, ConversationScope, StoredMessage } from 'toolpack-sdk';
|
|
4
|
-
import { I as IntentClassification } from '../intent-classifier-agent-
|
|
4
|
+
import { I as IntentClassification } from '../intent-classifier-agent-mmNoAozf.js';
|
|
5
5
|
import 'events';
|
|
6
|
-
import '../base-agent-
|
|
6
|
+
import '../base-agent-DzspMyaG.js';
|
|
7
7
|
import '@toolpack-sdk/knowledge';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -537,4 +537,91 @@ interface TracerConfig {
|
|
|
537
537
|
*/
|
|
538
538
|
declare function createTracerInterceptor(config?: TracerConfig): Interceptor;
|
|
539
539
|
|
|
540
|
-
|
|
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};
|
package/dist/testing/index.cjs
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
"use strict";var
|
|
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
|
|
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});
|
package/dist/testing/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgentOptions } from '../types-
|
|
1
|
+
import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgentOptions } from '../types-C3eW-auY.cjs';
|
|
2
2
|
import { Chunk, QueryOptions, QueryResult, Knowledge } from '@toolpack-sdk/knowledge';
|
|
3
3
|
import { Toolpack } from 'toolpack-sdk';
|
|
4
|
-
import { B as BaseAgent } from '../base-agent-
|
|
4
|
+
import { B as BaseAgent } from '../base-agent-65162dq7.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-BUD6NRiP.cjs';
|
|
5
6
|
import 'events';
|
|
6
7
|
|
|
7
8
|
/**
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgentOptions } from '../types-
|
|
1
|
+
import { C as ChannelInterface, e as AgentOutput, A as AgentInput, B as BaseAgentOptions } from '../types-C3eW-auY.js';
|
|
2
2
|
import { Chunk, QueryOptions, QueryResult, Knowledge } from '@toolpack-sdk/knowledge';
|
|
3
3
|
import { Toolpack } from 'toolpack-sdk';
|
|
4
|
-
import { B as BaseAgent } from '../base-agent-
|
|
4
|
+
import { B as BaseAgent } from '../base-agent-DzspMyaG.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-C6dSvR3Y.js';
|
|
5
6
|
import 'events';
|
|
6
7
|
|
|
7
8
|
/**
|
package/dist/testing/index.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
var
|
|
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: "${
|
|
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};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Participant, ModeConfig, Toolpack } from 'toolpack-sdk';
|
|
1
|
+
import { Participant, ModeConfig, ToolpackInitConfig, Toolpack } from 'toolpack-sdk';
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -110,16 +110,14 @@ interface InterceptorChainConfig {
|
|
|
110
110
|
/**
|
|
111
111
|
* Options for constructing a BaseAgent.
|
|
112
112
|
*
|
|
113
|
-
* - `
|
|
113
|
+
* - `ToolpackInitConfig` — agent creates and owns its own Toolpack instance using
|
|
114
|
+
* the supplied config. Accepts everything `Toolpack.init()` accepts: `apiKey`,
|
|
115
|
+
* `provider`, `model`, `customTools`, `tools`, `knowledge`, `customModes`, etc.
|
|
114
116
|
* The instance is initialised lazily in `start()`.
|
|
115
117
|
* - `{ toolpack }` — agent uses a shared Toolpack instance (e.g. passed from AgentRegistry
|
|
116
|
-
* for multi-agent setups where API client and config are shared).
|
|
118
|
+
* for multi-agent setups where the API client and config are shared).
|
|
117
119
|
*/
|
|
118
|
-
type BaseAgentOptions = {
|
|
119
|
-
apiKey: string;
|
|
120
|
-
provider?: string;
|
|
121
|
-
model?: string;
|
|
122
|
-
} | {
|
|
120
|
+
type BaseAgentOptions = ToolpackInitConfig | {
|
|
123
121
|
toolpack: Toolpack;
|
|
124
122
|
};
|
|
125
123
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Participant, ModeConfig, Toolpack } from 'toolpack-sdk';
|
|
1
|
+
import { Participant, ModeConfig, ToolpackInitConfig, Toolpack } from 'toolpack-sdk';
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -110,16 +110,14 @@ interface InterceptorChainConfig {
|
|
|
110
110
|
/**
|
|
111
111
|
* Options for constructing a BaseAgent.
|
|
112
112
|
*
|
|
113
|
-
* - `
|
|
113
|
+
* - `ToolpackInitConfig` — agent creates and owns its own Toolpack instance using
|
|
114
|
+
* the supplied config. Accepts everything `Toolpack.init()` accepts: `apiKey`,
|
|
115
|
+
* `provider`, `model`, `customTools`, `tools`, `knowledge`, `customModes`, etc.
|
|
114
116
|
* The instance is initialised lazily in `start()`.
|
|
115
117
|
* - `{ toolpack }` — agent uses a shared Toolpack instance (e.g. passed from AgentRegistry
|
|
116
|
-
* for multi-agent setups where API client and config are shared).
|
|
118
|
+
* for multi-agent setups where the API client and config are shared).
|
|
117
119
|
*/
|
|
118
|
-
type BaseAgentOptions = {
|
|
119
|
-
apiKey: string;
|
|
120
|
-
provider?: string;
|
|
121
|
-
model?: string;
|
|
122
|
-
} | {
|
|
120
|
+
type BaseAgentOptions = ToolpackInitConfig | {
|
|
123
121
|
toolpack: Toolpack;
|
|
124
122
|
};
|
|
125
123
|
/**
|