@omnicross/daemon 0.3.1 → 0.4.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/dist/cli.cjs +1504 -269
- package/dist/cli.js +1475 -228
- package/dist/index.cjs +1400 -263
- package/dist/index.d.cts +215 -8
- package/dist/index.d.ts +215 -8
- package/dist/index.js +1373 -226
- package/package.json +6 -6
package/dist/index.d.cts
CHANGED
|
@@ -6,7 +6,7 @@ import { RouteLeaseManager, ProviderProxy } from '@omnicross/core/provider-proxy
|
|
|
6
6
|
import { UsageRecorder, PricingEngine } from '@omnicross/core/usage';
|
|
7
7
|
import { SubscriptionCredentialStore, FetchLike, CodexImageCapabilityEvidenceSource, CodexImageCapabilityEvidenceRequest, CodexImageCapabilityEvidence, CodexImageCapabilityObservation, ImageExecutionScheduler, ImageExecutionAccountKey, ImageExecutionSchedulerRequest, ImageExecutionSchedulerGrant, SubscriptionAccountService, SubscriptionProviderRegistry } from '@omnicross/subscriptions';
|
|
8
8
|
import { AccountAllowanceSnapshot, AllowanceWindow } from '@omnicross/contracts/account-allowance-types';
|
|
9
|
-
import { ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, KimiTokenConfig, AccountTokensConfig, ProxyConfig, SubscriptionAccountSanitized, AccountClientIdentity, SubscriptionAccountEntry } from '@omnicross/contracts/account-tokens-types';
|
|
9
|
+
import { ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, KimiTokenConfig, GrokTokenConfig, CopilotTokenConfig, AccountTokensConfig, ProxyConfig, SubscriptionAccountSanitized, AccountClientIdentity, SubscriptionAccountEntry } from '@omnicross/contracts/account-tokens-types';
|
|
10
10
|
import * as _omnicross_contracts_subscription_types from '@omnicross/contracts/subscription-types';
|
|
11
11
|
import { OpenCodeGoTokenConfig, SubscriptionProviderId } from '@omnicross/contracts/subscription-types';
|
|
12
12
|
import { AccountAllowanceStore } from '@omnicross/core/pipeline/AccountAllowanceStore';
|
|
@@ -536,6 +536,18 @@ interface DaemonProviderConfig {
|
|
|
536
536
|
* round-trips verbatim on GET. Management-UI only.
|
|
537
537
|
*/
|
|
538
538
|
modelsEndpoint?: string;
|
|
539
|
+
/**
|
|
540
|
+
* OPTIONAL static extra request headers merged into every BYO request for
|
|
541
|
+
* this row — identity/attribution contracts some gateways hard-gate on
|
|
542
|
+
* (e.g. the Cline client-identity set). Additive + back-compat: absent
|
|
543
|
+
* reads as undefined. NON-SECRET — round-trips verbatim on GET; values may
|
|
544
|
+
* carry `{{platform}}` (resolved to `process.platform` at request time).
|
|
545
|
+
* ENFORCED: the outbound header funnel (`getProviderHeaders`) +
|
|
546
|
+
* discover-models + test-model merge them; auth/content header NAMES are
|
|
547
|
+
* dropped by the load guard (`validateExtraHeaders`) so credentials stay
|
|
548
|
+
* key-field-only.
|
|
549
|
+
*/
|
|
550
|
+
extraHeaders?: Record<string, string>;
|
|
539
551
|
/**
|
|
540
552
|
* OPTIONAL provider transformer config (app-parity child 5). Additive +
|
|
541
553
|
* back-compat: absent reads as the prior default (undefined). NON-SECRET —
|
|
@@ -666,7 +678,7 @@ type AtomicFileReplace = (targetPath: string, contents: string) => void;
|
|
|
666
678
|
*/
|
|
667
679
|
|
|
668
680
|
/** Provider id → owned contract field names. */
|
|
669
|
-
type DaemonProvider = 'claude' | 'codex' | 'gemini' | 'opencodego' | 'kimi';
|
|
681
|
+
type DaemonProvider = 'claude' | 'codex' | 'gemini' | 'opencodego' | 'kimi' | 'grok' | 'copilot';
|
|
670
682
|
interface AccountMetadataPatch {
|
|
671
683
|
label?: string;
|
|
672
684
|
enabled?: boolean;
|
|
@@ -795,7 +807,7 @@ type ExternalCliReader = (provider: ExternalCliProvider) => ExternalCliCredentia
|
|
|
795
807
|
* shapes), keyed by `SubscriptionProviderId` the daemon admin layer validates
|
|
796
808
|
* the wire body to one of these before calling the writer.
|
|
797
809
|
*/
|
|
798
|
-
type SubscriptionTokenBlock = ClaudeTokenConfig | CodexTokenConfig | GeminiTokenConfig | OpenCodeGoTokenConfig | KimiTokenConfig;
|
|
810
|
+
type SubscriptionTokenBlock = ClaudeTokenConfig | CodexTokenConfig | GeminiTokenConfig | OpenCodeGoTokenConfig | KimiTokenConfig | GrokTokenConfig | CopilotTokenConfig;
|
|
799
811
|
declare class JsonSubscriptionCredentialStore implements SubscriptionCredentialStore {
|
|
800
812
|
private readonly tokensPath;
|
|
801
813
|
private readonly box;
|
|
@@ -907,13 +919,28 @@ declare class JsonSubscriptionCredentialStore implements SubscriptionCredentialS
|
|
|
907
919
|
* `false` when no refresh_token.
|
|
908
920
|
*/
|
|
909
921
|
refreshKimiToken(): Promise<boolean>;
|
|
922
|
+
/**
|
|
923
|
+
* Refresh the Grok (xAI SuperGrok) OAuth access token. The token endpoint is
|
|
924
|
+
* resolved through OIDC discovery on every refresh (process-cached 1h by the
|
|
925
|
+
* flow module) so a rotated endpoint document is picked up without a daemon
|
|
926
|
+
* restart. HONEST `false` when no refresh_token.
|
|
927
|
+
*/
|
|
928
|
+
refreshGrokToken(): Promise<boolean>;
|
|
929
|
+
/**
|
|
930
|
+
* "Refresh" a GitHub Copilot token — there is nothing to refresh (ghu_
|
|
931
|
+
* tokens are long-lived with no exchange endpoint). A call here means the
|
|
932
|
+
* strategy saw a 401 (the token was revoked); mark the account `expired`
|
|
933
|
+
* with a re-authenticate message and return `false` (the proxy then declines
|
|
934
|
+
* the retry instead of looping on a dead token).
|
|
935
|
+
*/
|
|
936
|
+
refreshCopilotToken(): Promise<boolean>;
|
|
910
937
|
/**
|
|
911
938
|
* Refresh a SPECIFIC managed account by id (background scheduler sweep and
|
|
912
939
|
* account-pool resolution). It uses only that account's stored refresh
|
|
913
940
|
* token. Coalesced per `provider:id`; on failure flags ONLY that account
|
|
914
941
|
* `expired`.
|
|
915
942
|
*/
|
|
916
|
-
refreshAccountById(provider: 'claude' | 'codex' | 'gemini' | 'kimi', id: string): Promise<boolean>;
|
|
943
|
+
refreshAccountById(provider: 'claude' | 'codex' | 'gemini' | 'kimi' | 'grok' | 'copilot', id: string): Promise<boolean>;
|
|
917
944
|
/**
|
|
918
945
|
* Resolve a SPECIFIC account's access token by id (design D6). Mirrors each
|
|
919
946
|
* provider's ACTIVE-getter policy, keyed by id: claude returns the stored token
|
|
@@ -1510,6 +1537,155 @@ declare class KimiAllowanceCollector {
|
|
|
1510
1537
|
private unsupportedSnapshot;
|
|
1511
1538
|
}
|
|
1512
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* Grok (xAI SuperGrok) OAuth usage collector.
|
|
1542
|
+
*
|
|
1543
|
+
* Polls the Grok CLI billing proxy (`cli-chat-proxy.grok.com/v1/billing` —
|
|
1544
|
+
* NOT `*.x.ai`, and it REJECTS paid API keys: OAuth bearer only) per grok
|
|
1545
|
+
* account, mirroring the Claude/Codex/Kimi collectors' cache contract:
|
|
1546
|
+
* 5-minute cache, per-account in-flight merging, one 401→refresh→retry.
|
|
1547
|
+
*
|
|
1548
|
+
* Dual shape (mirrors the audit source's semantics):
|
|
1549
|
+
* - WEEKLY credits (`?format=credits`): `config.creditUsagePercent` +
|
|
1550
|
+
* `config.currentPeriod{start,end,type}` (+ per-product rows and an
|
|
1551
|
+
* on-demand cap, both optional). A missing `creditUsagePercent` on an
|
|
1552
|
+
* ACTIVE weekly period reads as 0 (a fresh period has no usage row).
|
|
1553
|
+
* - UNIFIED monthly (default URL): `config.{billingPeriodStart,
|
|
1554
|
+
* billingPeriodEnd, monthlyLimit{val}, used{val}}` — accounts flagged
|
|
1555
|
+
* `isUnifiedBillingUser` omit the weekly percentage and meter a monthly
|
|
1556
|
+
* included quota instead.
|
|
1557
|
+
*
|
|
1558
|
+
* Probe policy: always probe weekly first; probe monthly when weekly is
|
|
1559
|
+
* missing OR the account is flagged unified. An INFERRED weekly percentage
|
|
1560
|
+
* (field absent) on a unified account is only kept when the monthly probe
|
|
1561
|
+
* positively confirms there is no monthly quota — otherwise the monthly
|
|
1562
|
+
* window wins (an inferred 0% weekly on a unified account is a lie), and a
|
|
1563
|
+
* failed monthly probe falls through to a failure snapshot so the store
|
|
1564
|
+
* retains the last good one.
|
|
1565
|
+
*
|
|
1566
|
+
* Every request carries `X-XAI-Token-Auth: xai-grok-cli` — the same product
|
|
1567
|
+
* gate the official CLI uses on this host.
|
|
1568
|
+
*/
|
|
1569
|
+
|
|
1570
|
+
interface GrokAllowanceCredentialReader {
|
|
1571
|
+
getAccessTokenForAccount(providerId: 'grok', accountId: string): Promise<string | null>;
|
|
1572
|
+
refreshAccountToken(providerId: 'grok', accountId: string): Promise<boolean>;
|
|
1573
|
+
}
|
|
1574
|
+
type GrokAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1575
|
+
interface GrokAllowanceCollectOptions {
|
|
1576
|
+
force?: boolean;
|
|
1577
|
+
refreshAheadMs?: number;
|
|
1578
|
+
}
|
|
1579
|
+
declare class GrokAllowanceCollector {
|
|
1580
|
+
private readonly credentials;
|
|
1581
|
+
private readonly store;
|
|
1582
|
+
private readonly fetchImpl;
|
|
1583
|
+
private readonly now;
|
|
1584
|
+
private readonly inFlight;
|
|
1585
|
+
constructor(credentials: GrokAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: GrokAllowanceFetch, now?: () => number);
|
|
1586
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<GrokTokenConfig>[], options?: GrokAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1587
|
+
collect(account: SubscriptionAccountEntry<GrokTokenConfig>, options?: GrokAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1588
|
+
private isCacheValid;
|
|
1589
|
+
private fetchAccount;
|
|
1590
|
+
private failureSnapshot;
|
|
1591
|
+
private unsupportedSnapshot;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* CopilotAllowanceCollector — GitHub Copilot quota via the internal user API.
|
|
1596
|
+
*
|
|
1597
|
+
* Polls `GET api.github.com/copilot_internal/user` per copilot account
|
|
1598
|
+
* (Bearer ghu_ + the mirrored Copilot CLI user-agent), reading
|
|
1599
|
+
* `quota_snapshots`:
|
|
1600
|
+
* - `premium_interactions` — the plan's premium-request monthly window
|
|
1601
|
+
* (`{entitlement, remaining, percent_remaining, unlimited}` + the
|
|
1602
|
+
* account-level `quota_reset_date`). Reported as a single `thirty-day`
|
|
1603
|
+
* window; an `unlimited` entitlement reports 0% (never blocks).
|
|
1604
|
+
* - `chat` — the legacy chat-completions quota, reported only when it is
|
|
1605
|
+
* NOT unlimited (newer plans fold it into premium).
|
|
1606
|
+
*
|
|
1607
|
+
* Mirrors the Claude/Codex/Kimi/Grok collectors' cache contract: 5-minute
|
|
1608
|
+
* cache, per-account in-flight merging, one 401→refresh→retry (for copilot a
|
|
1609
|
+
* "refresh" marks the account expired — ghu_ tokens cannot be refreshed — so
|
|
1610
|
+
* the retry path is exercised only by transient upstream 401 flaps and never
|
|
1611
|
+
* loops). The GitHub API base honors the account's `enterpriseUrl` (GHE).
|
|
1612
|
+
*/
|
|
1613
|
+
|
|
1614
|
+
interface CopilotAllowanceCredentialReader {
|
|
1615
|
+
getAccessTokenForAccount(providerId: 'copilot', accountId: string): Promise<string | null>;
|
|
1616
|
+
refreshAccountToken(providerId: 'copilot', accountId: string): Promise<boolean>;
|
|
1617
|
+
}
|
|
1618
|
+
type CopilotAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1619
|
+
interface CopilotAllowanceCollectOptions {
|
|
1620
|
+
force?: boolean;
|
|
1621
|
+
refreshAheadMs?: number;
|
|
1622
|
+
}
|
|
1623
|
+
declare class CopilotAllowanceCollector {
|
|
1624
|
+
private readonly credentials;
|
|
1625
|
+
private readonly store;
|
|
1626
|
+
private readonly fetchImpl;
|
|
1627
|
+
private readonly now;
|
|
1628
|
+
private readonly inFlight;
|
|
1629
|
+
constructor(credentials: CopilotAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: CopilotAllowanceFetch, now?: () => number);
|
|
1630
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<CopilotTokenConfig>[], options?: CopilotAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1631
|
+
collect(account: SubscriptionAccountEntry<CopilotTokenConfig>, options?: CopilotAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1632
|
+
private isCacheValid;
|
|
1633
|
+
private fetchAccount;
|
|
1634
|
+
private request;
|
|
1635
|
+
private failureSnapshot;
|
|
1636
|
+
private unsupportedSnapshot;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* GeminiAllowanceCollector — gemini subscription quota via the Cloud Code
|
|
1641
|
+
* Assist internal user-quota RPC.
|
|
1642
|
+
*
|
|
1643
|
+
* Probes `POST ${cloudcode-pa}/v1internal:retrieveUserQuota` per gemini
|
|
1644
|
+
* account (Bearer access token + the GeminiCLI masquerade pair the inference
|
|
1645
|
+
* path also carries), parsing `buckets[]` into one per-model window:
|
|
1646
|
+
* `remainingFraction` (0–1) → used percent, `resetTime` → resetsAt. The
|
|
1647
|
+
* Code Assist project id comes from the SHARED `GeminiCodeAssistProjectResolver`
|
|
1648
|
+
* (the same instance the dispatch seam uses, so the handshake runs at most
|
|
1649
|
+
* once per token across inference + quota); a handshake hard failure degrades
|
|
1650
|
+
* to a project-less probe (the valid free-tier envelope), mirroring the
|
|
1651
|
+
* reference implementation's tolerant behavior.
|
|
1652
|
+
*
|
|
1653
|
+
* Mirrors the sibling collectors' cache contract: 5-minute cache, per-account
|
|
1654
|
+
* in-flight merging, one 401/403→refresh→retry. Display-only — the scheduling
|
|
1655
|
+
* whitelist deliberately excludes gemini (per-model fraction buckets do not
|
|
1656
|
+
* fit the worst-window pause/demote rule).
|
|
1657
|
+
*
|
|
1658
|
+
* @module @omnicross/daemon/allowance/GeminiAllowanceCollector
|
|
1659
|
+
*/
|
|
1660
|
+
|
|
1661
|
+
interface GeminiAllowanceCredentialReader {
|
|
1662
|
+
getAccessTokenForAccount(providerId: 'gemini', accountId: string): Promise<string | null>;
|
|
1663
|
+
refreshAccountToken(providerId: 'gemini', accountId: string): Promise<boolean>;
|
|
1664
|
+
}
|
|
1665
|
+
type GeminiAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1666
|
+
interface GeminiAllowanceCollectOptions {
|
|
1667
|
+
force?: boolean;
|
|
1668
|
+
refreshAheadMs?: number;
|
|
1669
|
+
}
|
|
1670
|
+
declare class GeminiAllowanceCollector {
|
|
1671
|
+
private readonly credentials;
|
|
1672
|
+
private readonly store;
|
|
1673
|
+
private readonly fetchImpl;
|
|
1674
|
+
private readonly now;
|
|
1675
|
+
private readonly projectResolver;
|
|
1676
|
+
private readonly inFlight;
|
|
1677
|
+
constructor(credentials: GeminiAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: GeminiAllowanceFetch, now?: () => number, projectResolver?: {
|
|
1678
|
+
resolveProject(accessToken: string): Promise<string | undefined>;
|
|
1679
|
+
});
|
|
1680
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<GeminiTokenConfig>[], options?: GeminiAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1681
|
+
collect(account: SubscriptionAccountEntry<GeminiTokenConfig>, options?: GeminiAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1682
|
+
private isCacheValid;
|
|
1683
|
+
private fetchAccount;
|
|
1684
|
+
private request;
|
|
1685
|
+
private failureSnapshot;
|
|
1686
|
+
private unsupportedSnapshot;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1513
1689
|
/**
|
|
1514
1690
|
* OpenCodeGo usage collector.
|
|
1515
1691
|
*
|
|
@@ -1557,8 +1733,8 @@ declare class OpenCodeGoAllowanceCollector {
|
|
|
1557
1733
|
* literals — extending them all would make the overloads conflict.
|
|
1558
1734
|
*/
|
|
1559
1735
|
interface AccountAllowanceCredentialReader {
|
|
1560
|
-
getAccessTokenForAccount(providerId: 'claude' | 'codex' | 'kimi' | 'opencodego', accountId: string): Promise<string | null>;
|
|
1561
|
-
refreshAccountToken(providerId: 'claude' | 'codex' | 'kimi', accountId: string): Promise<boolean>;
|
|
1736
|
+
getAccessTokenForAccount(providerId: 'claude' | 'codex' | 'kimi' | 'opencodego' | 'grok' | 'copilot' | 'gemini', accountId: string): Promise<string | null>;
|
|
1737
|
+
refreshAccountToken(providerId: 'claude' | 'codex' | 'kimi' | 'grok' | 'copilot' | 'gemini', accountId: string): Promise<boolean>;
|
|
1562
1738
|
getFullConfig(): Promise<AccountTokensConfig>;
|
|
1563
1739
|
}
|
|
1564
1740
|
interface AccountAllowanceFilter {
|
|
@@ -1576,8 +1752,11 @@ declare class AccountAllowanceService {
|
|
|
1576
1752
|
readonly claudeCollector: ClaudeAllowanceCollector;
|
|
1577
1753
|
readonly codexCollector: CodexAllowanceCollector;
|
|
1578
1754
|
readonly kimiCollector: KimiAllowanceCollector;
|
|
1755
|
+
readonly grokCollector: GrokAllowanceCollector;
|
|
1756
|
+
readonly copilotCollector: CopilotAllowanceCollector;
|
|
1579
1757
|
readonly opencodegoCollector: OpenCodeGoAllowanceCollector;
|
|
1580
|
-
|
|
1758
|
+
readonly geminiCollector: GeminiAllowanceCollector;
|
|
1759
|
+
constructor(credentials: AccountAllowanceCredentialReader, store?: AccountAllowanceStore, collector?: ClaudeAllowanceCollector, codexCollector?: CodexAllowanceCollector, kimiCollector?: KimiAllowanceCollector, opencodegoCollector?: OpenCodeGoAllowanceCollector, grokCollector?: GrokAllowanceCollector, copilotCollector?: CopilotAllowanceCollector, geminiCollector?: GeminiAllowanceCollector, now?: () => number);
|
|
1581
1760
|
/**
|
|
1582
1761
|
* Read all/filtered snapshots. Claude's and Codex's five-minute caches are
|
|
1583
1762
|
* refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
|
|
@@ -1597,6 +1776,12 @@ declare class AccountAllowanceService {
|
|
|
1597
1776
|
refreshOpenCodeGo(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1598
1777
|
/** Force-refresh Kimi usage (`/coding/v1/usages`) for one/all accounts. */
|
|
1599
1778
|
refreshKimi(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1779
|
+
/** Force-refresh Copilot usage (copilot_internal/user) for one/all accounts. */
|
|
1780
|
+
refreshCopilot(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1781
|
+
/** Force-refresh Grok usage (CLI billing proxy) for one/all accounts. */
|
|
1782
|
+
refreshGrok(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1783
|
+
/** Force-refresh Gemini usage (Code Assist retrieveUserQuota) for one/all accounts. */
|
|
1784
|
+
refreshGemini(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1600
1785
|
/**
|
|
1601
1786
|
* Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
|
|
1602
1787
|
* collectors preserve their cache + per-account in-flight coalescing; a tick
|
|
@@ -1988,6 +2173,12 @@ type BillingStatusReader = () => BillingDeliveryStatus;
|
|
|
1988
2173
|
* .status_code === 0` is the real success gate. `model_remains[]` buckets
|
|
1989
2174
|
* each carry a rolling interval + weekly window as REMAINING percent
|
|
1990
2175
|
* (0-100); the `"general"` bucket is the plan-wide shared quota.
|
|
2176
|
+
* - Cline Pass:
|
|
2177
|
+
* GET {origin}/api/v1/users/me/plan/usage-limits
|
|
2178
|
+
* `Authorization: Bearer <key>` PLUS the Cline client-identity header set
|
|
2179
|
+
* (the row's `extraHeaders` — the gateway 403s without the full mirror).
|
|
2180
|
+
* `limits[]` rows carry `{type: five_hour|weekly|monthly, percentUsed,
|
|
2181
|
+
* resetsAt}` — pure percentage windows, no absolute meters.
|
|
1991
2182
|
*
|
|
1992
2183
|
* Everything here is pure; the fetch/cache lifecycle lives in
|
|
1993
2184
|
* `ProviderKeyQuotaService`. Windows reuse the subscription `AllowanceWindow`
|
|
@@ -1995,7 +2186,7 @@ type BillingStatusReader = () => BillingDeliveryStatus;
|
|
|
1995
2186
|
*/
|
|
1996
2187
|
|
|
1997
2188
|
/** Which quota adapter applies to a provider row (by resolved endpoint). */
|
|
1998
|
-
type ProviderKeyQuotaAdapter = 'zai' | 'minimax-token-plan' | 'umans' | 'synthetic';
|
|
2189
|
+
type ProviderKeyQuotaAdapter = 'zai' | 'minimax-token-plan' | 'umans' | 'synthetic' | 'cline-pass';
|
|
1999
2190
|
|
|
2000
2191
|
/**
|
|
2001
2192
|
* ProviderKeyQuotaService — read-through quota cache for BYO provider-row keys.
|
|
@@ -2797,6 +2988,12 @@ interface AccountAllowanceAdminReader {
|
|
|
2797
2988
|
refreshKimi?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2798
2989
|
/** Optional: OpenCodeGo `/v1/usage` refresh (absent on older daemons). */
|
|
2799
2990
|
refreshOpenCodeGo?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2991
|
+
/** Optional: Grok CLI-billing refresh (absent on older daemons). */
|
|
2992
|
+
refreshGrok?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2993
|
+
/** Optional: Copilot user-quota refresh (absent on older daemons). */
|
|
2994
|
+
refreshCopilot?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2995
|
+
/** Optional: Gemini Code-Assist quota refresh (absent on older daemons). */
|
|
2996
|
+
refreshGemini?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2800
2997
|
removeAccountSnapshot?(providerId: SubscriptionProviderId, accountId: string): void;
|
|
2801
2998
|
removeProviderSnapshots?(providerId: SubscriptionProviderId): void;
|
|
2802
2999
|
getSchedulingStatus?(): AccountAllowanceSchedulingStatus;
|
|
@@ -2946,6 +3143,16 @@ interface AdminApiDeps {
|
|
|
2946
3143
|
* shape as codex; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
2947
3144
|
*/
|
|
2948
3145
|
readonly kimiSessions: CodexOAuthSessionStore;
|
|
3146
|
+
/**
|
|
3147
|
+
* Grok interactive-OAuth flow store (device code). Same token-free polled
|
|
3148
|
+
* shape as codex; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
3149
|
+
*/
|
|
3150
|
+
readonly grokSessions: CodexOAuthSessionStore;
|
|
3151
|
+
/**
|
|
3152
|
+
* Copilot interactive-OAuth flow store (device code). Same token-free
|
|
3153
|
+
* polled shape; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
3154
|
+
*/
|
|
3155
|
+
readonly copilotSessions: CodexOAuthSessionStore;
|
|
2949
3156
|
/**
|
|
2950
3157
|
* Codex loopback listener (app-parity-2 child 5) — defaults to `awaitLoopbackCode`
|
|
2951
3158
|
* (binds 127.0.0.1:1455) in `bootstrap.ts`; tests inject a mock so no real port
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { RouteLeaseManager, ProviderProxy } from '@omnicross/core/provider-proxy
|
|
|
6
6
|
import { UsageRecorder, PricingEngine } from '@omnicross/core/usage';
|
|
7
7
|
import { SubscriptionCredentialStore, FetchLike, CodexImageCapabilityEvidenceSource, CodexImageCapabilityEvidenceRequest, CodexImageCapabilityEvidence, CodexImageCapabilityObservation, ImageExecutionScheduler, ImageExecutionAccountKey, ImageExecutionSchedulerRequest, ImageExecutionSchedulerGrant, SubscriptionAccountService, SubscriptionProviderRegistry } from '@omnicross/subscriptions';
|
|
8
8
|
import { AccountAllowanceSnapshot, AllowanceWindow } from '@omnicross/contracts/account-allowance-types';
|
|
9
|
-
import { ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, KimiTokenConfig, AccountTokensConfig, ProxyConfig, SubscriptionAccountSanitized, AccountClientIdentity, SubscriptionAccountEntry } from '@omnicross/contracts/account-tokens-types';
|
|
9
|
+
import { ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, KimiTokenConfig, GrokTokenConfig, CopilotTokenConfig, AccountTokensConfig, ProxyConfig, SubscriptionAccountSanitized, AccountClientIdentity, SubscriptionAccountEntry } from '@omnicross/contracts/account-tokens-types';
|
|
10
10
|
import * as _omnicross_contracts_subscription_types from '@omnicross/contracts/subscription-types';
|
|
11
11
|
import { OpenCodeGoTokenConfig, SubscriptionProviderId } from '@omnicross/contracts/subscription-types';
|
|
12
12
|
import { AccountAllowanceStore } from '@omnicross/core/pipeline/AccountAllowanceStore';
|
|
@@ -536,6 +536,18 @@ interface DaemonProviderConfig {
|
|
|
536
536
|
* round-trips verbatim on GET. Management-UI only.
|
|
537
537
|
*/
|
|
538
538
|
modelsEndpoint?: string;
|
|
539
|
+
/**
|
|
540
|
+
* OPTIONAL static extra request headers merged into every BYO request for
|
|
541
|
+
* this row — identity/attribution contracts some gateways hard-gate on
|
|
542
|
+
* (e.g. the Cline client-identity set). Additive + back-compat: absent
|
|
543
|
+
* reads as undefined. NON-SECRET — round-trips verbatim on GET; values may
|
|
544
|
+
* carry `{{platform}}` (resolved to `process.platform` at request time).
|
|
545
|
+
* ENFORCED: the outbound header funnel (`getProviderHeaders`) +
|
|
546
|
+
* discover-models + test-model merge them; auth/content header NAMES are
|
|
547
|
+
* dropped by the load guard (`validateExtraHeaders`) so credentials stay
|
|
548
|
+
* key-field-only.
|
|
549
|
+
*/
|
|
550
|
+
extraHeaders?: Record<string, string>;
|
|
539
551
|
/**
|
|
540
552
|
* OPTIONAL provider transformer config (app-parity child 5). Additive +
|
|
541
553
|
* back-compat: absent reads as the prior default (undefined). NON-SECRET —
|
|
@@ -666,7 +678,7 @@ type AtomicFileReplace = (targetPath: string, contents: string) => void;
|
|
|
666
678
|
*/
|
|
667
679
|
|
|
668
680
|
/** Provider id → owned contract field names. */
|
|
669
|
-
type DaemonProvider = 'claude' | 'codex' | 'gemini' | 'opencodego' | 'kimi';
|
|
681
|
+
type DaemonProvider = 'claude' | 'codex' | 'gemini' | 'opencodego' | 'kimi' | 'grok' | 'copilot';
|
|
670
682
|
interface AccountMetadataPatch {
|
|
671
683
|
label?: string;
|
|
672
684
|
enabled?: boolean;
|
|
@@ -795,7 +807,7 @@ type ExternalCliReader = (provider: ExternalCliProvider) => ExternalCliCredentia
|
|
|
795
807
|
* shapes), keyed by `SubscriptionProviderId` the daemon admin layer validates
|
|
796
808
|
* the wire body to one of these before calling the writer.
|
|
797
809
|
*/
|
|
798
|
-
type SubscriptionTokenBlock = ClaudeTokenConfig | CodexTokenConfig | GeminiTokenConfig | OpenCodeGoTokenConfig | KimiTokenConfig;
|
|
810
|
+
type SubscriptionTokenBlock = ClaudeTokenConfig | CodexTokenConfig | GeminiTokenConfig | OpenCodeGoTokenConfig | KimiTokenConfig | GrokTokenConfig | CopilotTokenConfig;
|
|
799
811
|
declare class JsonSubscriptionCredentialStore implements SubscriptionCredentialStore {
|
|
800
812
|
private readonly tokensPath;
|
|
801
813
|
private readonly box;
|
|
@@ -907,13 +919,28 @@ declare class JsonSubscriptionCredentialStore implements SubscriptionCredentialS
|
|
|
907
919
|
* `false` when no refresh_token.
|
|
908
920
|
*/
|
|
909
921
|
refreshKimiToken(): Promise<boolean>;
|
|
922
|
+
/**
|
|
923
|
+
* Refresh the Grok (xAI SuperGrok) OAuth access token. The token endpoint is
|
|
924
|
+
* resolved through OIDC discovery on every refresh (process-cached 1h by the
|
|
925
|
+
* flow module) so a rotated endpoint document is picked up without a daemon
|
|
926
|
+
* restart. HONEST `false` when no refresh_token.
|
|
927
|
+
*/
|
|
928
|
+
refreshGrokToken(): Promise<boolean>;
|
|
929
|
+
/**
|
|
930
|
+
* "Refresh" a GitHub Copilot token — there is nothing to refresh (ghu_
|
|
931
|
+
* tokens are long-lived with no exchange endpoint). A call here means the
|
|
932
|
+
* strategy saw a 401 (the token was revoked); mark the account `expired`
|
|
933
|
+
* with a re-authenticate message and return `false` (the proxy then declines
|
|
934
|
+
* the retry instead of looping on a dead token).
|
|
935
|
+
*/
|
|
936
|
+
refreshCopilotToken(): Promise<boolean>;
|
|
910
937
|
/**
|
|
911
938
|
* Refresh a SPECIFIC managed account by id (background scheduler sweep and
|
|
912
939
|
* account-pool resolution). It uses only that account's stored refresh
|
|
913
940
|
* token. Coalesced per `provider:id`; on failure flags ONLY that account
|
|
914
941
|
* `expired`.
|
|
915
942
|
*/
|
|
916
|
-
refreshAccountById(provider: 'claude' | 'codex' | 'gemini' | 'kimi', id: string): Promise<boolean>;
|
|
943
|
+
refreshAccountById(provider: 'claude' | 'codex' | 'gemini' | 'kimi' | 'grok' | 'copilot', id: string): Promise<boolean>;
|
|
917
944
|
/**
|
|
918
945
|
* Resolve a SPECIFIC account's access token by id (design D6). Mirrors each
|
|
919
946
|
* provider's ACTIVE-getter policy, keyed by id: claude returns the stored token
|
|
@@ -1510,6 +1537,155 @@ declare class KimiAllowanceCollector {
|
|
|
1510
1537
|
private unsupportedSnapshot;
|
|
1511
1538
|
}
|
|
1512
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* Grok (xAI SuperGrok) OAuth usage collector.
|
|
1542
|
+
*
|
|
1543
|
+
* Polls the Grok CLI billing proxy (`cli-chat-proxy.grok.com/v1/billing` —
|
|
1544
|
+
* NOT `*.x.ai`, and it REJECTS paid API keys: OAuth bearer only) per grok
|
|
1545
|
+
* account, mirroring the Claude/Codex/Kimi collectors' cache contract:
|
|
1546
|
+
* 5-minute cache, per-account in-flight merging, one 401→refresh→retry.
|
|
1547
|
+
*
|
|
1548
|
+
* Dual shape (mirrors the audit source's semantics):
|
|
1549
|
+
* - WEEKLY credits (`?format=credits`): `config.creditUsagePercent` +
|
|
1550
|
+
* `config.currentPeriod{start,end,type}` (+ per-product rows and an
|
|
1551
|
+
* on-demand cap, both optional). A missing `creditUsagePercent` on an
|
|
1552
|
+
* ACTIVE weekly period reads as 0 (a fresh period has no usage row).
|
|
1553
|
+
* - UNIFIED monthly (default URL): `config.{billingPeriodStart,
|
|
1554
|
+
* billingPeriodEnd, monthlyLimit{val}, used{val}}` — accounts flagged
|
|
1555
|
+
* `isUnifiedBillingUser` omit the weekly percentage and meter a monthly
|
|
1556
|
+
* included quota instead.
|
|
1557
|
+
*
|
|
1558
|
+
* Probe policy: always probe weekly first; probe monthly when weekly is
|
|
1559
|
+
* missing OR the account is flagged unified. An INFERRED weekly percentage
|
|
1560
|
+
* (field absent) on a unified account is only kept when the monthly probe
|
|
1561
|
+
* positively confirms there is no monthly quota — otherwise the monthly
|
|
1562
|
+
* window wins (an inferred 0% weekly on a unified account is a lie), and a
|
|
1563
|
+
* failed monthly probe falls through to a failure snapshot so the store
|
|
1564
|
+
* retains the last good one.
|
|
1565
|
+
*
|
|
1566
|
+
* Every request carries `X-XAI-Token-Auth: xai-grok-cli` — the same product
|
|
1567
|
+
* gate the official CLI uses on this host.
|
|
1568
|
+
*/
|
|
1569
|
+
|
|
1570
|
+
interface GrokAllowanceCredentialReader {
|
|
1571
|
+
getAccessTokenForAccount(providerId: 'grok', accountId: string): Promise<string | null>;
|
|
1572
|
+
refreshAccountToken(providerId: 'grok', accountId: string): Promise<boolean>;
|
|
1573
|
+
}
|
|
1574
|
+
type GrokAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1575
|
+
interface GrokAllowanceCollectOptions {
|
|
1576
|
+
force?: boolean;
|
|
1577
|
+
refreshAheadMs?: number;
|
|
1578
|
+
}
|
|
1579
|
+
declare class GrokAllowanceCollector {
|
|
1580
|
+
private readonly credentials;
|
|
1581
|
+
private readonly store;
|
|
1582
|
+
private readonly fetchImpl;
|
|
1583
|
+
private readonly now;
|
|
1584
|
+
private readonly inFlight;
|
|
1585
|
+
constructor(credentials: GrokAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: GrokAllowanceFetch, now?: () => number);
|
|
1586
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<GrokTokenConfig>[], options?: GrokAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1587
|
+
collect(account: SubscriptionAccountEntry<GrokTokenConfig>, options?: GrokAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1588
|
+
private isCacheValid;
|
|
1589
|
+
private fetchAccount;
|
|
1590
|
+
private failureSnapshot;
|
|
1591
|
+
private unsupportedSnapshot;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* CopilotAllowanceCollector — GitHub Copilot quota via the internal user API.
|
|
1596
|
+
*
|
|
1597
|
+
* Polls `GET api.github.com/copilot_internal/user` per copilot account
|
|
1598
|
+
* (Bearer ghu_ + the mirrored Copilot CLI user-agent), reading
|
|
1599
|
+
* `quota_snapshots`:
|
|
1600
|
+
* - `premium_interactions` — the plan's premium-request monthly window
|
|
1601
|
+
* (`{entitlement, remaining, percent_remaining, unlimited}` + the
|
|
1602
|
+
* account-level `quota_reset_date`). Reported as a single `thirty-day`
|
|
1603
|
+
* window; an `unlimited` entitlement reports 0% (never blocks).
|
|
1604
|
+
* - `chat` — the legacy chat-completions quota, reported only when it is
|
|
1605
|
+
* NOT unlimited (newer plans fold it into premium).
|
|
1606
|
+
*
|
|
1607
|
+
* Mirrors the Claude/Codex/Kimi/Grok collectors' cache contract: 5-minute
|
|
1608
|
+
* cache, per-account in-flight merging, one 401→refresh→retry (for copilot a
|
|
1609
|
+
* "refresh" marks the account expired — ghu_ tokens cannot be refreshed — so
|
|
1610
|
+
* the retry path is exercised only by transient upstream 401 flaps and never
|
|
1611
|
+
* loops). The GitHub API base honors the account's `enterpriseUrl` (GHE).
|
|
1612
|
+
*/
|
|
1613
|
+
|
|
1614
|
+
interface CopilotAllowanceCredentialReader {
|
|
1615
|
+
getAccessTokenForAccount(providerId: 'copilot', accountId: string): Promise<string | null>;
|
|
1616
|
+
refreshAccountToken(providerId: 'copilot', accountId: string): Promise<boolean>;
|
|
1617
|
+
}
|
|
1618
|
+
type CopilotAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1619
|
+
interface CopilotAllowanceCollectOptions {
|
|
1620
|
+
force?: boolean;
|
|
1621
|
+
refreshAheadMs?: number;
|
|
1622
|
+
}
|
|
1623
|
+
declare class CopilotAllowanceCollector {
|
|
1624
|
+
private readonly credentials;
|
|
1625
|
+
private readonly store;
|
|
1626
|
+
private readonly fetchImpl;
|
|
1627
|
+
private readonly now;
|
|
1628
|
+
private readonly inFlight;
|
|
1629
|
+
constructor(credentials: CopilotAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: CopilotAllowanceFetch, now?: () => number);
|
|
1630
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<CopilotTokenConfig>[], options?: CopilotAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1631
|
+
collect(account: SubscriptionAccountEntry<CopilotTokenConfig>, options?: CopilotAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1632
|
+
private isCacheValid;
|
|
1633
|
+
private fetchAccount;
|
|
1634
|
+
private request;
|
|
1635
|
+
private failureSnapshot;
|
|
1636
|
+
private unsupportedSnapshot;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* GeminiAllowanceCollector — gemini subscription quota via the Cloud Code
|
|
1641
|
+
* Assist internal user-quota RPC.
|
|
1642
|
+
*
|
|
1643
|
+
* Probes `POST ${cloudcode-pa}/v1internal:retrieveUserQuota` per gemini
|
|
1644
|
+
* account (Bearer access token + the GeminiCLI masquerade pair the inference
|
|
1645
|
+
* path also carries), parsing `buckets[]` into one per-model window:
|
|
1646
|
+
* `remainingFraction` (0–1) → used percent, `resetTime` → resetsAt. The
|
|
1647
|
+
* Code Assist project id comes from the SHARED `GeminiCodeAssistProjectResolver`
|
|
1648
|
+
* (the same instance the dispatch seam uses, so the handshake runs at most
|
|
1649
|
+
* once per token across inference + quota); a handshake hard failure degrades
|
|
1650
|
+
* to a project-less probe (the valid free-tier envelope), mirroring the
|
|
1651
|
+
* reference implementation's tolerant behavior.
|
|
1652
|
+
*
|
|
1653
|
+
* Mirrors the sibling collectors' cache contract: 5-minute cache, per-account
|
|
1654
|
+
* in-flight merging, one 401/403→refresh→retry. Display-only — the scheduling
|
|
1655
|
+
* whitelist deliberately excludes gemini (per-model fraction buckets do not
|
|
1656
|
+
* fit the worst-window pause/demote rule).
|
|
1657
|
+
*
|
|
1658
|
+
* @module @omnicross/daemon/allowance/GeminiAllowanceCollector
|
|
1659
|
+
*/
|
|
1660
|
+
|
|
1661
|
+
interface GeminiAllowanceCredentialReader {
|
|
1662
|
+
getAccessTokenForAccount(providerId: 'gemini', accountId: string): Promise<string | null>;
|
|
1663
|
+
refreshAccountToken(providerId: 'gemini', accountId: string): Promise<boolean>;
|
|
1664
|
+
}
|
|
1665
|
+
type GeminiAllowanceFetch = (url: string, init: RequestInit, accountId: string) => Promise<Response>;
|
|
1666
|
+
interface GeminiAllowanceCollectOptions {
|
|
1667
|
+
force?: boolean;
|
|
1668
|
+
refreshAheadMs?: number;
|
|
1669
|
+
}
|
|
1670
|
+
declare class GeminiAllowanceCollector {
|
|
1671
|
+
private readonly credentials;
|
|
1672
|
+
private readonly store;
|
|
1673
|
+
private readonly fetchImpl;
|
|
1674
|
+
private readonly now;
|
|
1675
|
+
private readonly projectResolver;
|
|
1676
|
+
private readonly inFlight;
|
|
1677
|
+
constructor(credentials: GeminiAllowanceCredentialReader, store?: AccountAllowanceStore, fetchImpl?: GeminiAllowanceFetch, now?: () => number, projectResolver?: {
|
|
1678
|
+
resolveProject(accessToken: string): Promise<string | undefined>;
|
|
1679
|
+
});
|
|
1680
|
+
collectMany(accounts: readonly SubscriptionAccountEntry<GeminiTokenConfig>[], options?: GeminiAllowanceCollectOptions): Promise<AccountAllowanceSnapshot[]>;
|
|
1681
|
+
collect(account: SubscriptionAccountEntry<GeminiTokenConfig>, options?: GeminiAllowanceCollectOptions): Promise<AccountAllowanceSnapshot>;
|
|
1682
|
+
private isCacheValid;
|
|
1683
|
+
private fetchAccount;
|
|
1684
|
+
private request;
|
|
1685
|
+
private failureSnapshot;
|
|
1686
|
+
private unsupportedSnapshot;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1513
1689
|
/**
|
|
1514
1690
|
* OpenCodeGo usage collector.
|
|
1515
1691
|
*
|
|
@@ -1557,8 +1733,8 @@ declare class OpenCodeGoAllowanceCollector {
|
|
|
1557
1733
|
* literals — extending them all would make the overloads conflict.
|
|
1558
1734
|
*/
|
|
1559
1735
|
interface AccountAllowanceCredentialReader {
|
|
1560
|
-
getAccessTokenForAccount(providerId: 'claude' | 'codex' | 'kimi' | 'opencodego', accountId: string): Promise<string | null>;
|
|
1561
|
-
refreshAccountToken(providerId: 'claude' | 'codex' | 'kimi', accountId: string): Promise<boolean>;
|
|
1736
|
+
getAccessTokenForAccount(providerId: 'claude' | 'codex' | 'kimi' | 'opencodego' | 'grok' | 'copilot' | 'gemini', accountId: string): Promise<string | null>;
|
|
1737
|
+
refreshAccountToken(providerId: 'claude' | 'codex' | 'kimi' | 'grok' | 'copilot' | 'gemini', accountId: string): Promise<boolean>;
|
|
1562
1738
|
getFullConfig(): Promise<AccountTokensConfig>;
|
|
1563
1739
|
}
|
|
1564
1740
|
interface AccountAllowanceFilter {
|
|
@@ -1576,8 +1752,11 @@ declare class AccountAllowanceService {
|
|
|
1576
1752
|
readonly claudeCollector: ClaudeAllowanceCollector;
|
|
1577
1753
|
readonly codexCollector: CodexAllowanceCollector;
|
|
1578
1754
|
readonly kimiCollector: KimiAllowanceCollector;
|
|
1755
|
+
readonly grokCollector: GrokAllowanceCollector;
|
|
1756
|
+
readonly copilotCollector: CopilotAllowanceCollector;
|
|
1579
1757
|
readonly opencodegoCollector: OpenCodeGoAllowanceCollector;
|
|
1580
|
-
|
|
1758
|
+
readonly geminiCollector: GeminiAllowanceCollector;
|
|
1759
|
+
constructor(credentials: AccountAllowanceCredentialReader, store?: AccountAllowanceStore, collector?: ClaudeAllowanceCollector, codexCollector?: CodexAllowanceCollector, kimiCollector?: KimiAllowanceCollector, opencodegoCollector?: OpenCodeGoAllowanceCollector, grokCollector?: GrokAllowanceCollector, copilotCollector?: CopilotAllowanceCollector, geminiCollector?: GeminiAllowanceCollector, now?: () => number);
|
|
1581
1760
|
/**
|
|
1582
1761
|
* Read all/filtered snapshots. Claude's and Codex's five-minute caches are
|
|
1583
1762
|
* refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
|
|
@@ -1597,6 +1776,12 @@ declare class AccountAllowanceService {
|
|
|
1597
1776
|
refreshOpenCodeGo(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1598
1777
|
/** Force-refresh Kimi usage (`/coding/v1/usages`) for one/all accounts. */
|
|
1599
1778
|
refreshKimi(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1779
|
+
/** Force-refresh Copilot usage (copilot_internal/user) for one/all accounts. */
|
|
1780
|
+
refreshCopilot(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1781
|
+
/** Force-refresh Grok usage (CLI billing proxy) for one/all accounts. */
|
|
1782
|
+
refreshGrok(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1783
|
+
/** Force-refresh Gemini usage (Code Assist retrieveUserQuota) for one/all accounts. */
|
|
1784
|
+
refreshGemini(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
1600
1785
|
/**
|
|
1601
1786
|
* Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
|
|
1602
1787
|
* collectors preserve their cache + per-account in-flight coalescing; a tick
|
|
@@ -1988,6 +2173,12 @@ type BillingStatusReader = () => BillingDeliveryStatus;
|
|
|
1988
2173
|
* .status_code === 0` is the real success gate. `model_remains[]` buckets
|
|
1989
2174
|
* each carry a rolling interval + weekly window as REMAINING percent
|
|
1990
2175
|
* (0-100); the `"general"` bucket is the plan-wide shared quota.
|
|
2176
|
+
* - Cline Pass:
|
|
2177
|
+
* GET {origin}/api/v1/users/me/plan/usage-limits
|
|
2178
|
+
* `Authorization: Bearer <key>` PLUS the Cline client-identity header set
|
|
2179
|
+
* (the row's `extraHeaders` — the gateway 403s without the full mirror).
|
|
2180
|
+
* `limits[]` rows carry `{type: five_hour|weekly|monthly, percentUsed,
|
|
2181
|
+
* resetsAt}` — pure percentage windows, no absolute meters.
|
|
1991
2182
|
*
|
|
1992
2183
|
* Everything here is pure; the fetch/cache lifecycle lives in
|
|
1993
2184
|
* `ProviderKeyQuotaService`. Windows reuse the subscription `AllowanceWindow`
|
|
@@ -1995,7 +2186,7 @@ type BillingStatusReader = () => BillingDeliveryStatus;
|
|
|
1995
2186
|
*/
|
|
1996
2187
|
|
|
1997
2188
|
/** Which quota adapter applies to a provider row (by resolved endpoint). */
|
|
1998
|
-
type ProviderKeyQuotaAdapter = 'zai' | 'minimax-token-plan' | 'umans' | 'synthetic';
|
|
2189
|
+
type ProviderKeyQuotaAdapter = 'zai' | 'minimax-token-plan' | 'umans' | 'synthetic' | 'cline-pass';
|
|
1999
2190
|
|
|
2000
2191
|
/**
|
|
2001
2192
|
* ProviderKeyQuotaService — read-through quota cache for BYO provider-row keys.
|
|
@@ -2797,6 +2988,12 @@ interface AccountAllowanceAdminReader {
|
|
|
2797
2988
|
refreshKimi?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2798
2989
|
/** Optional: OpenCodeGo `/v1/usage` refresh (absent on older daemons). */
|
|
2799
2990
|
refreshOpenCodeGo?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2991
|
+
/** Optional: Grok CLI-billing refresh (absent on older daemons). */
|
|
2992
|
+
refreshGrok?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2993
|
+
/** Optional: Copilot user-quota refresh (absent on older daemons). */
|
|
2994
|
+
refreshCopilot?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2995
|
+
/** Optional: Gemini Code-Assist quota refresh (absent on older daemons). */
|
|
2996
|
+
refreshGemini?(accountId?: string): Promise<AccountAllowanceSnapshot[]>;
|
|
2800
2997
|
removeAccountSnapshot?(providerId: SubscriptionProviderId, accountId: string): void;
|
|
2801
2998
|
removeProviderSnapshots?(providerId: SubscriptionProviderId): void;
|
|
2802
2999
|
getSchedulingStatus?(): AccountAllowanceSchedulingStatus;
|
|
@@ -2946,6 +3143,16 @@ interface AdminApiDeps {
|
|
|
2946
3143
|
* shape as codex; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
2947
3144
|
*/
|
|
2948
3145
|
readonly kimiSessions: CodexOAuthSessionStore;
|
|
3146
|
+
/**
|
|
3147
|
+
* Grok interactive-OAuth flow store (device code). Same token-free polled
|
|
3148
|
+
* shape as codex; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
3149
|
+
*/
|
|
3150
|
+
readonly grokSessions: CodexOAuthSessionStore;
|
|
3151
|
+
/**
|
|
3152
|
+
* Copilot interactive-OAuth flow store (device code). Same token-free
|
|
3153
|
+
* polled shape; one sign-in at a time. Wired in `bootstrap.ts`.
|
|
3154
|
+
*/
|
|
3155
|
+
readonly copilotSessions: CodexOAuthSessionStore;
|
|
2949
3156
|
/**
|
|
2950
3157
|
* Codex loopback listener (app-parity-2 child 5) — defaults to `awaitLoopbackCode`
|
|
2951
3158
|
* (binds 127.0.0.1:1455) in `bootstrap.ts`; tests inject a mock so no real port
|