"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.PolicyEngine=void 0,exports.getGlobalPolicyEngine=getGlobalPolicyEngine;const shared_1=require("../_deps/shared/index.js"),agent_call_js_1=require("./agent-call.js");class PolicyEngine{rateLimits=new Map;dailySpending=new Map;monthlySpending=new Map;evaluate(t,e,n,o){if(o.allowedTools&&o.allowedTools.length>0){const[t]=e.split(":");if(!o.allowedTools.some(n=>n===e||n===`${t}:*`||"*"===n)){const n={requested:e,allowed:o.allowedTools,constraint:"tool",fix:`Update policy.allowedTools to include "${e}" or "${t}:*" or request approval`};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Tool "${e}" is not allowed by policy`,n))}}if(o.scopes&&o.scopes.length>0){const t="object"==typeof n&&null!==n&&"scope"in n?n.scope:void 0;if(t&&!o.scopes.includes(t)){const e={requested:t,allowed:o.scopes,constraint:"scope",fix:`Update policy.scopes to include "${t}" or request additional permissions`};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Scope "${t}" is not allowed by policy`,e))}}if(o.limits?.callsPerMinute){const e=this.checkRateLimit(t,o.limits.callsPerMinute);if(!e.ok)return e}const i=this.extractAmount(n);if(null!==i){if(o.limits?.amountPerTxn&&i>o.limits.amountPerTxn){const t={requested:i,allowed:o.limits.amountPerTxn,constraint:"amountPerTxn",fix:`Reduce amount to ${o.limits.amountPerTxn} or less, or update policy.limits.amountPerTxn`};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Amount ${i} exceeds per-transaction limit of ${o.limits.amountPerTxn}`,t))}if(o.limits?.dailyAmount){const e=this.checkDailyLimit(t,i,o.limits.dailyAmount);if(!e.ok)return e}if(o.limits?.monthlyAmount){const e=this.checkMonthlyLimit(t,i,o.limits.monthlyAmount);if(!e.ok)return e}}return(0,shared_1.ok)(void 0)}recordCall(t){const e=Date.now(),n=this.rateLimits.get(t)??{calls:[],windowStart:e};n.calls.push(e);const o=e-6e4;n.calls=n.calls.filter(t=>t>o),this.rateLimits.set(t,n)}recordSpending(t,e){const n=this.getCurrentDay(),o=this.getCurrentMonth(),i=this.dailySpending.get(t);i&&i.day===n?i.amount+=e:this.dailySpending.set(t,{amount:e,day:n});const l=this.monthlySpending.get(t);l&&l.month===o?l.amount+=e:this.monthlySpending.set(t,{amount:e,month:o})}getCurrentRateLimit(t){const e=this.rateLimits.get(t);if(!e)return 0;const n=Date.now()-6e4;return e.calls.filter(t=>t>n).length}getDailySpending(t){const e=this.getCurrentDay(),n=this.dailySpending.get(t);return n&&n.day===e?n.amount:0}getMonthlySpending(t){const e=this.getCurrentMonth(),n=this.monthlySpending.get(t);return n&&n.month===e?n.amount:0}reset(t){this.rateLimits.delete(t),this.dailySpending.delete(t),this.monthlySpending.delete(t)}checkRateLimit(t,e){const n=this.getCurrentRateLimit(t);if(n>=e){const t={requested:n+1,allowed:e,constraint:"callsPerMinute",current:n,fix:"Wait before making additional calls, or update policy.limits.callsPerMinute to a higher value"};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Rate limit exceeded: ${n}/${e} calls per minute`,t))}return(0,shared_1.ok)(void 0)}checkDailyLimit(t,e,n){const o=this.getDailySpending(t),i=o+e;if(i>n){const t=n-o,l={requested:e,allowed:n,constraint:"dailyAmount",current:o,newTotal:i,fix:t>0?`Reduce amount to ${t} or less (remaining today), or update policy.limits.dailyAmount`:"Daily limit already reached. Wait until tomorrow or update policy.limits.dailyAmount"};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Amount ${e} would exceed daily limit: ${i}/${n} (current: ${o})`,l))}return(0,shared_1.ok)(void 0)}extractAmount(t){if("object"!=typeof t||null===t)return null;const e=t;return"number"==typeof e.amount?e.amount:"number"==typeof e.value?e.value:"number"==typeof e.price?e.price:"number"==typeof e.total?e.total:null}getCurrentDay(){return(new Date).toISOString().split("T")[0]??""}getCurrentMonth(){return(new Date).toISOString().substring(0,7)}checkMonthlyLimit(t,e,n){const o=this.getMonthlySpending(t),i=o+e;if(i>n){const t=n-o,l={requested:e,allowed:n,constraint:"dailyAmount",current:o,newTotal:i,fix:t>0?`Reduce amount to ${t} or less (remaining this month), or update policy.limits.monthlyAmount`:"Monthly limit already reached. Wait until next month or update policy.limits.monthlyAmount"};return(0,shared_1.err)(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.POLICY_VIOLATION,`Amount ${e} would exceed monthly limit: ${i}/${n} (current: ${o})`,l))}return(0,shared_1.ok)(void 0)}}exports.PolicyEngine=PolicyEngine;let globalPolicyEngine=null;function getGlobalPolicyEngine(){return globalPolicyEngine||(globalPolicyEngine=new PolicyEngine),globalPolicyEngine}