Replace the previous implementation with one that registers the Provider API catalog through pi's own provider layer instead of shipping a custom transport, cache file, and hand-maintained pricing table. - models: derive the catalog from the published command-code CLI package (context windows, reasoning efforts, image input, output limits, rates) and keep it as the offline baseline; scripts/sync-catalog.mjs regenerates it and supports --check - refresh: use refreshModels plus context.publish so pi persists the live /provider/v1/models listing in models-store.json and restores it offline - auth: /login browser transfer through a localhost callback server with a pasted-key fallback; $COMMAND_CODE_API_KEY, --api-key and auth.json keep working - streaming: pi's native openai-completions and anthropic-messages adapters; the generate-transport fallback and Oh My Pi branches are gone - keep the context-overflow rewrite that enables pi's compaction retry and the /commandcode-quota command - tests: 51 cases under tests/<module>/ covering models, catalog sync, auth, the callback server, overflow handling, quota, and the extension factory Verified against the live API: chat, tool round trip, image input and --thinking max on deepseek/deepseek-v4.1-flash, quota output, and catalog persistence in an interactive session.
163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import { test } from "node:test"
|
|
|
|
import { formatQuota } from "../../src/quota-format.ts"
|
|
import {
|
|
fetchCommandCodeQuota,
|
|
normalizeResetAt,
|
|
parseAccount,
|
|
parseCredits,
|
|
parseSubscription,
|
|
parseSummary,
|
|
parseWindowLimits,
|
|
} from "../../src/quota.ts"
|
|
|
|
/** Shapes returned by the Command Code alpha account endpoints. */
|
|
const accountResponse = {
|
|
success: true,
|
|
user: { id: "7a18ec22", name: "cat_shark", userName: "shark-cat", keyName: "cli-key" },
|
|
org: null,
|
|
}
|
|
const creditsResponse = {
|
|
credits: { monthlyCredits: 12.5, purchasedCredits: 3, freeCredits: 0 },
|
|
windowLimits: {
|
|
fiveHour: { used: 2.5, cap: 10, resetAt: 1_800_000_000 },
|
|
weekly: { used: 20, cap: 100, resetAt: 1_800_500_000 },
|
|
},
|
|
}
|
|
const subscriptionResponse = {
|
|
data: {
|
|
planId: "go",
|
|
status: "active",
|
|
currentPeriodStart: "2026-09-01T00:00:00.000Z",
|
|
currentPeriodEnd: "2026-10-01T00:00:00.000Z",
|
|
},
|
|
}
|
|
const summaryResponse = { totalCost: 1.23, totalCount: 45, totalTokens: 123_456 }
|
|
|
|
/** Answers each alpha endpoint with its canned payload. */
|
|
function createFetchStub(responses: {
|
|
whoami?: Response
|
|
credits?: Response
|
|
subscription?: Response
|
|
summary?: Response
|
|
}): typeof fetch {
|
|
return async (input) => {
|
|
const url = String(input)
|
|
if (url.includes("/alpha/whoami")) return responses.whoami ?? json(accountResponse)
|
|
if (url.includes("/alpha/billing/credits")) return responses.credits ?? json(creditsResponse)
|
|
if (url.includes("/alpha/billing/subscriptions")) {
|
|
return responses.subscription ?? json(subscriptionResponse)
|
|
}
|
|
if (url.includes("/alpha/usage/summary")) return responses.summary ?? json(summaryResponse)
|
|
throw new Error(`Unexpected request: ${url}`)
|
|
}
|
|
}
|
|
|
|
function json(value: unknown): Response {
|
|
return new Response(JSON.stringify(value), { status: 200 })
|
|
}
|
|
|
|
test("parseAccount accepts user names and organization logins", () => {
|
|
assert.deepEqual(parseAccount(accountResponse), { login: "shark-cat", orgId: null, keyName: "cli-key" })
|
|
assert.deepEqual(parseAccount({ org: { login: "team", id: "org_1" }, user: {} }), {
|
|
login: "team",
|
|
orgId: "org_1",
|
|
})
|
|
assert.equal(parseAccount({ user: {} }), null)
|
|
})
|
|
|
|
test("parseCredits totals the credit sources", () => {
|
|
const credits = parseCredits(creditsResponse)
|
|
|
|
assert.equal(credits?.remainingCredits, 15.5)
|
|
assert.equal(credits?.monthlyCredits, 12.5)
|
|
assert.deepEqual(
|
|
credits?.windowLimits.map((limit) => [limit.window, limit.used, limit.cap]),
|
|
[
|
|
["fiveHour", 2.5, 10],
|
|
["weekly", 20, 100],
|
|
],
|
|
)
|
|
assert.equal(parseCredits({ credits: {} }), null)
|
|
})
|
|
|
|
test("parseWindowLimits drops empty windows and normalizes reset times", () => {
|
|
const limits = parseWindowLimits({
|
|
fiveHour: { used: 0, cap: 0, resetAt: "2026-09-14T10:00:00.000Z" },
|
|
weekly: { used: 4, cap: 8, resetAt: "2026-09-20T10:00:00.000Z" },
|
|
})
|
|
|
|
assert.equal(limits.length, 1)
|
|
assert.equal(limits[0]?.window, "weekly")
|
|
assert.equal(limits[0]?.resetAt, Date.parse("2026-09-20T10:00:00.000Z") / 1000)
|
|
assert.equal(normalizeResetAt(1_800_000_000_000), 1_800_000_000)
|
|
assert.equal(normalizeResetAt("not a date"), null)
|
|
})
|
|
|
|
test("parseSubscription and parseSummary read the plan and usage payloads", () => {
|
|
assert.deepEqual(parseSubscription(subscriptionResponse), {
|
|
planId: "go",
|
|
status: "active",
|
|
currentPeriodStart: "2026-09-01T00:00:00.000Z",
|
|
currentPeriodEnd: "2026-10-01T00:00:00.000Z",
|
|
})
|
|
assert.equal(parseSubscription({ data: {} }), null)
|
|
assert.deepEqual(parseSummary(summaryResponse), { totalCost: 1.23, totalCount: 45, totalTokens: 123_456 })
|
|
assert.equal(parseSummary({ totalCost: 1 }), null)
|
|
})
|
|
|
|
test("fetchCommandCodeQuota assembles every section", async () => {
|
|
const result = await fetchCommandCodeQuota({
|
|
apiKey: "user_abc",
|
|
fetchImpl: createFetchStub({}),
|
|
})
|
|
|
|
assert.equal(result.ok, true)
|
|
if (!result.ok) return
|
|
assert.equal(result.quota.account.login, "shark-cat")
|
|
assert.equal(result.quota.credits?.remainingCredits, 15.5)
|
|
assert.equal(result.quota.subscription?.planId, "go")
|
|
assert.equal(result.quota.summary?.totalCount, 45)
|
|
assert.deepEqual(result.quota.unavailable, [])
|
|
})
|
|
|
|
test("fetchCommandCodeQuota reports rejected keys and missing sections", async () => {
|
|
const rejected = await fetchCommandCodeQuota({
|
|
apiKey: "user_bad",
|
|
fetchImpl: createFetchStub({ whoami: new Response("{}", { status: 401 }) }),
|
|
})
|
|
assert.equal(rejected.ok, false)
|
|
|
|
const partial = await fetchCommandCodeQuota({
|
|
apiKey: "user_abc",
|
|
fetchImpl: createFetchStub({ credits: new Response("{}", { status: 500 }) }),
|
|
})
|
|
assert.equal(partial.ok, true)
|
|
if (!partial.ok) return
|
|
assert.equal(partial.quota.credits, null)
|
|
assert.deepEqual(partial.quota.unavailable, ["credits"])
|
|
})
|
|
|
|
test("fetchCommandCodeQuota without a key fails fast", async () => {
|
|
const result = await fetchCommandCodeQuota({ apiKey: "" })
|
|
|
|
assert.equal(result.ok, false)
|
|
})
|
|
|
|
test("formatQuota renders account, credits and usage sections", async () => {
|
|
const result = await fetchCommandCodeQuota({ apiKey: "user_abc", fetchImpl: createFetchStub({}) })
|
|
assert.equal(result.ok, true)
|
|
if (!result.ok) return
|
|
|
|
const text = formatQuota(result.quota, () => Date.parse("2026-09-14T09:30:00.000Z"))
|
|
|
|
assert.match(text, /Account: shark-cat/)
|
|
assert.match(text, /API key: cli-key/)
|
|
assert.match(text, /Plan: go \(active\)/)
|
|
assert.match(text, /Credits remaining: 15\.50/)
|
|
assert.match(text, /5-hour: 2\.50 \/ 10\.00 credits \(25% used\)/)
|
|
assert.match(text, /Weekly: 20\.00 \/ 100\.00 credits \(20% used\)/)
|
|
assert.match(text, /Usage this period: \$1\.23 over 45 requests \(123456 tokens\)/)
|
|
})
|