UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

80 lines • 3.19 kB
/** The first window whose token or spend ceiling is reached, as a {@link QuotaBlock}. */ export function exhaustedWindow(windows) { for (const window of windows) { const tokensOut = window.limitTokens !== undefined && (window.usedTokens ?? 0) >= window.limitTokens; const spendOut = window.limitUsd !== undefined && window.usedUsd >= window.limitUsd; if (tokensOut || spendOut) { return { period: window.period, reason: `${window.period === 'day' ? 'Daily' : 'Monthly'} ${spendOut ? 'spend' : 'token'} limit reached`, }; } } return undefined; } /** How much of `window`'s ceilings is used, `0..1+` (the larger of spend and tokens), or `null`. */ export function quotaUsedRatio(window) { const ratios = []; if (window.limitUsd !== undefined && window.limitUsd > 0) { ratios.push(window.usedUsd / window.limitUsd); } if (window.limitTokens !== undefined && window.limitTokens > 0 && window.usedTokens !== undefined) { ratios.push(window.usedTokens / window.limitTokens); } return ratios.length === 0 ? null : Math.max(...ratios); } /** * The fullest window past its `warnAt`, as a {@link QuotaWarning} — `undefined` when none is, or * when one is exhausted (that is `blocked`, not a warning). */ export function quotaWarning(windows) { if (exhaustedWindow(windows) !== undefined) return undefined; let fullest; for (const window of windows) { if (window.warnAt === undefined) continue; const ratio = quotaUsedRatio(window); if (ratio === null || ratio < window.warnAt) continue; if (fullest === undefined || ratio > fullest.ratio) { fullest = { period: window.period, ratio }; } } return fullest; } /** The UTC day range (`YYYY-MM-DD`, inclusive) and reset instant of `period` around `now`. */ export function quotaPeriodRange(period, now) { const year = now.getUTCFullYear(); const month = now.getUTCMonth(); const day = now.toISOString().slice(0, 10); if (period === 'day') { const next = new Date(Date.UTC(year, month, now.getUTCDate() + 1)); return { fromDay: day, toDay: day, resetsAt: next.toISOString() }; } const first = new Date(Date.UTC(year, month, 1)); const last = new Date(Date.UTC(year, month + 1, 0)); return { fromDay: first.toISOString().slice(0, 10), toDay: last.toISOString().slice(0, 10), resetsAt: new Date(Date.UTC(year, month + 1, 1)).toISOString(), }; } /** Is this a {@link QuotaProvider} (rather than a daily `QuotaStore`)? */ export function isQuotaProvider(value) { return (typeof value === 'object' && value !== null && typeof value.report === 'function'); } /** A send refused because a budget window is exhausted — the chat route's `429 quota_exceeded`. */ export class QuotaBlockedError extends Error { period; constructor(period, message) { super(message); this.period = period; this.name = 'QuotaBlockedError'; } } //# sourceMappingURL=quota-provider.js.map