import { r as guardedFetch } from "./endpoint-allowlist-C4ojr3jY.mjs";
//#region extensions/crypto/src/services/credit-monitor.ts
/**
* Credit Monitor — proactive LLM credit balance monitoring.
*
* Periodically checks the Bankr LLM Gateway credit balance and emits
* alerts when balance drops below configurable thresholds. Integrates
* with the channel sender to notify users before credits run out.
*
* Architecture follows the HeartbeatMonitor pattern:
* - Periodic timer with configurable interval
* - Alert callbacks wired by index.ts to channel sender
* - Event bus integration for credit_low events
*/
const BANKR_BASE = "https://llm.bankr.bot";
/** Suppress duplicate alerts for this long after firing one. */
const ALERT_COOLDOWN_MS = 30 * 6e4;
var CreditMonitor = class {
	config;
	timer = null;
	running = false;
	callbacks = [];
	lastAlertTimestamp = 0;
	lastBalance = null;
	checkCount = 0;
	tickInProgress = false;
	constructor(config = {}) {
		this.config = {
			intervalMs: config.intervalMs ?? 3e5,
			warningThresholdUsd: config.warningThresholdUsd ?? 5,
			criticalThresholdUsd: config.criticalThresholdUsd ?? 1,
			enabled: config.enabled ?? true
		};
	}
	/** Register an alert callback. */
	onAlert(cb) {
		this.callbacks.push(cb);
	}
	/** Start periodic checking. */
	start() {
		if (this.running || !this.config.enabled) return;
		this.running = true;
		this.timer = setInterval(() => this.tick(), this.config.intervalMs);
		if (this.timer && typeof this.timer.unref === "function") this.timer.unref();
		setTimeout(() => this.tick(), 1e4);
	}
	/** Stop periodic checking. */
	stop() {
		this.running = false;
		if (this.timer) {
			clearInterval(this.timer);
			this.timer = null;
		}
	}
	/** Get current state (for /llmcredits display). */
	getState() {
		return {
			lastBalance: this.lastBalance,
			checkCount: this.checkCount,
			running: this.running
		};
	}
	get isRunning() {
		return this.running;
	}
	/** Run one check cycle. */
	async tick() {
		if (this.tickInProgress) return;
		this.tickInProgress = true;
		try {
			const key = process.env.BANKR_LLM_KEY;
			if (!key) return;
			const balance = await this.fetchBalance(key);
			if (balance === null) return;
			this.lastBalance = balance;
			this.checkCount++;
			const now = Date.now();
			const cooldownExpired = now - this.lastAlertTimestamp > ALERT_COOLDOWN_MS;
			if (balance <= this.config.criticalThresholdUsd && cooldownExpired) {
				this.lastAlertTimestamp = now;
				this.emitAlert({
					severity: "critical",
					balance,
					currency: "USD",
					message: `LLM credits critically low: $${balance.toFixed(2)} remaining. Top up immediately with \`/topup 25\` or enable auto top-up with \`/autotopup enable\`.`,
					timestamp: now
				});
			} else if (balance <= this.config.warningThresholdUsd && cooldownExpired) {
				this.lastAlertTimestamp = now;
				this.emitAlert({
					severity: "warning",
					balance,
					currency: "USD",
					message: `LLM credits low: $${balance.toFixed(2)} remaining. Consider topping up with \`/topup 25\` or enable \`/autotopup enable\`.`,
					timestamp: now
				});
			}
		} finally {
			this.tickInProgress = false;
		}
	}
	async fetchBalance(key) {
		try {
			const res = await guardedFetch(`${BANKR_BASE}/v1/credits`, {
				headers: {
					"X-API-Key": key,
					"Content-Type": "application/json"
				},
				signal: AbortSignal.timeout(1e4)
			});
			if (!res.ok) return null;
			const data = await res.json();
			const balance = data?.balance ?? data?.credits ?? data?.remaining ?? null;
			if (typeof balance !== "number") return null;
			return balance;
		} catch {
			return null;
		}
	}
	emitAlert(alert) {
		for (const cb of this.callbacks) try {
			const result = cb(alert);
			if (result && typeof result.catch === "function") result.catch(() => {});
		} catch {}
	}
};
let instance = null;
function getCreditMonitor(config) {
	if (!instance) instance = new CreditMonitor(config);
	return instance;
}
//#endregion
export { getCreditMonitor };

//# sourceMappingURL=credit-monitor-a4fmlgrF.mjs.map