pi-credits 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-credits",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A pi extension that shows the active provider's credit balance or rate-limit usage",
5
5
  "keywords": [
6
6
  "pi-coding-agent",
package/src/manager.ts CHANGED
@@ -9,6 +9,7 @@ const REQUEST_TIMEOUT_MS = 30_000;
9
9
 
10
10
  export class CreditsManager {
11
11
  private inflight: AbortController | undefined = undefined;
12
+ private currentProvider: string | undefined = undefined;
12
13
 
13
14
  async refresh(ctx: ExtensionContext): Promise<void> {
14
15
  this.inflight?.abort();
@@ -16,10 +17,17 @@ export class CreditsManager {
16
17
  const provider = findProvider(ctx.model?.provider);
17
18
  if (!provider) {
18
19
  this.inflight = undefined;
20
+ this.currentProvider = undefined;
19
21
  ctx.ui.setStatus(STATUS_KEY, undefined);
20
22
  return;
21
23
  }
22
24
 
25
+ // Clear stale credits from another provider while the new fetch is in flight.
26
+ if (this.currentProvider !== provider.id) {
27
+ this.currentProvider = provider.id;
28
+ ctx.ui.setStatus(STATUS_KEY, undefined);
29
+ }
30
+
23
31
  const controller = new AbortController();
24
32
  this.inflight = controller;
25
33
 
@@ -30,7 +38,7 @@ export class CreditsManager {
30
38
 
31
39
  private async fetch(ctx: ExtensionContext, provider: CreditsProvider, signal: AbortSignal): Promise<void> {
32
40
  try {
33
- const apiKey = await ctx.modelRegistry.getApiKeyForProvider(provider.provider);
41
+ const apiKey = await ctx.modelRegistry.getApiKeyForProvider(provider.id);
34
42
  if (!apiKey) {
35
43
  ctx.ui.setStatus(STATUS_KEY, undefined);
36
44
  return;
@@ -42,12 +50,12 @@ export class CreditsManager {
42
50
  const credits = await provider.fetch(ctx, apiKey, AbortSignal.any(signals));
43
51
 
44
52
  // The active model may have changed while the request was in flight.
45
- if (ctx.model?.provider !== provider.provider) return;
53
+ if (ctx.model?.provider !== provider.id) return;
46
54
 
47
55
  ctx.ui.setStatus(STATUS_KEY, renderCredits(ctx.ui.theme, provider.label, credits));
48
56
  } catch (error) {
49
57
  if (signal.aborted || ctx.signal?.aborted) return;
50
- if (ctx.model?.provider !== provider.provider) return;
58
+ if (ctx.model?.provider !== provider.id) return;
51
59
 
52
60
  const message = error instanceof Error ? error.message : String(error);
53
61
  ctx.ui.setStatus(STATUS_KEY, renderError(ctx.ui.theme, provider.label, message));
@@ -15,7 +15,7 @@ interface DeepSeekBalanceInfo {
15
15
  }
16
16
 
17
17
  export const deepseekProvider: CreditsProvider = {
18
- provider: PROVIDER,
18
+ id: PROVIDER,
19
19
  label: "DeepSeek",
20
20
 
21
21
  async fetch(_ctx, apiKey, signal): Promise<Credits> {
@@ -99,7 +99,7 @@ function moneyToNumber(money: Money | null | undefined): number | undefined {
99
99
  }
100
100
 
101
101
  export const fireworksProvider: CreditsProvider = {
102
- provider: PROVIDER,
102
+ id: PROVIDER,
103
103
  label: "Fireworks",
104
104
 
105
105
  async fetch(_ctx, apiKey, signal): Promise<Credits> {
@@ -18,5 +18,5 @@ const PROVIDERS: CreditsProvider[] = [
18
18
  ];
19
19
 
20
20
  export function findProvider(provider?: string): CreditsProvider | undefined {
21
- return PROVIDERS.find((entry) => entry.provider === provider);
21
+ return PROVIDERS.find((entry) => entry.id === provider);
22
22
  }
@@ -13,9 +13,9 @@ interface MoonshotBalanceResponse {
13
13
  * different currencies (USD vs CNY), which the endpoint does not report, so each pi provider ID
14
14
  * fixes both host and currency.
15
15
  */
16
- function createMoonshotProvider(provider: string, host: string, currency: string): CreditsProvider {
16
+ function createMoonshotProvider(id: string, host: string, currency: string): CreditsProvider {
17
17
  return {
18
- provider,
18
+ id,
19
19
  label: "Moonshot",
20
20
 
21
21
  async fetch(_ctx, apiKey, signal): Promise<Credits> {
@@ -33,7 +33,7 @@ function parseUsedPercent(window?: CodexRateWindow | null): number | undefined {
33
33
  }
34
34
 
35
35
  export const openaiCodexProvider: CreditsProvider = {
36
- provider: PROVIDER,
36
+ id: PROVIDER,
37
37
  label: "Codex",
38
38
 
39
39
  async fetch(ctx, apiKey, signal): Promise<Credits> {
@@ -13,7 +13,7 @@ interface OpenRouterCreditsResponse {
13
13
  }
14
14
 
15
15
  export const openrouterProvider: CreditsProvider = {
16
- provider: PROVIDER,
16
+ id: PROVIDER,
17
17
  label: "OpenRouter",
18
18
 
19
19
  async fetch(_ctx, apiKey, signal): Promise<Credits> {
@@ -10,7 +10,7 @@ interface VercelCreditsResponse {
10
10
  }
11
11
 
12
12
  export const vercelAiGatewayProvider: CreditsProvider = {
13
- provider: PROVIDER,
13
+ id: PROVIDER,
14
14
  label: "Vercel",
15
15
 
16
16
  async fetch(_ctx, apiKey, signal): Promise<Credits> {
package/src/types.ts CHANGED
@@ -18,7 +18,7 @@ export interface CreditsLane {
18
18
 
19
19
  /** A credits source for a pi provider, shown in the status line while that provider is active. */
20
20
  export interface CreditsProvider {
21
- readonly provider: Provider;
21
+ readonly id: Provider;
22
22
  readonly label: string;
23
23
  fetch(ctx: ExtensionContext, apiKey: string, signal: AbortSignal): Promise<Credits>;
24
24
  }