@directive-run/ai 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # @directive-run/ai
2
2
 
3
- AI agent orchestration, guardrails, and multi-agent coordination for Directive. Use Directive constraints to add safety guardrails, approval workflows, and state persistence to any LLM agent framework.
3
+ [![npm](https://img.shields.io/npm/v/@directive-run/ai?color=%236366f1)](https://www.npmjs.com/package/@directive-run/ai)
4
+ [![downloads](https://img.shields.io/npm/dm/@directive-run/ai)](https://www.npmjs.com/package/@directive-run/ai)
5
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@directive-run/ai)](https://bundlephobia.com/package/@directive-run/ai)
6
+ [![license](https://img.shields.io/npm/l/@directive-run/ai)](https://github.com/directive-run/directive/blob/main/LICENSE)
7
+
8
+ AI agent orchestration with guardrails, cost tracking, and multi-agent coordination. Built on [Directive](https://www.npmjs.com/package/@directive-run/core)'s constraint-driven runtime.
9
+
10
+ - **No SDK dependencies** – pure `fetch` adapters for OpenAI, Anthropic, and Ollama
11
+ - **Guardrails** – input, output, and tool call validation with retry support
12
+ - **Multi-agent orchestration** – parallel, sequential, and supervisor patterns
13
+ - **Cost tracking** – per-call token usage with pricing constants for every provider
14
+ - **Streaming** – async iterable streams with backpressure and streaming guardrails
15
+ - **Provider adapters** – swap providers by changing one import, not your codebase
4
16
 
5
17
  ## Install
6
18
 
@@ -8,9 +20,9 @@ AI agent orchestration, guardrails, and multi-agent coordination for Directive.
8
20
  npm install @directive-run/core @directive-run/ai
9
21
  ```
10
22
 
11
- Provider adapters are included as subpath exports no extra packages needed.
23
+ Provider adapters are subpath exports – no extra packages needed.
12
24
 
13
- ## Usage
25
+ ## Quick Start
14
26
 
15
27
  ```typescript
16
28
  import { createAgentStack } from "@directive-run/ai";
@@ -21,7 +33,9 @@ const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });
21
33
  const stack = createAgentStack({
22
34
  runner,
23
35
  agents: {
24
- assistant: { instructions: "You are a helpful assistant." },
36
+ assistant: {
37
+ agent: { name: "assistant", instructions: "You are a helpful assistant." },
38
+ },
25
39
  },
26
40
  guardrails: {
27
41
  input: [async (data) => ({ passed: data.input.length < 10000 })],
@@ -32,39 +46,9 @@ const result = await stack.run("assistant", "Hello!");
32
46
  console.log(result.output);
33
47
  ```
34
48
 
35
- ## Why Directive Adapters?
36
-
37
- Directive adapters are intentionally thin &ndash; they map `createRunner()` config to each provider's HTTP API. This gives you:
38
-
39
- - **No SDK dependencies** &ndash; pure `fetch`, no `openai` or `@anthropic-ai/sdk` to install
40
- - **Uniform interface** &ndash; swap providers by changing one import, not your entire codebase
41
- - **Built-in observability** &ndash; lifecycle hooks (`onBeforeCall`, `onAfterCall`, `onError`) on every adapter
42
- - **Cost tracking** &ndash; `tokenUsage` breakdown (input/output) and pricing constants for every provider
43
- - **Tree-shakeable** &ndash; each adapter is a separate entry point; unused adapters never enter your bundle
44
-
45
- ## Key Features
46
-
47
- - Guardrails (input, output, tool call) with retry support
48
- - Approval workflows for tool calls
49
- - Multi-agent orchestration (parallel, sequential, supervisor patterns)
50
- - Agent memory (sliding window, token-based, hybrid strategies)
51
- - Streaming with backpressure and streaming guardrails
52
- - Semantic caching and RAG enrichment
53
- - Circuit breakers and observability
54
- - Per-call cost tracking with `tokenUsage` and pricing constants
55
- - Adapter lifecycle hooks for tracing, logging, and metrics
56
-
57
- ## Subpath Exports
58
-
59
- | Import | Purpose |
60
- |--------|---------|
61
- | `@directive-run/ai` | Orchestrator, guardrails, multi-agent, streaming |
62
- | `@directive-run/ai/testing` | Mock runners, test helpers |
63
- | `@directive-run/ai/openai` | OpenAI, Azure, Together adapter |
64
- | `@directive-run/ai/anthropic` | Anthropic Claude adapter |
65
- | `@directive-run/ai/ollama` | Local Ollama inference adapter |
49
+ ## Provider Adapters
66
50
 
67
- ## Provider Comparison
51
+ Adapters are thin wrappers around each provider's HTTP API. No SDK dependencies &ndash; pure `fetch`.
68
52
 
69
53
  | | OpenAI | Anthropic | Ollama |
70
54
  |---|--------|-----------|--------|
@@ -81,16 +65,16 @@ Directive adapters are intentionally thin &ndash; they map `createRunner()` conf
81
65
  Every adapter returns `tokenUsage` with input/output breakdown:
82
66
 
83
67
  ```typescript
84
- import { estimateCost } from '@directive-run/ai';
85
- import { createOpenAIRunner, OPENAI_PRICING } from '@directive-run/ai/openai';
68
+ import { estimateCost } from "@directive-run/ai";
69
+ import { createOpenAIRunner, OPENAI_PRICING } from "@directive-run/ai/openai";
86
70
 
87
71
  const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });
88
- const result = await runner(agent, 'Hello');
72
+ const result = await runner(agent, "Hello");
89
73
 
90
74
  const { inputTokens, outputTokens } = result.tokenUsage!;
91
75
  const cost =
92
- estimateCost(inputTokens, OPENAI_PRICING['gpt-4o'].input) +
93
- estimateCost(outputTokens, OPENAI_PRICING['gpt-4o'].output);
76
+ estimateCost(inputTokens, OPENAI_PRICING["gpt-4o"].input) +
77
+ estimateCost(outputTokens, OPENAI_PRICING["gpt-4o"].output);
94
78
  ```
95
79
 
96
80
  ## Lifecycle Hooks
@@ -98,38 +82,81 @@ const cost =
98
82
  Attach hooks to any adapter for observability:
99
83
 
100
84
  ```typescript
101
- import { createAnthropicRunner } from '@directive-run/ai/anthropic';
85
+ import { createAnthropicRunner } from "@directive-run/ai/anthropic";
102
86
 
103
87
  const runner = createAnthropicRunner({
104
88
  apiKey: process.env.ANTHROPIC_API_KEY!,
105
89
  hooks: {
106
- onBeforeCall: ({ agent, input }) => console.log(`→ ${agent.name}`),
90
+ onBeforeCall: ({ agent, input }) => console.log(`Calling ${agent.name}`),
107
91
  onAfterCall: ({ durationMs, tokenUsage }) => {
108
- metrics.track('llm_call', { durationMs, ...tokenUsage });
92
+ metrics.track("llm_call", { durationMs, ...tokenUsage });
109
93
  },
110
94
  onError: ({ error }) => Sentry.captureException(error),
111
95
  },
112
96
  });
113
97
  ```
114
98
 
99
+ ## Multi-Agent Orchestration
100
+
101
+ Coordinate multiple agents with built-in execution patterns:
102
+
103
+ ```typescript
104
+ import { createAgentStack, parallel } from "@directive-run/ai";
105
+ import { createOpenAIRunner } from "@directive-run/ai/openai";
106
+
107
+ const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });
108
+
109
+ const researchAgent = { name: "researcher", instructions: "Research the topic thoroughly." };
110
+ const writerAgent = { name: "writer", instructions: "Write a clear summary." };
111
+
112
+ const stack = createAgentStack({
113
+ runner,
114
+ agents: {
115
+ researcher: { agent: researchAgent, maxConcurrent: 3 },
116
+ writer: { agent: writerAgent, maxConcurrent: 1 },
117
+ },
118
+ patterns: {
119
+ researchAndWrite: parallel(
120
+ ["researcher", "writer"],
121
+ (results) => results.map((r) => r.output).join("\n\n"),
122
+ ),
123
+ },
124
+ });
125
+
126
+ // Run the pattern
127
+ const result = await stack.runPattern("researchAndWrite", "Quantum computing basics");
128
+ ```
129
+
130
+ ## Subpath Exports
131
+
132
+ | Import | Purpose |
133
+ |--------|---------|
134
+ | `@directive-run/ai` | Orchestrator, guardrails, multi-agent, streaming, memory |
135
+ | `@directive-run/ai/testing` | Mock runners, test helpers |
136
+ | `@directive-run/ai/openai` | OpenAI / Azure / Together adapter |
137
+ | `@directive-run/ai/anthropic` | Anthropic Claude adapter |
138
+ | `@directive-run/ai/ollama` | Local Ollama inference adapter |
139
+
115
140
  ## Testing
116
141
 
117
- The `@directive-run/ai/testing` subpath provides mock runners and test helpers for unit testing agent stacks without making real LLM calls:
142
+ Mock runners for unit testing without real LLM calls:
118
143
 
119
144
  ```typescript
120
145
  import { createAgentStack } from "@directive-run/ai";
121
- import { createMockRunner, createMockStreamingRunner } from "@directive-run/ai/testing";
146
+ import { createMockAgentRunner } from "@directive-run/ai/testing";
122
147
 
123
- const mockRunner = createMockRunner({
148
+ const mock = createMockAgentRunner({
124
149
  responses: {
125
- assistant: "This is a mock response.",
150
+ assistant: { output: "This is a mock response." },
126
151
  },
127
152
  });
128
153
 
129
154
  const stack = createAgentStack({
130
- runner: mockRunner,
155
+ runner: mock.run,
131
156
  agents: {
132
- assistant: { instructions: "You are a helpful assistant." },
157
+ assistant: {
158
+ agent: { name: "assistant", instructions: "You are a helpful assistant." },
159
+ },
133
160
  },
134
161
  });
135
162
 
@@ -137,10 +164,12 @@ const result = await stack.run("assistant", "Hello!");
137
164
  // result.output === "This is a mock response."
138
165
  ```
139
166
 
140
- Use `createMockStreamingRunner` to test streaming code paths with controlled chunk delivery.
167
+ ## Documentation
168
+
169
+ - [AI Guide](https://directive.run/docs/ai)
170
+ - [API Reference](https://directive.run/docs/api)
171
+ - [GitHub](https://github.com/directive-run/directive)
141
172
 
142
173
  ## License
143
174
 
144
175
  MIT
145
-
146
- [Full documentation](https://directive.run/docs)
@@ -1,4 +1,4 @@
1
- import { f as AdapterHooks, c as AgentRunner } from './types-BKCdgKC-.cjs';
1
+ import { f as AdapterHooks, c as AgentRunner } from './types-Bbar7yKz.cjs';
2
2
  import { StreamingCallbackRunner } from './index.cjs';
3
3
  import '@directive-run/core';
4
4
  import '@directive-run/core/plugins';
@@ -1,4 +1,4 @@
1
- import { f as AdapterHooks, c as AgentRunner } from './types-BKCdgKC-.js';
1
+ import { f as AdapterHooks, c as AgentRunner } from './types-Bbar7yKz.js';
2
2
  import { StreamingCallbackRunner } from './index.js';
3
3
  import '@directive-run/core';
4
4
  import '@directive-run/core/plugins';
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var adapterUtils=require('@directive-run/core/adapter-utils'),core=require('@directive-run/core'),plugins=require('@directive-run/core/plugins');var Z=class extends Error{code;guardrailName;guardrailType;userMessage;agentName;constructor(t){super(t.message,{cause:t.cause}),this.name="GuardrailError",this.code=t.code,this.guardrailName=t.guardrailName,this.guardrailType=t.guardrailType,this.userMessage=t.userMessage??t.message,this.agentName=t.agentName,Object.defineProperty(this,"input",{value:t.input,enumerable:false,writable:false,configurable:false}),Object.defineProperty(this,"data",{value:t.data,enumerable:false,writable:false,configurable:false});}toJSON(){return {name:this.name,code:this.code,message:this.message,guardrailName:this.guardrailName,guardrailType:this.guardrailType,userMessage:this.userMessage,agentName:this.agentName}}};function Ot(e){return e instanceof Z}var ae="__agent",ge="__approval",Te="__conversation",Ce="__toolCalls",at={facts:{[ae]:core.t.any(),[ge]:core.t.any(),[Te]:core.t.any(),[Ce]:core.t.any()}};var it=1e5;function ut(e){if(typeof e=="string")return e;try{let t=new WeakSet,r=JSON.stringify(e,(s,n)=>{if(typeof n=="object"&&n!==null){if(t.has(n))return "[Circular]";t.add(n);}return n});return r.length>it?r.slice(0,it)+"...[truncated]":r}catch{return String(e)}}function Dt(e){let{patterns:t=[/\b\d{3}-\d{2}-\d{4}\b/g,/\b\d{16}\b/g,/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi],redact:r=false,redactReplacement:s="[REDACTED]"}=e;return n=>{let a=n.input,o=false;for(let c of t)c.lastIndex=0,c.test(a)&&(o=true,r&&(c.lastIndex=0,a=a.replace(c,s)));return o&&!r?{passed:false,reason:"Input contains PII"}:{passed:true,transformed:r&&o?a:void 0}}}function Nt(e){let{checkFn:t,message:r="Content flagged by moderation"}=e;return async s=>{let n="output"in s?typeof s.output=="string"?s.output:JSON.stringify(s.output):s.input,a=await t(n);return {passed:!a,reason:a?r:void 0}}}function Gt(e){let{maxTokensPerMinute:t=1e5,maxRequestsPerMinute:r=60}=e,s=Math.max(r,1e3),n=[],a=[],o=6e4;function c(l,d){let u=0,m=l.length;for(;u<m;){let f=u+m>>>1;(l[f]??0)<d?u=f+1:m=f;}return u}let i=(l,d)=>{let u=Date.now(),m=u-o,f=c(n,m);f>0&&(n=n.slice(f));let R=c(a,m);R>0&&(a=a.slice(R));let y=d.facts[ae]?.tokenUsage??0,h=n.length,g=a.length;return h+y>t?{passed:false,reason:"Token rate limit exceeded"}:g>=r?{passed:false,reason:"Request rate limit exceeded"}:(a.length<s&&a.push(u),n.length<s&&n.push(u),{passed:true})};return i.reset=()=>{n=[],a=[];},i}function Ft(e){let{allowlist:t,denylist:r,caseSensitive:s=false}=e,n=t?.map(o=>s?o:o.toLowerCase()),a=r?.map(o=>s?o:o.toLowerCase());return o=>{let c=s?o.toolCall.name:o.toolCall.name.toLowerCase();return n&&!n.includes(c)?{passed:false,reason:`Tool "${o.toolCall.name}" not in allowlist`}:a&&a.includes(c)?{passed:false,reason:`Tool "${o.toolCall.name}" is blocked`}:{passed:true}}}function _t(e){let{validate:t,errorPrefix:r="Output schema validation failed"}=e;return s=>{let n=t(s.output);return typeof n=="boolean"?{passed:n,reason:n?void 0:r}:n.valid?{passed:true}:{passed:false,reason:n.errors?.length?`${r}: ${n.errors.join("; ")}`:r}}}function jt(e){let{type:t,requiredFields:r=[],minLength:s,maxLength:n,minStringLength:a,maxStringLength:o}=e;return c=>{let i=c.output;switch(t){case "string":return typeof i!="string"?{passed:false,reason:`Expected string, got ${typeof i}`}:a!==void 0&&i.length<a?{passed:false,reason:`String too short: ${i.length} < ${a}`}:o!==void 0&&i.length>o?{passed:false,reason:`String too long: ${i.length} > ${o}`}:{passed:true};case "number":return typeof i!="number"||Number.isNaN(i)?{passed:false,reason:`Expected number, got ${typeof i}`}:{passed:true};case "boolean":return typeof i!="boolean"?{passed:false,reason:`Expected boolean, got ${typeof i}`}:{passed:true};case "object":if(typeof i!="object"||i===null||Array.isArray(i))return {passed:false,reason:`Expected object, got ${Array.isArray(i)?"array":typeof i}`};for(let l of r)if(!(l in i))return {passed:false,reason:`Missing required field: ${l}`};return {passed:true};case "array":return Array.isArray(i)?s!==void 0&&i.length<s?{passed:false,reason:`Array too short: ${i.length} < ${s}`}:n!==void 0&&i.length>n?{passed:false,reason:`Array too long: ${i.length} > ${n}`}:{passed:true}:{passed:false,reason:`Expected array, got ${typeof i}`};default:return {passed:false,reason:`Unknown type: ${t}`}}}}function $t(e){let{maxCharacters:t,maxTokens:r,estimateTokens:s=n=>Math.ceil(n.length/4)}=e;return n=>{let a=ut(n.output);if(t!==void 0&&a.length>t)return {passed:false,reason:`Output too long: ${a.length} characters (max: ${t})`};if(r!==void 0){let o=s(a);if(o>r)return {passed:false,reason:`Output too long: ~${o} tokens (max: ${r})`}}return {passed:true}}}function Bt(e){let{blockedPatterns:t,caseSensitive:r=false}=e;t.length===0&&console.warn("[Directive] createContentFilterGuardrail: blockedPatterns is empty \u2014 no content will be filtered");let s=t.map(n=>{if(n instanceof RegExp)return n;let a=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(a,r?"g":"gi")});return n=>{let a=ut(n.output);for(let o of s)if(o.lastIndex=0,o.test(a))return {passed:false,reason:`Output contains blocked content matching: ${o.source}`};return {passed:true}}}function Lt(e){return e.status==="running"}function qt(e){return e.pending.length>0}function se(e,t){return e/1e6*t}var Ut=new Set(["http:","https:"]);function Ht(e){try{let t=new URL(e);if(!Ut.has(t.protocol))throw new Error(`[Directive] Invalid baseURL protocol "${t.protocol}" \u2013 only http: and https: are allowed`)}catch(t){throw t instanceof Error&&t.message.startsWith("[Directive]")?t:new Error(`[Directive] Invalid baseURL "${e}" \u2013 must be a valid URL (e.g. "https://api.openai.com/v1")`)}}function zt(e){let{fetch:t=globalThis.fetch,buildRequest:r,parseResponse:s,parseOutput:n,hooks:a}=e,c=n??(i=>{try{return JSON.parse(i)}catch{return i}});return async(i,l,d)=>{let u=Date.now();a?.onBeforeCall?.({agent:i,input:l,timestamp:u});let m=[{role:"user",content:l}];try{let{url:f,init:R}=r(i,l,m),b=d?.signal?{...R,signal:d.signal}:R,v=await t(f,b);if(!v.ok){let S=await v.text().catch(()=>"");throw new Error(`[Directive] AgentRunner request failed: ${v.status} ${v.statusText}${S?` \u2013 ${S.slice(0,300)}`:""}`)}let y=await s(v,m),h={inputTokens:y.inputTokens??0,outputTokens:y.outputTokens??0},g={role:"assistant",content:y.text},T=[...m,g];d?.onMessage?.(g);let E=Date.now()-u;return a?.onAfterCall?.({agent:i,input:l,output:y.text,totalTokens:y.totalTokens,tokenUsage:h,durationMs:E,timestamp:Date.now()}),{output:c(y.text),messages:T,toolCalls:[],totalTokens:y.totalTokens,tokenUsage:h}}catch(f){let R=Date.now()-u;throw f instanceof Error&&a?.onError?.({agent:i,input:l,error:f,durationMs:R,timestamp:Date.now()}),f}}}function Wt(){return {when(e){return {require(t){let r=0,s={priority(n){return r=n,s},build(){return {when:e,require:t,priority:r}}};return s}}}}}function Vt(e){return {require(t){return {when:e,require:t,priority:0,withPriority(r){return {when:e,require:t,priority:r}}}}}}function pe(e,t){let r=typeof e.content=="string"?e.content:JSON.stringify(e.content);return Math.ceil(r.length/4)}function _e(e,t){return e.reduce((r,s)=>r+pe(s),0)}function ke(e={}){return (t,r={})=>{let s={...e,...r},n=s.maxMessages??100,a=s.preserveRecentCount??5;if(t.length<=n)return {keep:[...t],toSummarize:[],estimatedTokens:_e(t)};let o=t.slice(-a),c=t.slice(0,-a),i=Math.max(0,n-a),l=c.slice(-i),d=c.slice(0,-i||void 0),u=[...l,...o];return {keep:u,toSummarize:d.length>0?d:[],estimatedTokens:_e(u)}}}function ct(e={}){return (t,r={})=>{let s={...e,...r},n=s.maxTokens??4e3,a=s.preserveRecentCount??5,o=s.countSystemMessages??true,c=t.slice(-a),i=t.slice(0,-a),l=c.reduce((f,R)=>!o&&R.role==="system"?f:f+pe(R),0),d=[],u=[],m=l;for(let f=i.length-1;f>=0;f--){let R=i[f],b=!o&&R.role==="system"?0:pe(R);if(m+b<=n)d.unshift(R),m+=b;else {u.push(...i.slice(0,f+1));break}}return {keep:[...d,...c],toSummarize:u,estimatedTokens:m}}}function Jt(e={}){let t=ke(e),r=ct(e);return (s,n={})=>{let a={...e,...n},o=t(s,a),c=r(s,a);return o.keep.length<=c.keep.length?o:c}}function je(e){let{strategy:t,summarizer:r,strategyConfig:s={},autoManage:n=false,onMemoryManaged:a,onManageError:o,maxContextTokens:c}=e,i={messages:[],summaries:[],totalMessagesProcessed:0,estimatedTokens:0},l=false;async function d(){if(l)return {messagesBefore:i.messages.length,messagesAfter:i.messages.length,messagesSummarized:0,estimatedTokensBefore:i.estimatedTokens,estimatedTokensAfter:i.estimatedTokens};l=true;try{let m=i.messages.length,f=i.estimatedTokens,R=t(i.messages,s);if(R.toSummarize.length===0)return {messagesBefore:m,messagesAfter:m,messagesSummarized:0,estimatedTokensBefore:f,estimatedTokensAfter:R.estimatedTokens};let b;r&&R.toSummarize.length>0&&(b=await r(R.toSummarize),i.summaries.push({content:b,messagesCount:R.toSummarize.length,createdAt:Date.now()})),i.messages=R.keep,i.estimatedTokens=R.estimatedTokens;let v={messagesBefore:m,messagesAfter:i.messages.length,messagesSummarized:R.toSummarize.length,summary:b,estimatedTokensBefore:f,estimatedTokensAfter:R.estimatedTokens};return a?.(v),v}finally{l=false;}}function u(){if(l)return;t(i.messages,s).toSummarize.length>0&&d().catch(f=>{let R=f instanceof Error?f:new Error(String(f));o?o(R):console.error("[Directive Memory] Auto-manage error:",R);});}return {getState(){return {...i,messages:[...i.messages],summaries:i.summaries.map(m=>({...m}))}},addMessage(m){i.messages.push(m),i.totalMessagesProcessed++,i.estimatedTokens+=pe(m),n&&u();},addMessages(m){for(let f of m)i.messages.push(f),i.totalMessagesProcessed++,i.estimatedTokens+=pe(f);n&&u();},getContextMessages(){let m=[];if(i.summaries.length>0){let f=i.summaries.map(R=>R.content).join(`
1
+ 'use strict';var adapterUtils=require('@directive-run/core/adapter-utils'),core=require('@directive-run/core'),plugins=require('@directive-run/core/plugins');var Z=class extends Error{code;guardrailName;guardrailType;userMessage;agentName;constructor(t){super(t.message,{cause:t.cause}),this.name="GuardrailError",this.code=t.code,this.guardrailName=t.guardrailName,this.guardrailType=t.guardrailType,this.userMessage=t.userMessage??t.message,this.agentName=t.agentName,Object.defineProperty(this,"input",{value:t.input,enumerable:false,writable:false,configurable:false}),Object.defineProperty(this,"data",{value:t.data,enumerable:false,writable:false,configurable:false});}toJSON(){return {name:this.name,code:this.code,message:this.message,guardrailName:this.guardrailName,guardrailType:this.guardrailType,userMessage:this.userMessage,agentName:this.agentName}}};function Ot(e){return e instanceof Z}var ae="__agent",ge="__approval",Te="__conversation",Ce="__toolCalls",at={facts:{[ae]:core.t.object(),[ge]:core.t.object(),[Te]:core.t.object(),[Ce]:core.t.object()}};var it=1e5;function ut(e){if(typeof e=="string")return e;try{let t=new WeakSet,r=JSON.stringify(e,(s,n)=>{if(typeof n=="object"&&n!==null){if(t.has(n))return "[Circular]";t.add(n);}return n});return r.length>it?r.slice(0,it)+"...[truncated]":r}catch{return String(e)}}function Dt(e){let{patterns:t=[/\b\d{3}-\d{2}-\d{4}\b/g,/\b\d{16}\b/g,/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi],redact:r=false,redactReplacement:s="[REDACTED]"}=e;return n=>{let a=n.input,o=false;for(let c of t)c.lastIndex=0,c.test(a)&&(o=true,r&&(c.lastIndex=0,a=a.replace(c,s)));return o&&!r?{passed:false,reason:"Input contains PII"}:{passed:true,transformed:r&&o?a:void 0}}}function Nt(e){let{checkFn:t,message:r="Content flagged by moderation"}=e;return async s=>{let n="output"in s?typeof s.output=="string"?s.output:JSON.stringify(s.output):s.input,a=await t(n);return {passed:!a,reason:a?r:void 0}}}function Gt(e){let{maxTokensPerMinute:t=1e5,maxRequestsPerMinute:r=60}=e,s=Math.max(r,1e3),n=[],a=[],o=6e4;function c(l,d){let u=0,m=l.length;for(;u<m;){let f=u+m>>>1;(l[f]??0)<d?u=f+1:m=f;}return u}let i=(l,d)=>{let u=Date.now(),m=u-o,f=c(n,m);f>0&&(n=n.slice(f));let R=c(a,m);R>0&&(a=a.slice(R));let y=d.facts[ae]?.tokenUsage??0,h=n.length,g=a.length;return h+y>t?{passed:false,reason:"Token rate limit exceeded"}:g>=r?{passed:false,reason:"Request rate limit exceeded"}:(a.length<s&&a.push(u),n.length<s&&n.push(u),{passed:true})};return i.reset=()=>{n=[],a=[];},i}function Ft(e){let{allowlist:t,denylist:r,caseSensitive:s=false}=e,n=t?.map(o=>s?o:o.toLowerCase()),a=r?.map(o=>s?o:o.toLowerCase());return o=>{let c=s?o.toolCall.name:o.toolCall.name.toLowerCase();return n&&!n.includes(c)?{passed:false,reason:`Tool "${o.toolCall.name}" not in allowlist`}:a&&a.includes(c)?{passed:false,reason:`Tool "${o.toolCall.name}" is blocked`}:{passed:true}}}function _t(e){let{validate:t,errorPrefix:r="Output schema validation failed"}=e;return s=>{let n=t(s.output);return typeof n=="boolean"?{passed:n,reason:n?void 0:r}:n.valid?{passed:true}:{passed:false,reason:n.errors?.length?`${r}: ${n.errors.join("; ")}`:r}}}function jt(e){let{type:t,requiredFields:r=[],minLength:s,maxLength:n,minStringLength:a,maxStringLength:o}=e;return c=>{let i=c.output;switch(t){case "string":return typeof i!="string"?{passed:false,reason:`Expected string, got ${typeof i}`}:a!==void 0&&i.length<a?{passed:false,reason:`String too short: ${i.length} < ${a}`}:o!==void 0&&i.length>o?{passed:false,reason:`String too long: ${i.length} > ${o}`}:{passed:true};case "number":return typeof i!="number"||Number.isNaN(i)?{passed:false,reason:`Expected number, got ${typeof i}`}:{passed:true};case "boolean":return typeof i!="boolean"?{passed:false,reason:`Expected boolean, got ${typeof i}`}:{passed:true};case "object":if(typeof i!="object"||i===null||Array.isArray(i))return {passed:false,reason:`Expected object, got ${Array.isArray(i)?"array":typeof i}`};for(let l of r)if(!(l in i))return {passed:false,reason:`Missing required field: ${l}`};return {passed:true};case "array":return Array.isArray(i)?s!==void 0&&i.length<s?{passed:false,reason:`Array too short: ${i.length} < ${s}`}:n!==void 0&&i.length>n?{passed:false,reason:`Array too long: ${i.length} > ${n}`}:{passed:true}:{passed:false,reason:`Expected array, got ${typeof i}`};default:return {passed:false,reason:`Unknown type: ${t}`}}}}function $t(e){let{maxCharacters:t,maxTokens:r,estimateTokens:s=n=>Math.ceil(n.length/4)}=e;return n=>{let a=ut(n.output);if(t!==void 0&&a.length>t)return {passed:false,reason:`Output too long: ${a.length} characters (max: ${t})`};if(r!==void 0){let o=s(a);if(o>r)return {passed:false,reason:`Output too long: ~${o} tokens (max: ${r})`}}return {passed:true}}}function Bt(e){let{blockedPatterns:t,caseSensitive:r=false}=e;t.length===0&&console.warn("[Directive] createContentFilterGuardrail: blockedPatterns is empty \u2014 no content will be filtered");let s=t.map(n=>{if(n instanceof RegExp)return n;let a=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(a,r?"g":"gi")});return n=>{let a=ut(n.output);for(let o of s)if(o.lastIndex=0,o.test(a))return {passed:false,reason:`Output contains blocked content matching: ${o.source}`};return {passed:true}}}function Lt(e){return e.status==="running"}function qt(e){return e.pending.length>0}function se(e,t){return e/1e6*t}var Ut=new Set(["http:","https:"]);function Ht(e){try{let t=new URL(e);if(!Ut.has(t.protocol))throw new Error(`[Directive] Invalid baseURL protocol "${t.protocol}" \u2013 only http: and https: are allowed`)}catch(t){throw t instanceof Error&&t.message.startsWith("[Directive]")?t:new Error(`[Directive] Invalid baseURL "${e}" \u2013 must be a valid URL (e.g. "https://api.openai.com/v1")`)}}function zt(e){let{fetch:t=globalThis.fetch,buildRequest:r,parseResponse:s,parseOutput:n,hooks:a}=e,c=n??(i=>{try{return JSON.parse(i)}catch{return i}});return async(i,l,d)=>{let u=Date.now();a?.onBeforeCall?.({agent:i,input:l,timestamp:u});let m=[{role:"user",content:l}];try{let{url:f,init:R}=r(i,l,m),b=d?.signal?{...R,signal:d.signal}:R,v=await t(f,b);if(!v.ok){let S=await v.text().catch(()=>"");throw new Error(`[Directive] AgentRunner request failed: ${v.status} ${v.statusText}${S?` \u2013 ${S.slice(0,300)}`:""}`)}let y=await s(v,m),h={inputTokens:y.inputTokens??0,outputTokens:y.outputTokens??0},g={role:"assistant",content:y.text},T=[...m,g];d?.onMessage?.(g);let E=Date.now()-u;return a?.onAfterCall?.({agent:i,input:l,output:y.text,totalTokens:y.totalTokens,tokenUsage:h,durationMs:E,timestamp:Date.now()}),{output:c(y.text),messages:T,toolCalls:[],totalTokens:y.totalTokens,tokenUsage:h}}catch(f){let R=Date.now()-u;throw f instanceof Error&&a?.onError?.({agent:i,input:l,error:f,durationMs:R,timestamp:Date.now()}),f}}}function Wt(){return {when(e){return {require(t){let r=0,s={priority(n){return r=n,s},build(){return {when:e,require:t,priority:r}}};return s}}}}}function Vt(e){return {require(t){return {when:e,require:t,priority:0,withPriority(r){return {when:e,require:t,priority:r}}}}}}function pe(e,t){let r=typeof e.content=="string"?e.content:JSON.stringify(e.content);return Math.ceil(r.length/4)}function _e(e,t){return e.reduce((r,s)=>r+pe(s),0)}function ke(e={}){return (t,r={})=>{let s={...e,...r},n=s.maxMessages??100,a=s.preserveRecentCount??5;if(t.length<=n)return {keep:[...t],toSummarize:[],estimatedTokens:_e(t)};let o=t.slice(-a),c=t.slice(0,-a),i=Math.max(0,n-a),l=c.slice(-i),d=c.slice(0,-i||void 0),u=[...l,...o];return {keep:u,toSummarize:d.length>0?d:[],estimatedTokens:_e(u)}}}function ct(e={}){return (t,r={})=>{let s={...e,...r},n=s.maxTokens??4e3,a=s.preserveRecentCount??5,o=s.countSystemMessages??true,c=t.slice(-a),i=t.slice(0,-a),l=c.reduce((f,R)=>!o&&R.role==="system"?f:f+pe(R),0),d=[],u=[],m=l;for(let f=i.length-1;f>=0;f--){let R=i[f],b=!o&&R.role==="system"?0:pe(R);if(m+b<=n)d.unshift(R),m+=b;else {u.push(...i.slice(0,f+1));break}}return {keep:[...d,...c],toSummarize:u,estimatedTokens:m}}}function Jt(e={}){let t=ke(e),r=ct(e);return (s,n={})=>{let a={...e,...n},o=t(s,a),c=r(s,a);return o.keep.length<=c.keep.length?o:c}}function je(e){let{strategy:t,summarizer:r,strategyConfig:s={},autoManage:n=false,onMemoryManaged:a,onManageError:o,maxContextTokens:c}=e,i={messages:[],summaries:[],totalMessagesProcessed:0,estimatedTokens:0},l=false;async function d(){if(l)return {messagesBefore:i.messages.length,messagesAfter:i.messages.length,messagesSummarized:0,estimatedTokensBefore:i.estimatedTokens,estimatedTokensAfter:i.estimatedTokens};l=true;try{let m=i.messages.length,f=i.estimatedTokens,R=t(i.messages,s);if(R.toSummarize.length===0)return {messagesBefore:m,messagesAfter:m,messagesSummarized:0,estimatedTokensBefore:f,estimatedTokensAfter:R.estimatedTokens};let b;r&&R.toSummarize.length>0&&(b=await r(R.toSummarize),i.summaries.push({content:b,messagesCount:R.toSummarize.length,createdAt:Date.now()})),i.messages=R.keep,i.estimatedTokens=R.estimatedTokens;let v={messagesBefore:m,messagesAfter:i.messages.length,messagesSummarized:R.toSummarize.length,summary:b,estimatedTokensBefore:f,estimatedTokensAfter:R.estimatedTokens};return a?.(v),v}finally{l=false;}}function u(){if(l)return;t(i.messages,s).toSummarize.length>0&&d().catch(f=>{let R=f instanceof Error?f:new Error(String(f));o?o(R):console.error("[Directive Memory] Auto-manage error:",R);});}return {getState(){return {...i,messages:[...i.messages],summaries:i.summaries.map(m=>({...m}))}},addMessage(m){i.messages.push(m),i.totalMessagesProcessed++,i.estimatedTokens+=pe(m),n&&u();},addMessages(m){for(let f of m)i.messages.push(f),i.totalMessagesProcessed++,i.estimatedTokens+=pe(f);n&&u();},getContextMessages(){let m=[];if(i.summaries.length>0){let f=i.summaries.map(R=>R.content).join(`
2
2
 
3
3
  ---
4
4
 
@@ -34,10 +34,10 @@ ${r}`),this.name="AllProvidersFailedError",this.errors=Object.freeze([...t]),t.l
34
34
  IMPORTANT: Respond with valid JSON matching `+o+". Output ONLY the JSON object, no additional text or markdown formatting."},u,m;for(let f=0;f<=s;f++){let R=f===0?i:`${i}
35
35
 
36
36
  Your previous response was not valid JSON. Error: ${m}
37
- Please try again with valid JSON only.`,b=await e(d,R,l);u=b;let v=typeof b.output=="string"?b.output:JSON.stringify(b.output);try{let y=n(v),h=r.safeParse(y);if(h.success)return {...b,output:h.data};m=sn(h.error);}catch(y){m=y instanceof Error?y.message:String(y);}}throw new Oe(`[Directive] Failed to get valid structured output after ${s+1} attempts: ${m}`,u)}}var Oe=class extends Error{lastResult;constructor(t,r){super(t),this.name="StructuredOutputError",this.lastResult=r;}};function ln(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.getState=="function"&&typeof t.addMessage=="function"&&typeof t.clear=="function"}function dn(e){return e?ln(e)?e:je({strategy:ke(),strategyConfig:{maxMessages:e.maxMessages??50,preserveRecentCount:e.preserveRecentCount??6},autoManage:true}):null}function gn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.execute=="function"&&typeof t.getState=="function"&&typeof t.reset=="function"}function pn(e){if(!e)return null;if(gn(e))return e;let t=e;if(t.failureThreshold!=null&&t.failureThreshold<1)throw new Error("[AgentStack] circuitBreaker.failureThreshold must be at least 1.");if(t.recoveryTimeMs!=null&&t.recoveryTimeMs<0)throw new Error("[AgentStack] circuitBreaker.recoveryTimeMs must be non-negative.");return plugins.createCircuitBreaker(t)}function Et(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.startSpan=="function"&&typeof t.endSpan=="function"&&typeof t.getDashboard=="function"}function mn(e){return e?Et(e)?e:plugins.createObservability({serviceName:e.serviceName,metrics:{enabled:true},tracing:{enabled:true,sampleRate:1},alerts:e.alerts}):null}function fn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.lookup=="function"&&typeof t.store=="function"&&typeof t.getStats=="function"}function yn(e){if(!e)return null;if(fn(e))return e;if(e.threshold!=null&&(e.threshold<0||e.threshold>1))throw new Error("[AgentStack] cache.threshold must be between 0 and 1.");if(e.maxSize!=null&&e.maxSize<1)throw new Error("[AgentStack] cache.maxSize must be at least 1.");return e.embedder||console.warn("[AgentStack] No cache embedder provided \u2014 using test embedder (character frequency). Provide a real embedder for production use."),We({embedder:e.embedder??Ve(),similarityThreshold:e.threshold??.95,maxCacheSize:e.maxSize??500,ttlMs:e.ttlMs??3e5})}function hn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.publish=="function"&&typeof t.getHistory=="function"&&typeof t.clear=="function"}function bn(e){return e?hn(e)?e:qe({maxHistory:e.maxHistory??100}):null}var rt=class{result;abort;_channel;constructor(t,r,s){this._channel=t,this.result=r,this.abort=s;}[Symbol.asyncIterator](){return this._channel[Symbol.asyncIterator]()}};function Rn(e){let{streaming:t,agents:r,patterns:s,guardrails:n={},maxTokenBudget:a,debug:o=false}=e,c=e.costPerMillionTokens??e.costRatePerMillion??0;e.retry&&e.intelligentRetry&&console.warn("[AgentStack] Both 'retry' (orchestrator-level) and 'intelligentRetry' (HTTP-aware) are configured. This causes double-retry behavior. Use 'intelligentRetry' for HTTP status-aware retry, or 'retry' for orchestrator-level retry, but not both.");let i=e.runner;e.modelSelection&&e.modelSelection.length>0&&(i=et(i,e.modelSelection)),e.fallback&&(i=Ye([i,...e.fallback.runners],e.fallback.config)),e.intelligentRetry&&(i=Qe(i,e.intelligentRetry)),e.budget&&(i=Ze(i,e.budget)),e.structuredOutput&&(i=tt(i,e.structuredOutput));let l=dn(e.memory),d=pn(e.circuitBreaker),u=mn(e.observability),m=yn(e.cache),f=bn(e.messageBus??e.bus),R=u?plugins.createAgentMetrics(u):null,b=null,v=null,y=0;if(e.rateLimit){let{maxPerMinute:k}=e.rateLimit;if(k<1||!Number.isFinite(k))throw new Error("[AgentStack] rateLimit.maxPerMinute must be a positive finite number.");v=[];let B=v;b={name:"rate-limit",fn:()=>{let F=Date.now(),U=F-6e4;for(;y<B.length&&B[y]<U;)y++;return y>B.length/2&&y>100&&(B.splice(0,y),y=0),B.length-y>=k?{passed:false,reason:`Rate limit exceeded (${k}/min)`}:(B.push(F),{passed:true})}};}let h=[...b?[b]:[],...n.input??[]],g=nt({runner:i,maxTokenBudget:a,memory:l??void 0,circuitBreaker:d??void 0,guardrails:{input:h.length>0?h:void 0,output:n.output},constraints:e.constraints,resolvers:e.resolvers,autoApproveToolCalls:e.approvals?.autoApproveToolCalls,onApprovalRequest:e.approvals?.onRequest,approvalTimeoutMs:e.approvals?.timeoutMs,agentRetry:e.retry,hooks:e.hooks,debug:o}),T=null;r&&(T=Le({runner:i,agents:r,patterns:s}));let E=null;t&&(E=Be(t.runner,{streamingGuardrails:n.streaming}));let S=null,p=null;if(e.otlp&&u){if(e.otlp.intervalMs!=null&&(!Number.isFinite(e.otlp.intervalMs)||e.otlp.intervalMs<1e3))throw new Error("[AgentStack] otlp.intervalMs must be at least 1000ms.");S=plugins.createOTLPExporter({endpoint:e.otlp.endpoint,serviceName:e.observability&&!Et(e.observability)?e.observability.serviceName:"directive-agents",onError:e.otlp.onError});let k=e.otlp.onError,B=e.otlp.intervalMs??15e3;p=setInterval(()=>{if(!(!u||!S))try{let F=u.export();F.metrics.length>0&&S.exportMetrics(F.metrics),F.traces.length>0&&S.exportTraces(F.traces);}catch(F){k?.(F instanceof Error?F:new Error(String(F)),"metrics");}},B);}let w=0;function C(k){if(!r)throw new Error(`[AgentStack] No agents registered.
37
+ Please try again with valid JSON only.`,b=await e(d,R,l);u=b;let v=typeof b.output=="string"?b.output:JSON.stringify(b.output);try{let y=n(v),h=r.safeParse(y);if(h.success)return {...b,output:h.data};m=sn(h.error);}catch(y){m=y instanceof Error?y.message:String(y);}}throw new Oe(`[Directive] Failed to get valid structured output after ${s+1} attempts: ${m}`,u)}}var Oe=class extends Error{lastResult;constructor(t,r){super(t),this.name="StructuredOutputError",this.lastResult=r;}};function ln(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.getState=="function"&&typeof t.addMessage=="function"&&typeof t.clear=="function"}function dn(e){return e?ln(e)?e:je({strategy:ke(),strategyConfig:{maxMessages:e.maxMessages??50,preserveRecentCount:e.preserveRecentCount??6},autoManage:true}):null}function gn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.execute=="function"&&typeof t.getState=="function"&&typeof t.reset=="function"}function pn(e){if(!e)return null;if(gn(e))return e;let t=e;if(t.failureThreshold!=null&&t.failureThreshold<1)throw new Error("[AgentStack] circuitBreaker.failureThreshold must be at least 1.");if(t.recoveryTimeMs!=null&&t.recoveryTimeMs<0)throw new Error("[AgentStack] circuitBreaker.recoveryTimeMs must be non-negative.");return plugins.createCircuitBreaker(t)}function Et(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.startSpan=="function"&&typeof t.endSpan=="function"&&typeof t.getDashboard=="function"}function mn(e){return e?Et(e)?e:plugins.createObservability({serviceName:e.serviceName,metrics:{enabled:true},tracing:{enabled:true,sampleRate:1},alerts:e.alerts}):null}function fn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.lookup=="function"&&typeof t.store=="function"&&typeof t.getStats=="function"}function yn(e){if(!e)return null;if(fn(e))return e;if(e.threshold!=null&&(e.threshold<0||e.threshold>1))throw new Error("[AgentStack] cache.threshold must be between 0 and 1.");if(e.maxSize!=null&&e.maxSize<1)throw new Error("[AgentStack] cache.maxSize must be at least 1.");return e.embedder||console.warn("[AgentStack] No cache embedder provided \u2014 using test embedder (character frequency). Provide a real embedder for production use."),We({embedder:e.embedder??Ve(),similarityThreshold:e.threshold??.95,maxCacheSize:e.maxSize??500,ttlMs:e.ttlMs??3e5})}function hn(e){if(e==null||typeof e!="object")return false;let t=e;return typeof t.publish=="function"&&typeof t.getHistory=="function"&&typeof t.clear=="function"}function bn(e){return e?hn(e)?e:qe({maxHistory:e.maxHistory??100}):null}var rt=class{result;abort;_channel;constructor(t,r,s){this._channel=t,this.result=r,this.abort=s;}[Symbol.asyncIterator](){return this._channel[Symbol.asyncIterator]()}};function Rn(e){let{streaming:t,agents:r,patterns:s,guardrails:n={},maxTokenBudget:a,debug:o=false}=e,c=e.costPerMillionTokens??0;e.retry&&e.intelligentRetry&&console.warn("[AgentStack] Both 'retry' (orchestrator-level) and 'intelligentRetry' (HTTP-aware) are configured. This causes double-retry behavior. Use 'intelligentRetry' for HTTP status-aware retry, or 'retry' for orchestrator-level retry, but not both.");let i=e.runner;e.modelSelection&&e.modelSelection.length>0&&(i=et(i,e.modelSelection)),e.fallback&&(i=Ye([i,...e.fallback.runners],e.fallback.config)),e.intelligentRetry&&(i=Qe(i,e.intelligentRetry)),e.budget&&(i=Ze(i,e.budget)),e.structuredOutput&&(i=tt(i,e.structuredOutput));let l=dn(e.memory),d=pn(e.circuitBreaker),u=mn(e.observability),m=yn(e.cache),f=bn(e.messageBus),R=u?plugins.createAgentMetrics(u):null,b=null,v=null,y=0;if(e.rateLimit){let{maxPerMinute:k}=e.rateLimit;if(k<1||!Number.isFinite(k))throw new Error("[AgentStack] rateLimit.maxPerMinute must be a positive finite number.");v=[];let B=v;b={name:"rate-limit",fn:()=>{let F=Date.now(),U=F-6e4;for(;y<B.length&&B[y]<U;)y++;return y>B.length/2&&y>100&&(B.splice(0,y),y=0),B.length-y>=k?{passed:false,reason:`Rate limit exceeded (${k}/min)`}:(B.push(F),{passed:true})}};}let h=[...b?[b]:[],...n.input??[]],g=nt({runner:i,maxTokenBudget:a,memory:l??void 0,circuitBreaker:d??void 0,guardrails:{input:h.length>0?h:void 0,output:n.output},constraints:e.constraints,resolvers:e.resolvers,autoApproveToolCalls:e.approvals?.autoApproveToolCalls,onApprovalRequest:e.approvals?.onRequest,approvalTimeoutMs:e.approvals?.timeoutMs,agentRetry:e.retry,hooks:e.hooks,debug:o}),T=null;r&&(T=Le({runner:i,agents:r,patterns:s}));let E=null;t&&(E=Be(t.runner,{streamingGuardrails:n.streaming}));let S=null,p=null;if(e.otlp&&u){if(e.otlp.intervalMs!=null&&(!Number.isFinite(e.otlp.intervalMs)||e.otlp.intervalMs<1e3))throw new Error("[AgentStack] otlp.intervalMs must be at least 1000ms.");S=plugins.createOTLPExporter({endpoint:e.otlp.endpoint,serviceName:e.observability&&!Et(e.observability)?e.observability.serviceName:"directive-agents",onError:e.otlp.onError});let k=e.otlp.onError,B=e.otlp.intervalMs??15e3;p=setInterval(()=>{if(!(!u||!S))try{let F=u.export();F.metrics.length>0&&S.exportMetrics(F.metrics),F.traces.length>0&&S.exportTraces(F.traces);}catch(F){k?.(F instanceof Error?F:new Error(String(F)),"metrics");}},B);}let w=0;function C(k){if(!r)throw new Error(`[AgentStack] No agents registered.
38
38
  Add to config: agents: { myAgent: { agent: myAgentDef, description: '...' } }`);let B=r[k];if(!B){let F=Object.keys(r).join(", ");throw new Error(`[AgentStack] Agent "${k}" not found in registry. Available: ${F}`)}return B.agent}async function x(k,B,F={}){let U=C(k),z=F.cache===false;if(m&&!z)try{let _=await m.lookup(B,k);if(_.hit&&_.entry){u?.incrementCounter("cache.hits");try{return {output:JSON.parse(_.entry.response),messages:[],toolCalls:[],totalTokens:0,isCached:!0}}catch{o&&console.debug(`[AgentStack] Cache hit for "${k}" contained invalid JSON \u2014 falling through to fresh run.`);}}u?.incrementCounter("cache.misses");}catch{u?.incrementCounter("cache.lookup.errors");}let I=u?.startSpan(`agent.${k}`),D=Date.now();try{let _={};F.guardrails?.output?_.outputGuardrails=F.guardrails.output:r?.[k]?.guardrails?.output&&(_.outputGuardrails=[...n.output??[],...r[k].guardrails.output]),F.signal&&(_.signal=F.signal);let N=await g.run(U,B,_),$=Date.now()-D;if(w+=N.totalTokens,m&&!z&&N.output!=null)try{let G=typeof N.output=="string"?N.output:JSON.stringify(N.output);await m.store(B,G,k);}catch{u?.incrementCounter("cache.store.errors");}return f&&f.publish({type:"INFORM",from:k,to:"*",topic:`${k}.completed`,content:{tokenCount:N.totalTokens}}),R&&R.trackRun(k,{success:!0,latencyMs:$,cost:c>0?se(N.totalTokens,c):void 0}),I&&u?.endSpan(I.spanId,"ok"),N}catch(_){let N=Date.now()-D;throw I&&u?.endSpan(I.spanId,"error"),R&&R.trackRun(k,{success:false,latencyMs:N}),_}}async function M(k,B,F){let{validate:U,retries:z=1,...I}=F,D=null;for(let _=0;_<=z;_++){let N=_>0?{...I,cache:false}:I,$=await x(k,B,N),G=U($.output);if(typeof G=="boolean"?G:G.valid)return $;let H=typeof G=="object"&&G.errors?G.errors.join("; "):"Validation failed";D=new Z({message:`Output validation failed (attempt ${_+1}/${z+1}): ${H}`,code:"OUTPUT_GUARDRAIL_FAILED",guardrailName:"runStructured",guardrailType:"output",agentName:k,input:B,data:$.output}),o&&console.debug(`[AgentStack] runStructured validation failed (attempt ${_+1}):`,H);}throw D}async function L(k,B,F={}){if(!T)throw new Error("[AgentStack] No agents/patterns configured. Provide 'agents' and 'patterns' config.");let U=F.cache===false;if(m&&!U)try{let N=await m.lookup(B,k);if(N.hit&&N.entry){u?.incrementCounter("cache.hits");try{return JSON.parse(N.entry.response)}catch{o&&console.debug(`[AgentStack] Cache hit for pattern "${k}" contained invalid JSON \u2014 falling through to fresh run.`);}}u?.incrementCounter("cache.misses");}catch{u?.incrementCounter("cache.lookup.errors");}for(let N of h){let $=typeof N=="function"?N:N.fn,G=typeof N=="function"?"input-guardrail":N.name,J=await $({input:B,agentName:k},{agentName:k,input:B,facts:{}});if(J&&!J.passed)throw new Z({message:`Input guardrail "${G}" failed: ${J.reason??"unknown"}`,code:"INPUT_GUARDRAIL_FAILED",guardrailName:G,guardrailType:"input",agentName:k,input:B})}let z=u?.startSpan(`pattern.${k}`),I=Date.now(),D=T.getAllAgentStates(),_=0;for(let N of Object.values(D))_+=N.totalTokens;try{let N=await T.runPattern(k,B),$=Date.now()-I,G=T.getAllAgentStates(),J=0;for(let Y of Object.values(G))J+=Y.totalTokens;let H=J-_;if(w+=H,m&&!U&&N!=null)try{let Y=typeof N=="string"?N:JSON.stringify(N);await m.store(B,Y,k);}catch{u?.incrementCounter("cache.store.errors");}return f&&f.publish({type:"INFORM",from:k,to:"*",topic:`${k}.completed`,content:{patternTokens:H}}),R&&R.trackRun(k,{success:!0,latencyMs:$,cost:c>0?se(H,c):void 0}),z&&u?.endSpan(z.spanId,"ok"),N}catch(N){let $=Date.now()-I;throw z&&u?.endSpan(z.spanId,"error"),R&&R.trackRun(k,{success:false,latencyMs:$}),N}}function A(k,B,F={}){if(!E)throw new Error(`[AgentStack] Streaming not configured.
39
39
  Add to config: streaming: { runner: createStreamingCallbackRunner(...) }`);if(d?.getState()==="OPEN")throw new Error("[AgentStack] Circuit breaker is OPEN. Streaming call rejected.");let U=C(k),z=be({bufferSize:100}),I=new AbortController,D=()=>I.abort();F.signal&&F.signal.addEventListener("abort",D,{once:true});let _=u?.startSpan(`stream.${k}`),N=Date.now(),{stream:$,result:G,abort:J}=E(U,B,{signal:I.signal}),H=Ke($,z,X=>X.type==="token"?X.data:""),Y=G.then(X=>{let j=Date.now()-N;return w+=X.totalTokens,F.signal?.removeEventListener("abort",D),_&&u?.endSpan(_.spanId,"ok"),f&&f.publish({type:"INFORM",from:k,to:"*",topic:`${k}.stream.completed`,content:{tokenCount:X.totalTokens}}),R&&R.trackRun(k,{success:true,latencyMs:j,cost:c>0?se(X.totalTokens,c):void 0}),X}).catch(X=>{let j=Date.now()-N;throw F.signal?.removeEventListener("abort",D),_&&u?.endSpan(_.spanId,"error"),R&&R.trackRun(k,{success:false,latencyMs:j}),X});return H.catch(X=>{o&&console.debug("[AgentStack] Pipe error:",X);}),new rt(z,Y,()=>{J(),I.abort(),F.signal?.removeEventListener("abort",D);})}function P(k,B,F={}){if(!E)throw new Error(`[AgentStack] Streaming not configured.
40
- Add to config: streaming: { runner: createStreamingCallbackRunner(...) }`);if(d?.getState()==="OPEN")throw new Error("[AgentStack] Circuit breaker is OPEN. Streaming call rejected.");let U=C(k),z=new AbortController,I=()=>z.abort();F.signal&&F.signal.addEventListener("abort",I,{once:true});let D=u?.startSpan(`streamChunks.${k}`),_=Date.now(),{stream:N,result:$,abort:G}=E(U,B,{signal:z.signal}),J=$.then(Y=>{let X=Date.now()-_;return w+=Y.totalTokens,F.signal?.removeEventListener("abort",I),D&&u?.endSpan(D.spanId,"ok"),f&&f.publish({type:"INFORM",from:k,to:"*",topic:`${k}.streamChunks.completed`,content:{tokenCount:Y.totalTokens}}),R&&R.trackRun(k,{success:true,latencyMs:X,cost:c>0?se(Y.totalTokens,c):void 0}),Y}).catch(Y=>{let X=Date.now()-_;throw F.signal?.removeEventListener("abort",I),D&&u?.endSpan(D.spanId,"error"),R&&R.trackRun(k,{success:false,latencyMs:X}),Y}),H=false;return {stream:N,result:J,abort:()=>{H||(H=true,G(),z.abort(),F.signal?.removeEventListener("abort",I));}}}function O(){let k=null;if(e.rateLimit&&v){let F=Date.now()-6e4;for(;y<v.length&&v[y]<F;)y++;let U=v.length-y;k=Math.max(0,e.rateLimit.maxPerMinute-U);}return {totalTokens:w,estimatedCost:c>0?se(w,c):0,circuitState:d?.getState()??"CLOSED",cacheStats:m?.getStats()??{totalEntries:0,totalHits:0,totalMisses:0,hitRate:0,avgSimilarityOnHit:0,oldestEntry:null,newestEntry:null},memoryMessageCount:l?.getState()?.messages?.length??0,busMessageCount:f?.getHistory()?.length??0,rateLimitRemaining:k}}function q(){l?.clear(),d?.reset(),m?.clear(),u?.clear(),f?.clear(),T?.reset(),v&&(v.length=0,y=0),w=0;}let W=false;async function K(){if(!W){if(W=true,p&&u&&S){clearInterval(p),p=null;try{let k=u.export();k.metrics.length>0&&S.exportMetrics(k.metrics),k.traces.length>0&&S.exportTraces(k.traces);}catch{}}else p&&(clearInterval(p),p=null);g.dispose(),T?.dispose(),await u?.dispose();}}return {run:x,runStructured:M,runPattern:L,stream:A,streamChunks:P,approve:k=>g.approve(k),reject:(k,B)=>g.reject(k,B),getState:O,reset:q,dispose:K,get orchestrator(){return g},get observability(){return u},get messageBus(){return f},get coordinator(){return T},get cache(){return m},get memory(){return l},getTimeline(k=50){return {spans:u?.getTraces(k)??[],metrics:u?.getDashboard()?.metrics??{}}},get obs(){return u},get bus(){return f},get multi(){return T}}}function vn(e,t){return function(){t(e.getState());}}function wn(e,t){let r=e.metadata.title??"",s=e.metadata.section??"",n=e.metadata.url??"";return `${r&&s&&n?`[${r} \u2014 ${s}](${n})`:r||e.id}
40
+ Add to config: streaming: { runner: createStreamingCallbackRunner(...) }`);if(d?.getState()==="OPEN")throw new Error("[AgentStack] Circuit breaker is OPEN. Streaming call rejected.");let U=C(k),z=new AbortController,I=()=>z.abort();F.signal&&F.signal.addEventListener("abort",I,{once:true});let D=u?.startSpan(`streamChunks.${k}`),_=Date.now(),{stream:N,result:$,abort:G}=E(U,B,{signal:z.signal}),J=$.then(Y=>{let X=Date.now()-_;return w+=Y.totalTokens,F.signal?.removeEventListener("abort",I),D&&u?.endSpan(D.spanId,"ok"),f&&f.publish({type:"INFORM",from:k,to:"*",topic:`${k}.streamChunks.completed`,content:{tokenCount:Y.totalTokens}}),R&&R.trackRun(k,{success:true,latencyMs:X,cost:c>0?se(Y.totalTokens,c):void 0}),Y}).catch(Y=>{let X=Date.now()-_;throw F.signal?.removeEventListener("abort",I),D&&u?.endSpan(D.spanId,"error"),R&&R.trackRun(k,{success:false,latencyMs:X}),Y}),H=false;return {stream:N,result:J,abort:()=>{H||(H=true,G(),z.abort(),F.signal?.removeEventListener("abort",I));}}}function O(){let k=null;if(e.rateLimit&&v){let F=Date.now()-6e4;for(;y<v.length&&v[y]<F;)y++;let U=v.length-y;k=Math.max(0,e.rateLimit.maxPerMinute-U);}return {totalTokens:w,estimatedCost:c>0?se(w,c):0,circuitState:d?.getState()??"CLOSED",cacheStats:m?.getStats()??{totalEntries:0,totalHits:0,totalMisses:0,hitRate:0,avgSimilarityOnHit:0,oldestEntry:null,newestEntry:null},memoryMessageCount:l?.getState()?.messages?.length??0,busMessageCount:f?.getHistory()?.length??0,rateLimitRemaining:k}}function q(){l?.clear(),d?.reset(),m?.clear(),u?.clear(),f?.clear(),T?.reset(),v&&(v.length=0,y=0),w=0;}let W=false;async function K(){if(!W){if(W=true,p&&u&&S){clearInterval(p),p=null;try{let k=u.export();k.metrics.length>0&&S.exportMetrics(k.metrics),k.traces.length>0&&S.exportTraces(k.traces);}catch{}}else p&&(clearInterval(p),p=null);g.dispose(),T?.dispose(),await u?.dispose();}}return {run:x,runStructured:M,runPattern:L,stream:A,streamChunks:P,approve:k=>g.approve(k),reject:(k,B)=>g.reject(k,B),getState:O,reset:q,dispose:K,get orchestrator(){return g},get observability(){return u},get messageBus(){return f},get coordinator(){return T},get cache(){return m},get memory(){return l},getTimeline(k=50){return {spans:u?.getTraces(k)??[],metrics:u?.getDashboard()?.metrics??{}}}}}function vn(e,t){return function(){t(e.getState());}}function wn(e,t){let r=e.metadata.title??"",s=e.metadata.section??"",n=e.metadata.url??"";return `${r&&s&&n?`[${r} \u2014 ${s}](${n})`:r||e.id}
41
41
  ${e.content}`}function Sn(e,t){return e.length===0?"":`Relevant documentation context:
42
42
 
43
43
  ${e.join(`