@leo000001/opencode-quota-sidebar 2.0.8 → 2.0.9

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/dist/cost.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { AssistantMessage } from '@opencode-ai/sdk';
2
2
  import type { CacheCoverageMode } from './types.js';
3
- export declare const SUBSCRIPTION_API_COST_PROVIDERS: Set<string>;
3
+ export declare const API_COST_ENABLED_PROVIDERS: Set<string>;
4
4
  export declare function canonicalApiCostProviderID(providerID: string): string;
5
5
  export type ModelCostRates = {
6
6
  input: number;
@@ -15,6 +15,7 @@ export type ModelCostRates = {
15
15
  };
16
16
  };
17
17
  export declare function modelCostKey(providerID: string, modelID: string): string;
18
+ export declare function modelCostLookupKeys(providerID: string, modelID: string): string[];
18
19
  export declare function parseModelCostRates(value: unknown): ModelCostRates | undefined;
19
20
  export declare function guessModelCostDivisor(rates: ModelCostRates): 1 | 1000000;
20
21
  export declare function cacheCoverageModeFromRates(rates: ModelCostRates | undefined): CacheCoverageMode;
package/dist/cost.js CHANGED
@@ -1,5 +1,13 @@
1
1
  import { asNumber, isRecord } from './helpers.js';
