build: token-monitor v0.1.0 — modular LLM API quota visibility
Implements modular provider probing with two distinct header schemas: - Teams direct (unified schema): 5h/7d utilization floats, status, reset countdown - Shelley proxy (classic schema): token/request counts + Exedev-Gateway-Cost (USD/call) - api-ateam: reports no billing data (confirmed non-existent by recon) Key: uses claude-haiku-4-5-20251001 for minimal probe calls (1 token). Rate-limit headers present on ALL responses (200 and 429). 113/113 tests passing. Built from Face recon (trentuna/a-team#91) — live header capture confirmed unified schema with utilization floats replaces old per-count schema.
This commit is contained in:
parent
760049a25e
commit
07a544c50d
10 changed files with 1093 additions and 1 deletions
93
monitor.js
Normal file
93
monitor.js
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* monitor.js — Token Monitor entrypoint
|
||||
*
|
||||
* Probes all configured LLM API providers, extracts rate-limit/quota headers,
|
||||
* and outputs a human-readable summary or JSON.
|
||||
*
|
||||
* Usage:
|
||||
* node monitor.js # human-readable summary + log
|
||||
* node monitor.js --json # JSON to stdout + log
|
||||
* node monitor.js --summary # human-readable only (no log)
|
||||
* node monitor.js --provider team-nadja # single provider
|
||||
* node monitor.js --no-log # suppress log file
|
||||
*/
|
||||
|
||||
import { getProviders } from './providers/index.js';
|
||||
import { probeTeamsProvider } from './providers/anthropic-teams.js';
|
||||
import { getApiAteamStatus } from './providers/anthropic-api.js';
|
||||
import { probeShelleyProxy } from './providers/shelley-proxy.js';
|
||||
import { generateReport, getSeverity } from './report.js';
|
||||
import { logRun } from './logger.js';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const isJson = args.includes('--json');
|
||||
const isSummaryOnly = args.includes('--summary');
|
||||
const noLog = args.includes('--no-log');
|
||||
const filterIdx = args.indexOf('--provider');
|
||||
const filterProvider = filterIdx !== -1 ? args[filterIdx + 1] : null;
|
||||
|
||||
/**
|
||||
* Probe a single provider and return normalized result.
|
||||
*/
|
||||
async function probeProvider(p) {
|
||||
const start = Date.now();
|
||||
let result;
|
||||
|
||||
if (p.type === 'teams-direct') {
|
||||
result = await probeTeamsProvider(p.name, p.baseUrl, p.apiKey);
|
||||
} else if (p.type === 'shelley-proxy') {
|
||||
result = await probeShelleyProxy(p.name, p.baseUrl);
|
||||
} else if (p.type === 'api-direct') {
|
||||
result = getApiAteamStatus();
|
||||
} else {
|
||||
result = { type: 'unknown', status: 'skipped', severity: 'unknown' };
|
||||
}
|
||||
|
||||
result.probe_latency_ms = Date.now() - start;
|
||||
if (!result.severity) {
|
||||
result.severity = getSeverity(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const allProviders = getProviders();
|
||||
const providerNames = filterProvider
|
||||
? [filterProvider]
|
||||
: Object.keys(allProviders);
|
||||
|
||||
if (filterProvider && !allProviders[filterProvider]) {
|
||||
console.error(
|
||||
`Unknown provider: ${filterProvider}. Available: ${Object.keys(allProviders).join(', ')}`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const results = {};
|
||||
for (const name of providerNames) {
|
||||
const p = allProviders[name];
|
||||
results[name] = await probeProvider(p);
|
||||
}
|
||||
|
||||
const output = {
|
||||
timestamp: new Date().toISOString(),
|
||||
providers: results,
|
||||
};
|
||||
|
||||
if (isJson) {
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
} else {
|
||||
console.log(generateReport(output));
|
||||
}
|
||||
|
||||
// Log to file unless --summary or --no-log
|
||||
if (!isSummaryOnly && !noLog) {
|
||||
logRun(output);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('Fatal:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue