fix(usage): preserve the selected Kimi credential home

Compare deployment credentials within each home so a newer legacy-home
login cannot override KIMI_CODE_HOME. Cover the expired-default plus live
global workflow through discovery and usage fetching.

Co-authored-by: benthecarman <benthecarman@live.com>
This commit is contained in:
paseo-bot[bot]
2026-11-02 00:42:16 +00:00
co-authored by benthecarman
parent 521afd9f33
commit 6d98544251
2 changed files with 51 additions and 3 deletions
@@ -215,6 +215,52 @@ describe("kimi usage source", () => {
]);
});
it("fetches global usage when an expired default-deployment login remains", async () => {
const kimiHome = join(homeDir, ".kimi-code");
writeKimiCredentials(kimiHome, "expired_default", { expires_at: 1_700_000_000 });
writeKimiCredentials(kimiHome, "live_global", { expires_at: 2_000_000_000 }, GLOBAL_SLOT);
const [account] = await discover();
if (!account) throw new Error("No configured Kimi account");
const requests: string[] = [];
const report = await fetchUsage(
account.input as Parameters<typeof fetchUsage>[0],
async (url, init) => {
requests.push(url.toString());
expect(new Headers(init?.headers).get("Authorization")).toBe("Bearer live_global");
return jsonResponse({ usage: { limit: "100", remaining: "60" } });
},
);
expect(requests).toEqual(["https://api.kimi.ai/coding/v1/usages"]);
expect(report).toMatchObject({ status: "available", windows: [{ usedPct: 40 }] });
});
it("keeps KIMI_CODE_HOME ahead of a newer legacy-home login", async () => {
const selectedHome = join(homeDir, "selected-kimi");
process.env.KIMI_CODE_HOME = selectedHome;
writeKimiCredentials(
selectedHome,
"selected_global_token",
{ expires_at: 2_000_000_000 },
GLOBAL_SLOT,
);
writeKimiCredentials(join(homeDir, ".kimi"), "legacy_token", { expires_at: 2_000_000_100 });
const accounts = await discover();
expect(accounts).toEqual([
{
key: "default",
input: {
store: "file",
locator: kimiCredentialPath(selectedHome, GLOBAL_SLOT),
baseUrl: "https://api.kimi.ai/coding/v1",
},
},
]);
});
it("asks the user to run kimi when the CLI token has expired", async () => {
writeKimiCredentials(join(homeDir, ".kimi-code"), "kimi_cli_token", {
expires_at: 1_700_000_000,
+5 -3
View File
@@ -331,9 +331,10 @@ export async function discover(): Promise<UsageAccount[]> {
join(homedir(), ".kimi"),
];
// A login to another deployment leaves the old slot behind with a dead token.
// The CLI keeps refreshing the slot it uses, so the latest expiry wins.
let found: { input: UsageInput; expiresAt: number } | undefined;
// Within each home, prefer the latest expiry. Keep the configured home ahead
// of the legacy fallback, even if that fallback holds a newer token.
for (const home of homes) {
let found: { input: UsageInput; expiresAt: number } | undefined;
for (const deployment of KIMI_CODE_DEPLOYMENTS) {
const input: UsageInput = {
store: "file",
@@ -345,6 +346,7 @@ export async function discover(): Promise<UsageAccount[]> {
const expiresAt = credentials.expires_at ?? Number.POSITIVE_INFINITY;
if (!found || expiresAt > found.expiresAt) found = { input, expiresAt };
}
if (found) return [{ key: "default", input: found.input }];
}
return found ? [{ key: "default", input: found.input }] : [];
return [];
}