2
- export const SUBSCRIPTION_API_COST_PROVIDERS = new Set(['openai', 'anthropic']);
2
+ export const API_COST_ENABLED_PROVIDERS = new Set([
3
+ 'openai',
4
+ 'anthropic',
5
+ 'kimi-for-coding',
6
+ ]);
7
+ const MODEL_COST_RATE_ALIASES = {
8
+ 'kimi-for-coding:k2p5': ['moonshotai-cn:kimi-k2.5'],
9
+ 'kimi-for-coding:kimi-k2-thinking': ['moonshotai-cn:kimi-k2-thinking'],
10
+ };
3
11
  function normalizeKnownProviderID(providerID) {
4
12
  if (providerID.startsWith('github-copilot'))
5
13
  return 'github-copilot';
@@ -7,7 +15,7 @@ function normalizeKnownProviderID(providerID) {
7
15
  }
8
16
  export function canonicalApiCostProviderID(providerID) {
9
17
  const normalized = normalizeKnownProviderID(providerID);
10
- if (SUBSCRIPTION_API_COST_PROVIDERS.has(normalized))
18
+ if (API_COST_ENABLED_PROVIDERS.has(normalized))
11
19
  return normalized;
12
20
  const lowered = providerID.toLowerCase();
13
21
  if (lowered.includes('copilot'))
@@ -22,6 +30,24 @@ export function canonicalApiCostProviderID(providerID) {
22
30
  export function modelCostKey(providerID, modelID) {
23
31
  return `${providerID}:${modelID}`;
24
32
  }
33
+ export function modelCostLookupKeys(providerID, modelID) {
34
+ const keys = [];
35
+ const canonicalProviderID = canonicalApiCostProviderID(providerID);
36
+ const push = (key) => {
37
+ if (!keys.includes(key))
38
+ keys.push(key);
39
+ };
40
+ push(modelCostKey(providerID, modelID));
41
+ if (canonicalProviderID !== providerID) {
42
+ push(modelCostKey(canonicalProviderID, modelID));
43
+ }
44
+ for (const key of [...keys]) {
45
+ for (const alias of MODEL_COST_RATE_ALIASES[key] || []) {
46
+ push(alias);
47
+ }
48
+ }
49
+ return keys;
50
+ }
25
51
  export function parseModelCostRates(value) {
26
52
  if (!isRecord(value))
27
53
  return undefined;
package/dist/usage.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { CacheCoverageMetrics, CacheCoverageMode, CacheUsageBuckets, Cached
6
6
  * fields). This is distinct from the plugin *state* version managed by the
7
7
  * persistence layer; billing version only governs usage-cache staleness.
8
8
  */
9
- export declare const USAGE_BILLING_CACHE_VERSION = 4;
9
+ export declare const USAGE_BILLING_CACHE_VERSION = 5;
10
10
  export type ProviderUsage = {
11
11
  providerID: string;
12
12
  input: number;
package/dist/usage.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * fields). This is distinct from the plugin *state* version managed by the
5
5
  * persistence layer; billing version only governs usage-cache staleness.
6
6
  */
7
- export const USAGE_BILLING_CACHE_VERSION = 4;
7
+ export const USAGE_BILLING_CACHE_VERSION = 5;
8
8
  function emptyCacheUsageBucket() {
9
9
  return {
10
10
  input: 0,
@@ -1,5 +1,5 @@
1
1
  import { TtlValueCache } from './cache.js';
2
- import { cacheCoverageModeFromRates, calcEquivalentApiCostForMessage, canonicalApiCostProviderID, modelCostKey, parseModelCostRates, SUBSCRIPTION_API_COST_PROVIDERS, } from './cost.js';
2
+ import { API_COST_ENABLED_PROVIDERS, cacheCoverageModeFromRates, calcEquivalentApiCostForMessage, canonicalApiCostProviderID, modelCostLookupKeys, modelCostKey, parseModelCostRates, } from './cost.js';
3
3
  import { deleteSessionFromDayChunk, dateKeyFromTimestamp, scanAllSessions, updateSessionsInDayChunks, } from './storage.js';
4
4
  import { periodStart } from './period.js';
5
5
  import { debug, debugError, isRecord, mapConcurrent, swallow, } from './helpers.js';
@@ -87,10 +87,11 @@ export function createUsageService(deps) {
87
87
  };
88
88
  const calcEquivalentApiCost = (message, modelCostMap) => {
89
89
  const providerID = canonicalApiCostProviderID(message.providerID);
90
- if (!SUBSCRIPTION_API_COST_PROVIDERS.has(providerID))
90
+ if (!API_COST_ENABLED_PROVIDERS.has(providerID))
91
91
  return 0;
92
- const rates = modelCostMap[modelCostKey(message.providerID, message.modelID)] ||
93
- modelCostMap[modelCostKey(providerID, message.modelID)];
92
+ const rates = modelCostLookupKeys(message.providerID, message.modelID)
93
+ .map((key) => modelCostMap[key])
94
+ .find(Boolean);
94
95
  if (!rates) {
95
96
  const key = modelCostKey(providerID, message.modelID);
96
97
  if (!missingApiCostRateKeys.has(key)) {
@@ -103,8 +104,9 @@ export function createUsageService(deps) {
103
104
  };
104
105
  const classifyCacheMode = (message, modelCostMap) => {
105
106
  const canonicalProviderID = canonicalApiCostProviderID(message.providerID);
106
- const baseRates = modelCostMap[modelCostKey(message.providerID, message.modelID)] ||
107
- modelCostMap[modelCostKey(canonicalProviderID, message.modelID)];
107
+ const baseRates = modelCostLookupKeys(message.providerID, message.modelID)
108
+ .map((key) => modelCostMap[key])
109
+ .find(Boolean);
108
110
  const effectiveRates = baseRates &&
109
111
  message.tokens.input + message.tokens.cache.read > 200_000 &&
110
112
  baseRates.contextOver200k
@@ -309,21 +311,6 @@ export function createUsageService(deps) {
309
311
  return false;
310
312
  return cached.billingVersion === USAGE_BILLING_CACHE_VERSION;
311
313
  };
312
- const hasStaleZeroApiCost = (cached, modelCostMap) => {
313
- if (!cached)
314
- return false;
315
- if (cached.apiCost > 0)
316
- return false;
317
- return Object.entries(cached.providers).some(([providerID, provider]) => {
318
- if (provider.apiCost > 0)
319
- return false;
320
- const canonicalProviderID = canonicalApiCostProviderID(providerID);
321
- if (!SUBSCRIPTION_API_COST_PROVIDERS.has(canonicalProviderID))
322
- return false;
323
- return Object.keys(modelCostMap).some((key) => key.startsWith(`${providerID}:`) ||
324
- key.startsWith(`${canonicalProviderID}:`));
325
- });
326
- };
327
314
  const summarizeSessionUsage = async (sessionID, generationAtStart, options) => {
328
315
  const load = await loadSessionEntries(sessionID);
329
316
  const entries = load.status === 'ok' ? load.entries : undefined;
@@ -345,9 +332,7 @@ export function createUsageService(deps) {
345
332
  return { usage: empty, persist: false };
346
333
  }
347
334
  const modelCostMap = await getModelCostMap();
348
- const staleBillingCache = Boolean(sessionState?.usage) &&
349
- (!isUsageBillingCurrent(sessionState?.usage) ||
350
- hasStaleZeroApiCost(sessionState?.usage, modelCostMap));
335
+ const staleBillingCache = Boolean(sessionState?.usage) && !isUsageBillingCurrent(sessionState?.usage);
351
336
  const forceRescan = forceRescanSessions.has(sessionID) || staleBillingCache;
352
337
  if (forceRescan)
353
338
  forceRescanSessions.delete(sessionID);
@@ -470,7 +455,7 @@ export function createUsageService(deps) {
470
455
  return true;
471
456
  return providerIDs.some((providerID) => {
472
457
  const canonical = canonicalApiCostProviderID(providerID);
473
- return SUBSCRIPTION_API_COST_PROVIDERS.has(canonical);
458
+ return API_COST_ENABLED_PROVIDERS.has(canonical);
474
459
  });
475
460
  };
476
461
  const shouldRecomputeUsageCache = (cached) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leo000001/opencode-quota-sidebar",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "OpenCode plugin that shows quota and token usage in session titles",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",