fix(auth): migrate to current pi credential API
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { AuthStorage, type AuthCredential, type ExtensionAPI, type ExtensionContext, type ExtensionCommandContext, type ReadonlyFooterDataProvider, type SessionStartEvent, type SessionShutdownEvent, type AgentEndEvent } from "@mariozechner/pi-coding-agent";
|
import { readStoredCredential, type ExtensionAPI, type ExtensionContext, type ExtensionCommandContext, type ReadonlyFooterDataProvider, type SessionStartEvent, type SessionShutdownEvent, type AgentEndEvent } from "@earendil-works/pi-coding-agent";
|
||||||
import { statusbarConfig } from "./config";
|
import { statusbarConfig } from "./config";
|
||||||
import { contextModule, costModule, directoryModule, modelModule, thinkingModule } from "./modules/basic";
|
import { contextModule, costModule, directoryModule, modelModule, thinkingModule } from "./modules/basic";
|
||||||
import { usageModule } from "./modules/usage";
|
import { usageModule } from "./modules/usage";
|
||||||
@@ -31,7 +31,7 @@ function credentialString(raw: unknown, key: string): string | undefined {
|
|||||||
return isRecord(raw) && typeof raw[key] === "string" ? raw[key] : undefined;
|
return isRecord(raw) && typeof raw[key] === "string" ? raw[key] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildUsageCredential(raw: AuthCredential | undefined, apiKey: string): UsageCredential {
|
function buildUsageCredential(raw: ReturnType<typeof readStoredCredential>, apiKey: string): UsageCredential {
|
||||||
if (raw?.type === "oauth") {
|
if (raw?.type === "oauth") {
|
||||||
return {
|
return {
|
||||||
type: "oauth",
|
type: "oauth",
|
||||||
@@ -49,27 +49,14 @@ function buildUsageCredential(raw: AuthCredential | undefined, apiKey: string):
|
|||||||
apiKey,
|
apiKey,
|
||||||
accountId: credentialString(raw, "accountId"),
|
accountId: credentialString(raw, "accountId"),
|
||||||
email: credentialString(raw, "email"),
|
email: credentialString(raw, "email"),
|
||||||
metadata: raw,
|
metadata: raw ? { ...raw } : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readPiCredential(authStorage: AuthStorage, provider: Provider): Promise<UsageCredential | undefined> {
|
async function readPiCredential(ctx: ExtensionContext, provider: Provider): Promise<UsageCredential | undefined> {
|
||||||
authStorage.reload();
|
const apiKey = await ctx.modelRegistry.getApiKeyForProvider(provider);
|
||||||
const apiKey = await authStorage.getApiKey(provider);
|
|
||||||
if (!apiKey) return undefined;
|
if (!apiKey) return undefined;
|
||||||
return buildUsageCredential(authStorage.get(provider), apiKey);
|
return buildUsageCredential(readStoredCredential(provider), apiKey);
|
||||||
}
|
|
||||||
|
|
||||||
async function forceRefreshPiCredential(authStorage: AuthStorage, provider: Provider): Promise<UsageCredential> {
|
|
||||||
authStorage.reload();
|
|
||||||
const raw = authStorage.get(provider);
|
|
||||||
const oauthProvider = authStorage.getOAuthProviders().find(candidate => candidate.id === provider);
|
|
||||||
if (raw?.type !== "oauth" || !oauthProvider) throw new Error("login expired");
|
|
||||||
|
|
||||||
// Refresh Provider OAuth Token
|
|
||||||
const refreshed = await oauthProvider.refreshToken(raw);
|
|
||||||
authStorage.set(provider, { type: "oauth", ...refreshed });
|
|
||||||
return buildUsageCredential(authStorage.get(provider), oauthProvider.getApiKey(refreshed));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderModule(moduleCtx: ModuleContext, spec: ModuleSpec): RenderedModule {
|
function renderModule(moduleCtx: ModuleContext, spec: ModuleSpec): RenderedModule {
|
||||||
@@ -113,7 +100,6 @@ export default function piStatusbarExtension(pi: ExtensionAPI) {
|
|||||||
let latestCtx: ExtensionContext | undefined;
|
let latestCtx: ExtensionContext | undefined;
|
||||||
let requestRender: (() => void) | undefined;
|
let requestRender: (() => void) | undefined;
|
||||||
const statusbarState: StatusbarState = {};
|
const statusbarState: StatusbarState = {};
|
||||||
const authStorage = AuthStorage.create();
|
|
||||||
|
|
||||||
function updateThinkingLevel() {
|
function updateThinkingLevel() {
|
||||||
try {
|
try {
|
||||||
@@ -172,7 +158,7 @@ export default function piStatusbarExtension(pi: ExtensionAPI) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const credential = await readPiCredential(authStorage, provider);
|
const credential = await readPiCredential(ctx, provider);
|
||||||
if (!credential) {
|
if (!credential) {
|
||||||
statusbarState.report = { provider, fetchedAt: Date.now(), limits: [] };
|
statusbarState.report = { provider, fetchedAt: Date.now(), limits: [] };
|
||||||
statusbarState.error = "not logged in";
|
statusbarState.error = "not logged in";
|
||||||
@@ -185,7 +171,6 @@ export default function piStatusbarExtension(pi: ExtensionAPI) {
|
|||||||
inFlight = controller;
|
inFlight = controller;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let activeCredential = credential;
|
|
||||||
const usageCtx = {
|
const usageCtx = {
|
||||||
fetch: globalThis.fetch.bind(globalThis),
|
fetch: globalThis.fetch.bind(globalThis),
|
||||||
logger: {
|
logger: {
|
||||||
@@ -193,21 +178,12 @@ export default function piStatusbarExtension(pi: ExtensionAPI) {
|
|||||||
warn: () => undefined,
|
warn: () => undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const fetchParams = () => ({
|
const report = await usageProviders[provider].fetchUsage({
|
||||||
provider,
|
provider,
|
||||||
credential: activeCredential,
|
credential,
|
||||||
baseUrl: ctx.model?.baseUrl,
|
baseUrl: ctx.model?.baseUrl,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
});
|
}, usageCtx);
|
||||||
|
|
||||||
let report: UsageReport | null;
|
|
||||||
try {
|
|
||||||
report = await usageProviders[provider].fetchUsage(fetchParams(), usageCtx);
|
|
||||||
} catch (error) {
|
|
||||||
if (!(error instanceof Error) || error.message !== "unauthorized") throw error;
|
|
||||||
activeCredential = await forceRefreshPiCredential(authStorage, provider);
|
|
||||||
report = await usageProviders[provider].fetchUsage(fetchParams(), usageCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
statusbarState.report = report ?? { provider, fetchedAt: Date.now(), limits: [] };
|
statusbarState.report = report ?? { provider, fetchedAt: Date.now(), limits: [] };
|
||||||
statusbarState.error = report ? undefined : "unavailable";
|
statusbarState.error = report ? undefined : "unavailable";
|
||||||
|
|||||||
Generated
+1546
-3338
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mariozechner/pi-coding-agent": "^0.72.1",
|
"@earendil-works/pi-coding-agent": "^0.80.10",
|
||||||
"@types/node": "^25.6.0",
|
"@types/node": "^25.6.0",
|
||||||
"oxlint": "^1.62.0",
|
"oxlint": "^1.62.0",
|
||||||
"typescript": "^6.0.3"
|
"typescript": "^6.0.3"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ExtensionContext, ReadonlyFooterDataProvider } from "@mariozechner/pi-coding-agent";
|
import type { ExtensionContext, ReadonlyFooterDataProvider } from "@earendil-works/pi-coding-agent";
|
||||||
import type { UsageLimit, UsageReport } from "./usage";
|
import type { UsageLimit, UsageReport } from "./usage";
|
||||||
|
|
||||||
export type ModuleName = "directory" | "context" | "model" | "thinking" | "cost" | "usage";
|
export type ModuleName = "directory" | "context" | "model" | "thinking" | "cost" | "usage";
|
||||||
|
|||||||
Reference in New Issue
Block a user