feat: add exe.dev usage tracking

This commit is contained in:
Bohdan Triapitsyn
2026-09-03 11:49:34 +03:00
parent 62a18f07a0
commit da6ab52a65
30 changed files with 300 additions and 16 deletions
@@ -0,0 +1,75 @@
import { readManagedCredential } from '../credentials/providers.js';
import { asObject, buildResult, formatMoney, toNumber, toTimestamp, toUsageWindow } from '../utils/index.js';
export const providerId = 'exe-dev';
export const providerName = 'exe.dev';
export const aliases = ['exe-dev'];
const EXEC_URL = 'https://exe.dev/exec';
const USAGE_COMMAND = 'billing credits usage --group=day --json';
export const parseExeDevUsage = (payload) => {
const data = asObject(payload);
if (!data) return null;
const totalCost = toNumber(data.total_cost_usd);
const monthlyAllowance = toNumber(data.monthly_allowance_usd);
const resetAt = toTimestamp(data.period_end);
if (totalCost === null || monthlyAllowance === null || monthlyAllowance < 0 || resetAt === null) return null;
const usedPercent = monthlyAllowance > 0
? Math.min(100, Math.max(0, (totalCost / monthlyAllowance) * 100))
: null;
const spent = formatMoney(totalCost);
const allowance = formatMoney(monthlyAllowance);
if (spent === null || allowance === null) return null;
return {
monthly: toUsageWindow({
usedPercent,
windowSeconds: null,
resetAt,
valueLabel: `$${spent} / $${allowance}`,
}),
};
};
export const fetchExeDevUsage = async (credential, fetchImpl = fetch) => {
const response = await fetchImpl(EXEC_URL, {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${credential.usageToken}`,
'Content-Type': 'text/plain',
'User-Agent': 'OpenChamber quota provider',
},
body: USAGE_COMMAND,
signal: AbortSignal.timeout(15_000),
});
if (response.status === 401 || response.status === 403) throw new Error('exe.dev authentication failed');
if (!response.ok) throw new Error(`exe.dev usage API returned HTTP ${response.status}`);
const windows = parseExeDevUsage(await response.json().catch(() => null));
if (!windows) throw new Error('exe.dev usage data could not be parsed');
return windows;
};
export const isConfigured = () => Boolean(readManagedCredential(providerId));
export const fetchQuota = async () => {
const credential = readManagedCredential(providerId);
if (!credential) {
return buildResult({ providerId, providerName, ok: false, configured: false, error: 'Not configured' });
}
try {
const windows = await fetchExeDevUsage(credential);
return buildResult({ providerId, providerName, ok: true, configured: true, usage: { windows } });
} catch (error) {
return buildResult({
providerId,
providerName,
ok: false,
configured: true,
error: error instanceof Error ? error.message : 'Request failed',
});
}
};
@@ -0,0 +1,47 @@
import { describe, expect, it } from 'bun:test';
import { fetchExeDevUsage, parseExeDevUsage } from './exe-dev.js';
const payload = {
allowance_spend_usd: 0.11,
extra_spend_usd: 0,
group: 'day',
month: '2026-09',
monthly_allowance_usd: 20,
period_end: '2026-10-01T00:00:00Z',
period_start: '2026-09-01T00:00:00Z',
total_cost_usd: 0.11,
total_requests: 17,
};
describe('exe.dev quota provider', () => {
it('parses monthly credit usage', () => {
const windows = parseExeDevUsage(payload);
expect(windows?.monthly.usedPercent).toBeCloseTo(0.55);
expect(windows?.monthly.valueLabel).toBe('$0.11 / $20.00');
expect(windows?.monthly.resetAt).toBe(Date.parse('2026-10-01T00:00:00Z'));
});
it('sends the scoped billing command without exposing the token elsewhere', async () => {
const requests = [];
const windows = await fetchExeDevUsage({ usageToken: 'test-token' }, async (url, init) => {
requests.push({ url, init });
return Response.json(payload);
});
expect(windows.monthly.valueLabel).toBe('$0.11 / $20.00');
expect(requests).toHaveLength(1);
expect(requests[0].url).toBe('https://exe.dev/exec');
expect(requests[0].init.method).toBe('POST');
expect(requests[0].init.body).toBe('billing credits usage --group=day --json');
expect(requests[0].init.headers.Authorization).toBe('Bearer test-token');
});
it('rejects malformed successful responses', async () => {
await expect(fetchExeDevUsage({ usageToken: 'test-token' }, async () => Response.json({})))
.rejects.toThrow('could not be parsed');
});
it('reports authentication failure without including the token', async () => {
await expect(fetchExeDevUsage({ usageToken: 'test-token' }, async () => new Response('', { status: 401 })))
.rejects.toThrow('exe.dev authentication failed');
});
});
@@ -13,6 +13,7 @@ import * as copilot from './copilot.js';
import * as crof from './crof.js';
import * as cursor from './cursor.js';
import * as deepseek from './deepseek.js';
import * as exeDev from './exe-dev.js';
import * as google from './google/index.js';
import * as kimi from './kimi.js';
import * as nanogpt from './nanogpt.js';
@@ -59,6 +60,12 @@ const registry = {
isConfigured: deepseek.isConfigured,
fetchQuota: deepseek.fetchQuota
},
'exe-dev': {
providerId: exeDev.providerId,
providerName: exeDev.providerName,
isConfigured: exeDev.isConfigured,
fetchQuota: exeDev.fetchQuota
},
google: {
providerId: google.providerId,
providerName: google.providerName,