monitor-openrouter-credits.js
1 /** 2 * Cron Job: Monitor OpenRouter Credits 3 * Runs periodically to check credit balance and alert if low 4 * Logs balance to database for historical tracking 5 * 6 * Schedule: Every 6 hours 7 * Purpose: Early warning of credit depletion to avoid service disruption 8 */ 9 10 import { monitorCredits } from '../utils/openrouter-monitor.js'; 11 import '../utils/load-env.js'; 12 13 const DEFAULT_THRESHOLD = parseFloat(process.env.OPENROUTER_CREDIT_THRESHOLD || '10.0'); 14 15 async function main() { 16 console.log('[monitor-openrouter-credits] Starting credit check...'); 17 18 try { 19 // Check if OpenRouter is configured 20 if (!process.env.OPENROUTER_API_KEY) { 21 console.log('[monitor-openrouter-credits] Skipping: OPENROUTER_API_KEY not configured'); 22 return; 23 } 24 25 const status = await monitorCredits({ threshold: DEFAULT_THRESHOLD }); 26 27 // Log current status 28 if (status.remaining === null) { 29 console.log('[monitor-openrouter-credits] Balance: Unlimited (Free tier or no limit)'); 30 } else { 31 console.log( 32 `[monitor-openrouter-credits] Balance: $${status.remaining.toFixed(2)} remaining` 33 ); 34 35 if (status.burnRate !== null) { 36 console.log(`[monitor-openrouter-credits] Burn rate: $${status.burnRate.toFixed(2)}/day`); 37 38 if (status.daysLeft !== null) { 39 console.log(`[monitor-openrouter-credits] Days left: ${status.daysLeft.toFixed(1)} days`); 40 } 41 } 42 } 43 44 // Alert if low 45 if (status.alert) { 46 console.error( 47 `[monitor-openrouter-credits] ${status.alert.level.toUpperCase()}: ${status.alert.message}` 48 ); 49 50 // In production, you could send alerts here: 51 // - Email notification 52 // - Slack/Discord webhook 53 // - SMS alert 54 // - Create agent task to investigate 55 } else if (status.remaining !== null) { 56 console.log('[monitor-openrouter-credits] ✓ Credits OK'); 57 } 58 59 console.log('[monitor-openrouter-credits] Completed successfully'); 60 } catch (err) { 61 console.error('[monitor-openrouter-credits] Error:', err.message); 62 throw err; 63 } 64 } 65 66 // Run if called directly 67 if (import.meta.url === `file://${process.argv[1]}`) { 68 main() 69 .then(() => process.exit(0)) 70 .catch(err => { 71 console.error('Fatal error:', err); 72 process.exit(1); 73 }); 74 } 75 76 export default main;