@omnicross/daemon 0.4.0 → 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/index.js CHANGED
@@ -4,7 +4,7 @@ import { dirname as dirname17 } from "path";
4
4
  import { DEFAULT_AUDIT_CONFIG } from "@omnicross/contracts/audit-types";
5
5
  import { DEFAULT_BILLING_CONFIG } from "@omnicross/contracts/billing-types";
6
6
  import { OpenAIOperationRegistry } from "@omnicross/core";
7
- import { getGeminiCodeAssistProjectResolver } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
7
+ import { getGeminiCodeAssistProjectResolver as getGeminiCodeAssistProjectResolver2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
8
8
  import { ApiKeyPoolService } from "@omnicross/core/completion/ApiKeyPoolService";
9
9
  import {
10
10
  __resetOutboundApiServerForTests,
@@ -18,14 +18,14 @@ import { setSubscriptionRegistryForOutbound } from "@omnicross/core/outbound-api
18
18
  import { getSharedAccountHealth as getSharedAccountHealth4 } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
19
19
  import {
20
20
  __resetSharedAccountAllowanceStoreForTests,
21
- AccountAllowanceStore as AccountAllowanceStore8,
21
+ AccountAllowanceStore as AccountAllowanceStore9,
22
22
  setSharedAccountAllowanceStore
23
23
  } from "@omnicross/core/pipeline/AccountAllowanceStore";
24
24
  import {
25
25
  __resetSharedAccountAllowanceSchedulingForTests,
26
26
  getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling5
27
27
  } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
28
- import { fetchUpstream as fetchUpstream13, setUpstreamProxyResolver } from "@omnicross/core/pipeline/upstreamFetch";
28
+ import { fetchUpstream as fetchUpstream14, setUpstreamProxyResolver } from "@omnicross/core/pipeline/upstreamFetch";
29
29
  import { __resetSharedIdentityStoreForTests } from "@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore";
30
30
  import { setGeminiCodeAssistResolver } from "@omnicross/core/ports/gemini-code-assist-resolver";
31
31
  import {
@@ -411,7 +411,7 @@ function handleCopilotOAuthStatus(sessionId, deps) {
411
411
 
412
412
  // src/allowance/AccountAllowanceService.ts
413
413
  import {
414
- getSharedAccountAllowanceStore as getSharedAccountAllowanceStore7
414
+ getSharedAccountAllowanceStore as getSharedAccountAllowanceStore8
415
415
  } from "@omnicross/core/pipeline/AccountAllowanceStore";
416
416
  import {
417
417
  getSharedAccountAllowanceScheduling
@@ -1614,11 +1614,198 @@ var CopilotAllowanceCollector = class {
1614
1614
  }
1615
1615
  };
1616
1616
 
1617
- // src/allowance/OpenCodeGoAllowanceCollector.ts
1617
+ // src/allowance/GeminiAllowanceCollector.ts
1618
+ import { getGeminiCodeAssistProjectResolver } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
1618
1619
  import {
1619
1620
  getSharedAccountAllowanceStore as getSharedAccountAllowanceStore6
1620
1621
  } from "@omnicross/core/pipeline/AccountAllowanceStore";
1621
1622
  import { fetchUpstream as fetchUpstream6 } from "@omnicross/core/pipeline/upstreamFetch";
1623
+ import {
1624
+ getGeminiCliIdentityHeaders,
1625
+ resolveCodeAssistEndpoint
1626
+ } from "@omnicross/core/transformer/transformers";
1627
+ var GEMINI_ALLOWANCE_CACHE_MS = 5 * 6e4;
1628
+ function isRecord4(value) {
1629
+ return !!value && typeof value === "object" && !Array.isArray(value);
1630
+ }
1631
+ function secondsUntil6(instant, now) {
1632
+ if (!instant) return void 0;
1633
+ return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
1634
+ }
1635
+ function parseGeminiQuotaPayload(payload, now) {
1636
+ if (!isRecord4(payload)) return null;
1637
+ const buckets = Array.isArray(payload["buckets"]) ? payload["buckets"] : [];
1638
+ const windows = [];
1639
+ const seen = /* @__PURE__ */ new Set();
1640
+ for (const raw of buckets) {
1641
+ if (!isRecord4(raw)) continue;
1642
+ const modelId = typeof raw["modelId"] === "string" && raw["modelId"].trim() ? raw["modelId"].trim() : void 0;
1643
+ const id = `gemini:${modelId ?? "all"}`;
1644
+ if (seen.has(id)) continue;
1645
+ seen.add(id);
1646
+ const fractionRaw = typeof raw["remainingFraction"] === "number" ? raw["remainingFraction"] : Number(raw["remainingFraction"]);
1647
+ const usedPercent = Number.isFinite(fractionRaw) ? Math.round(Math.min(100, Math.max(0, (1 - Math.min(1, Math.max(0, fractionRaw))) * 100)) * 10) / 10 : null;
1648
+ const resetRaw = typeof raw["resetTime"] === "string" && raw["resetTime"].trim() ? raw["resetTime"] : void 0;
1649
+ const resetsAt = resetRaw !== void 0 && Number.isFinite(Date.parse(resetRaw)) ? new Date(Date.parse(resetRaw)).toISOString() : void 0;
1650
+ windows.push({
1651
+ id,
1652
+ label: modelId ? `Gemini ${modelId}` : "Gemini quota",
1653
+ scope: modelId ? "model-family" : "all",
1654
+ ...modelId ? { modelFamily: modelId } : {},
1655
+ usedPercent,
1656
+ ...resetsAt !== void 0 ? { resetsAt } : {},
1657
+ remainingSeconds: secondsUntil6(resetsAt, now),
1658
+ state: "fresh"
1659
+ });
1660
+ }
1661
+ return windows.length > 0 ? windows : null;
1662
+ }
1663
+ var GeminiAllowanceCollector = class {
1664
+ constructor(credentials, store = getSharedAccountAllowanceStore6(), fetchImpl = (url, init, accountId) => fetchUpstream6(url, init, { providerId: "gemini", accountId, redactBodies: true }), now = Date.now, projectResolver = getGeminiCodeAssistProjectResolver()) {
1665
+ this.credentials = credentials;
1666
+ this.store = store;
1667
+ this.fetchImpl = fetchImpl;
1668
+ this.now = now;
1669
+ this.projectResolver = projectResolver;
1670
+ }
1671
+ credentials;
1672
+ store;
1673
+ fetchImpl;
1674
+ now;
1675
+ projectResolver;
1676
+ inFlight = /* @__PURE__ */ new Map();
1677
+ async collectMany(accounts, options = {}) {
1678
+ const settled = await Promise.allSettled(
1679
+ accounts.map((account) => this.collect(account, options))
1680
+ );
1681
+ return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
1682
+ }
1683
+ collect(account, options = {}) {
1684
+ const now = this.now();
1685
+ if (account.tokens.authMethod !== "oauth") {
1686
+ const existing = this.store.get("gemini", account.id, now);
1687
+ if (existing?.windows.every((window) => window.state === "unsupported")) {
1688
+ return Promise.resolve(existing);
1689
+ }
1690
+ const snapshot = this.unsupportedSnapshot(account.id, now);
1691
+ this.store.set(snapshot);
1692
+ return Promise.resolve(snapshot);
1693
+ }
1694
+ const cached = this.store.get("gemini", account.id, now);
1695
+ if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
1696
+ return Promise.resolve(cached);
1697
+ }
1698
+ const running = this.inFlight.get(account.id);
1699
+ if (running) return running;
1700
+ const promise = this.fetchAccount(account.id).catch(() => this.failureSnapshot(account.id, "gemini_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
1701
+ this.inFlight.set(account.id, promise);
1702
+ return promise;
1703
+ }
1704
+ isCacheValid(snapshot, now, refreshAheadMs) {
1705
+ if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
1706
+ const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
1707
+ const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
1708
+ return Number.isFinite(expiresAt) && expiresAt > now + ahead;
1709
+ }
1710
+ async fetchAccount(accountId) {
1711
+ let accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
1712
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
1713
+ let project;
1714
+ try {
1715
+ project = await this.projectResolver.resolveProject(accessToken);
1716
+ } catch {
1717
+ project = void 0;
1718
+ }
1719
+ let response = await this.request(accountId, accessToken, project);
1720
+ if (response.status === 401 || response.status === 403) {
1721
+ const refreshed = await this.credentials.refreshAccountToken("gemini", accountId);
1722
+ if (!refreshed) return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
1723
+ accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
1724
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
1725
+ response = await this.request(accountId, accessToken, project);
1726
+ if (response.status === 401 || response.status === 403) {
1727
+ return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
1728
+ }
1729
+ }
1730
+ if (!response.ok) return this.failureSnapshot(accountId, "gemini_usage_http_error", this.now());
1731
+ let payload;
1732
+ try {
1733
+ payload = await response.json();
1734
+ } catch {
1735
+ return this.failureSnapshot(accountId, "gemini_usage_invalid_response", this.now());
1736
+ }
1737
+ const now = this.now();
1738
+ const windows = parseGeminiQuotaPayload(payload, now);
1739
+ const snapshot = {
1740
+ providerId: "gemini",
1741
+ accountId,
1742
+ source: "oauth-usage-api",
1743
+ observedAt: new Date(now).toISOString(),
1744
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1745
+ windows: windows ?? [
1746
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
1747
+ ],
1748
+ ...windows ? {} : { lastErrorCode: "gemini_usage_invalid_response" }
1749
+ };
1750
+ this.store.set(snapshot);
1751
+ return snapshot;
1752
+ }
1753
+ request(accountId, accessToken, project) {
1754
+ return this.fetchImpl(`${resolveCodeAssistEndpoint()}/v1internal:retrieveUserQuota`, {
1755
+ method: "POST",
1756
+ headers: {
1757
+ Authorization: `Bearer ${accessToken}`,
1758
+ Accept: "application/json",
1759
+ "Content-Type": "application/json",
1760
+ ...getGeminiCliIdentityHeaders()
1761
+ },
1762
+ body: JSON.stringify(project ? { project } : {}),
1763
+ signal: AbortSignal.timeout(15e3)
1764
+ }, accountId);
1765
+ }
1766
+ failureSnapshot(accountId, code, now) {
1767
+ const existing = this.store.get("gemini", accountId, now);
1768
+ const snapshot = existing ? {
1769
+ ...existing,
1770
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1771
+ windows: existing.windows.map((window) => ({
1772
+ ...window,
1773
+ state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
1774
+ })),
1775
+ lastErrorCode: code
1776
+ } : {
1777
+ providerId: "gemini",
1778
+ accountId,
1779
+ source: "oauth-usage-api",
1780
+ observedAt: new Date(now).toISOString(),
1781
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1782
+ windows: [
1783
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
1784
+ ],
1785
+ lastErrorCode: code
1786
+ };
1787
+ this.store.set(snapshot);
1788
+ return snapshot;
1789
+ }
1790
+ unsupportedSnapshot(accountId, now) {
1791
+ return {
1792
+ providerId: "gemini",
1793
+ accountId,
1794
+ source: "oauth-usage-api",
1795
+ observedAt: new Date(now).toISOString(),
1796
+ windows: [
1797
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unsupported" }
1798
+ ],
1799
+ lastErrorCode: "gemini_usage_unsupported_auth"
1800
+ };
1801
+ }
1802
+ };
1803
+
1804
+ // src/allowance/OpenCodeGoAllowanceCollector.ts
1805
+ import {
1806
+ getSharedAccountAllowanceStore as getSharedAccountAllowanceStore7
1807
+ } from "@omnicross/core/pipeline/AccountAllowanceStore";
1808
+ import { fetchUpstream as fetchUpstream7 } from "@omnicross/core/pipeline/upstreamFetch";
1622
1809
  import { normalizeOpenCodeGoBaseUrl } from "@omnicross/subscriptions";
1623
1810
  var OPENCODEGO_ALLOWANCE_CACHE_MS = 5 * 6e4;
1624
1811
  var OPENCODEGO_DEFAULT_GO_BASE = "https://opencode.ai/zen/go";
@@ -1632,7 +1819,7 @@ function isoInstant2(value) {
1632
1819
  const time = Date.parse(value);
1633
1820
  return Number.isFinite(time) ? new Date(time).toISOString() : void 0;
1634
1821
  }
1635
- function secondsUntil6(instant, now) {
1822
+ function secondsUntil7(instant, now) {
1636
1823
  if (!instant) return void 0;
1637
1824
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
1638
1825
  }
@@ -1647,12 +1834,12 @@ function windowFromPayload3(id, label, minutes, payload, now) {
1647
1834
  usedPercent,
1648
1835
  windowMinutes: minutes,
1649
1836
  ...resetsAt !== void 0 ? { resetsAt } : {},
1650
- remainingSeconds: secondsUntil6(resetsAt, now),
1837
+ remainingSeconds: secondsUntil7(resetsAt, now),
1651
1838
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
1652
1839
  };
1653
1840
  }
1654
1841
  var OpenCodeGoAllowanceCollector = class {
1655
- constructor(credentials, store = getSharedAccountAllowanceStore6(), fetchImpl = (url, init, accountId) => fetchUpstream6(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
1842
+ constructor(credentials, store = getSharedAccountAllowanceStore7(), fetchImpl = (url, init, accountId) => fetchUpstream7(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
1656
1843
  this.credentials = credentials;
1657
1844
  this.store = store;
1658
1845
  this.fetchImpl = fetchImpl;
@@ -1757,7 +1944,7 @@ function codexUnavailable(accountId, now) {
1757
1944
  };
1758
1945
  }
1759
1946
  var AccountAllowanceService = class {
1760
- constructor(credentials, store = getSharedAccountAllowanceStore7(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, now = Date.now) {
1947
+ constructor(credentials, store = getSharedAccountAllowanceStore8(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, geminiCollector, now = Date.now) {
1761
1948
  this.credentials = credentials;
1762
1949
  this.store = store;
1763
1950
  this.now = now;
@@ -1767,6 +1954,7 @@ var AccountAllowanceService = class {
1767
1954
  this.opencodegoCollector = opencodegoCollector ?? new OpenCodeGoAllowanceCollector(credentials, store);
1768
1955
  this.grokCollector = grokCollector ?? new GrokAllowanceCollector(credentials, store);
1769
1956
  this.copilotCollector = copilotCollector ?? new CopilotAllowanceCollector(credentials, store);
1957
+ this.geminiCollector = geminiCollector ?? new GeminiAllowanceCollector(credentials, store);
1770
1958
  }
1771
1959
  credentials;
1772
1960
  store;
@@ -1777,6 +1965,7 @@ var AccountAllowanceService = class {
1777
1965
  grokCollector;
1778
1966
  copilotCollector;
1779
1967
  opencodegoCollector;
1968
+ geminiCollector;
1780
1969
  /**
1781
1970
  * Read all/filtered snapshots. Claude's and Codex's five-minute caches are
1782
1971
  * refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
@@ -1820,6 +2009,11 @@ var AccountAllowanceService = class {
1820
2009
  (account) => !filter.accountId || account.id === filter.accountId
1821
2010
  );
1822
2011
  if (wantsCopilot) await this.copilotCollector.collectMany(copilotAccounts);
2012
+ const wantsGemini = !filter.providerId || filter.providerId === "gemini";
2013
+ const geminiAccounts = (config.geminiAccounts ?? []).filter(
2014
+ (account) => !filter.accountId || account.id === filter.accountId
2015
+ );
2016
+ if (wantsGemini) await this.geminiCollector.collectMany(geminiAccounts);
1823
2017
  const known = /* @__PURE__ */ new Set();
1824
2018
  if (wantsClaude) for (const account of claudeAccounts) known.add(`claude\0${account.id}`);
1825
2019
  if (wantsCodex) for (const account of codexAccounts) known.add(`codex\0${account.id}`);
@@ -1827,6 +2021,7 @@ var AccountAllowanceService = class {
1827
2021
  if (wantsOpenCodeGo) for (const account of opencodegoAccounts) known.add(`opencodego\0${account.id}`);
1828
2022
  if (wantsGrok) for (const account of grokAccounts) known.add(`grok\0${account.id}`);
1829
2023
  if (wantsCopilot) for (const account of copilotAccounts) known.add(`copilot\0${account.id}`);
2024
+ if (wantsGemini) for (const account of geminiAccounts) known.add(`gemini\0${account.id}`);
1830
2025
  return this.store.list(filter).filter((snapshot) => known.has(`${snapshot.providerId}\0${snapshot.accountId}`));
1831
2026
  }
1832
2027
  knownAccounts(config) {
@@ -1836,7 +2031,8 @@ var AccountAllowanceService = class {
1836
2031
  ...(config.kimiAccounts ?? []).map((account) => ({ providerId: "kimi", accountId: account.id })),
1837
2032
  ...(config.opencodegoAccounts ?? []).map((account) => ({ providerId: "opencodego", accountId: account.id })),
1838
2033
  ...(config.grokAccounts ?? []).map((account) => ({ providerId: "grok", accountId: account.id })),
1839
- ...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id }))
2034
+ ...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id })),
2035
+ ...(config.geminiAccounts ?? []).map((account) => ({ providerId: "gemini", accountId: account.id }))
1840
2036
  ];
1841
2037
  }
1842
2038
  /** Force-refresh Claude usage for one account or every stored Claude account. */
@@ -1897,6 +2093,15 @@ var AccountAllowanceService = class {
1897
2093
  );
1898
2094
  return this.grokCollector.collectMany(accounts, { force: true });
1899
2095
  }
2096
+ /** Force-refresh Gemini usage (Code Assist retrieveUserQuota) for one/all accounts. */
2097
+ async refreshGemini(accountId) {
2098
+ const config = await this.credentials.getFullConfig();
2099
+ this.store.pruneToKnownAccounts(this.knownAccounts(config));
2100
+ const accounts = (config.geminiAccounts ?? []).filter(
2101
+ (account) => !accountId || account.id === accountId
2102
+ );
2103
+ return this.geminiCollector.collectMany(accounts, { force: true });
2104
+ }
1900
2105
  /**
1901
2106
  * Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
1902
2107
  * collectors preserve their cache + per-account in-flight coalescing; a tick
@@ -1913,6 +2118,7 @@ var AccountAllowanceService = class {
1913
2118
  await this.opencodegoCollector.collectMany(config.opencodegoAccounts ?? [], { refreshAheadMs });
1914
2119
  await this.grokCollector.collectMany(config.grokAccounts ?? [], { refreshAheadMs });
1915
2120
  await this.copilotCollector.collectMany(config.copilotAccounts ?? [], { refreshAheadMs });
2121
+ await this.geminiCollector.collectMany(config.geminiAccounts ?? [], { refreshAheadMs });
1916
2122
  }
1917
2123
  /** Remove a cache row as soon as an account is deleted by the admin path. */
1918
2124
  removeAccountSnapshot(providerId, accountId) {
@@ -2349,7 +2555,7 @@ import {
2349
2555
  } from "@omnicross/contracts/image-generation-types";
2350
2556
  import { getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling2 } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
2351
2557
  import { getSharedAccountHealth } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
2352
- import { fetchUpstream as fetchUpstream7 } from "@omnicross/core/pipeline/upstreamFetch";
2558
+ import { fetchUpstream as fetchUpstream8 } from "@omnicross/core/pipeline/upstreamFetch";
2353
2559
  import { mergeExtraHeaders } from "@omnicross/core";
2354
2560
 
2355
2561
  // src/image-generation/imagesConfigValidation.ts
@@ -5734,7 +5940,7 @@ async function handleSearchQuery(req, res, deps) {
5734
5940
  // src/admin/searchAdminView.ts
5735
5941
  var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
5736
5942
  var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
5737
- function isRecord4(value) {
5943
+ function isRecord5(value) {
5738
5944
  return value !== null && typeof value === "object" && !Array.isArray(value);
5739
5945
  }
5740
5946
  function redactSearchServerConfig(search) {
@@ -5784,13 +5990,13 @@ function resolveSecretField(entry, field, stored) {
5784
5990
  else delete entry[field];
5785
5991
  }
5786
5992
  function preserveSearchSecrets(incoming, current) {
5787
- if (!isRecord4(incoming)) return incoming;
5993
+ if (!isRecord5(incoming)) return incoming;
5788
5994
  const section = { ...incoming };
5789
5995
  const providersValue = section["providers"];
5790
- if (!isRecord4(providersValue)) return section;
5996
+ if (!isRecord5(providersValue)) return section;
5791
5997
  const providers = {};
5792
5998
  for (const [id, entryValue] of Object.entries(providersValue)) {
5793
- if (!isRecord4(entryValue)) {
5999
+ if (!isRecord5(entryValue)) {
5794
6000
  providers[id] = entryValue;
5795
6001
  continue;
5796
6002
  }
@@ -5868,7 +6074,7 @@ function parseKeyPolicyBody(body) {
5868
6074
  var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
5869
6075
  var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
5870
6076
  var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
5871
- function isRecord5(value) {
6077
+ function isRecord6(value) {
5872
6078
  return !!value && typeof value === "object" && !Array.isArray(value);
5873
6079
  }
5874
6080
  function nonBlank(value) {
@@ -5888,7 +6094,7 @@ function validateGatewayBindingsSegment(patch) {
5888
6094
  const ids = /* @__PURE__ */ new Set();
5889
6095
  raw.forEach((entry, index) => {
5890
6096
  const path2 = `bindings[${index}]`;
5891
- if (!isRecord5(entry)) {
6097
+ if (!isRecord6(entry)) {
5892
6098
  errors.push(`${path2} must be an object`);
5893
6099
  return;
5894
6100
  }
@@ -5917,12 +6123,12 @@ function validateGatewayBindingsSegment(patch) {
5917
6123
  } else if (entry.modelMappings.length > 100) {
5918
6124
  errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
5919
6125
  } else if (entry.modelMappings.some(
5920
- (mapping) => !isRecord5(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
6126
+ (mapping) => !isRecord6(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
5921
6127
  )) {
5922
6128
  errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
5923
6129
  }
5924
6130
  }
5925
- if (!isRecord5(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
6131
+ if (!isRecord6(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
5926
6132
  errors.push(`${path2}.target is invalid`);
5927
6133
  } else {
5928
6134
  if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
@@ -5937,7 +6143,7 @@ function validateGatewayBindingsSegment(patch) {
5937
6143
  }
5938
6144
  }
5939
6145
  if (entry.modelMap !== void 0) {
5940
- if (!isRecord5(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
6146
+ if (!isRecord6(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
5941
6147
  errors.push(`${path2}.modelMap must contain string values`);
5942
6148
  }
5943
6149
  }
@@ -7026,7 +7232,7 @@ function query(req) {
7026
7232
  }
7027
7233
  function allowanceProvider(value) {
7028
7234
  if (!value) return void 0;
7029
- return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" ? value : null;
7235
+ return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" || value === "gemini" ? value : null;
7030
7236
  }
7031
7237
  async function handleAccountAllowanceApi(req, res, method, rest, service) {
7032
7238
  if (!service) return writeError2(res, 501, "account allowance service is not available");
@@ -7041,7 +7247,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7041
7247
  const pathProvider = rest.length >= 2 ? rest[0] : null;
7042
7248
  const providerId = allowanceProvider(pathProvider ?? params.get("providerId") ?? params.get("provider"));
7043
7249
  if (providerId === null) {
7044
- return writeError2(res, 400, "providerId must be claude, codex, kimi, opencodego, grok, or copilot");
7250
+ return writeError2(res, 400, "providerId must be claude, codex, kimi, opencodego, grok, copilot, or gemini");
7045
7251
  }
7046
7252
  const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
7047
7253
  const allowances = await service.list({ providerId, accountId });
@@ -7103,6 +7309,16 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7103
7309
  }
7104
7310
  return writeJson3(res, 200, { allowances: allowances2 });
7105
7311
  }
7312
+ if (requestedProvider === "gemini") {
7313
+ if (!service.refreshGemini) {
7314
+ return writeError2(res, 501, "gemini allowance refresh is not available");
7315
+ }
7316
+ const allowances2 = await service.refreshGemini(accountId);
7317
+ if (accountId && allowances2.length === 0) {
7318
+ return writeError2(res, 404, `Gemini account '${accountId}' not found`);
7319
+ }
7320
+ return writeJson3(res, 200, { allowances: allowances2 });
7321
+ }
7106
7322
  const allowances = await service.refreshClaude(accountId);
7107
7323
  if (accountId && allowances.length === 0) {
7108
7324
  return writeError2(res, 404, `Claude account '${accountId}' not found`);
@@ -7452,7 +7668,7 @@ async function handleDiscoverModels(res, id, cfg) {
7452
7668
  const headers = { Accept: "application/json" };
7453
7669
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
7454
7670
  Object.assign(headers, expandRowExtraHeaders(row));
7455
- const response = await fetchUpstream7(url, { method: "GET", headers }, { providerId: "byo" });
7671
+ const response = await fetchUpstream8(url, { method: "GET", headers }, { providerId: "byo" });
7456
7672
  if (!response.ok) {
7457
7673
  const text = await response.text().catch(() => "");
7458
7674
  let message = text.slice(0, 300);
@@ -7512,7 +7728,7 @@ async function handleTestModel(req, res, id, cfg) {
7512
7728
  Object.assign(headers, expandRowExtraHeaders(row));
7513
7729
  const startedAt = Date.now();
7514
7730
  try {
7515
- const response = await fetchUpstream7(
7731
+ const response = await fetchUpstream8(
7516
7732
  url,
7517
7733
  { method: "POST", headers, body: JSON.stringify(payload) },
7518
7734
  { providerId: "byo" }
@@ -8919,12 +9135,12 @@ async function handlePlayground(req, res, method, deps) {
8919
9135
  const payload = body["body"];
8920
9136
  const status = deps.outboundApiServer.getStatus();
8921
9137
  if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
8922
- const path2 = resolvePlaygroundPath(endpoint, isRecord6(payload) ? payload : {});
9138
+ const path2 = resolvePlaygroundPath(endpoint, isRecord7(payload) ? payload : {});
8923
9139
  if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
8924
9140
  const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
8925
9141
  await proxyToOutbound(res, status.port, path2, key, upstreamBody);
8926
9142
  }
8927
- function isRecord6(v) {
9143
+ function isRecord7(v) {
8928
9144
  return !!v && typeof v === "object" && !Array.isArray(v);
8929
9145
  }
8930
9146
  function proxyToOutbound(res, outboundPort, path2, key, body) {
@@ -9059,7 +9275,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
9059
9275
  }
9060
9276
 
9061
9277
  // src/admin/version.ts
9062
- var DAEMON_VERSION = true ? "0.4.0" : "0.0.0-dev";
9278
+ var DAEMON_VERSION = true ? "0.4.1" : "0.0.0-dev";
9063
9279
 
9064
9280
  // src/admin/AdminServer.ts
9065
9281
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -9479,7 +9695,7 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
9479
9695
 
9480
9696
  // src/allowance/ProviderKeyQuotaService.ts
9481
9697
  import { mergeExtraHeaders as mergeExtraHeaders2 } from "@omnicross/core";
9482
- import { fetchUpstream as fetchUpstream8 } from "@omnicross/core/pipeline/upstreamFetch";
9698
+ import { fetchUpstream as fetchUpstream9 } from "@omnicross/core/pipeline/upstreamFetch";
9483
9699
 
9484
9700
  // src/allowance/ProviderKeyQuota.ts
9485
9701
  var MINUTE_MS3 = 6e4;
@@ -9508,11 +9724,11 @@ function isoInstant3(value) {
9508
9724
  }
9509
9725
  return void 0;
9510
9726
  }
9511
- function secondsUntil7(instant, now) {
9727
+ function secondsUntil8(instant, now) {
9512
9728
  if (!instant) return void 0;
9513
9729
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
9514
9730
  }
9515
- function isRecord7(value) {
9731
+ function isRecord8(value) {
9516
9732
  return !!value && typeof value === "object" && !Array.isArray(value);
9517
9733
  }
9518
9734
  function detectProviderKeyQuotaAdapter(baseUrl) {
@@ -9525,7 +9741,7 @@ function detectProviderKeyQuotaAdapter(baseUrl) {
9525
9741
  }
9526
9742
  const host = url.hostname.toLowerCase();
9527
9743
  const path2 = url.pathname.toLowerCase();
9528
- if ((host === "api.z.ai" || host === "open.bigmodel.cn") && path2.includes("/coding")) {
9744
+ if ((host === "api.z.ai" || host === "open.bigmodel.cn") && (path2.includes("/coding") || path2.includes("/anthropic"))) {
9529
9745
  return "zai";
9530
9746
  }
9531
9747
  if ((host === "api.minimax.io" || host === "api.minimaxi.com") && // Token Plan rides the plain openai `/v1` (chat completions) surface; the
@@ -9579,17 +9795,17 @@ function zaiWindowIdLabel(durationMs) {
9579
9795
  return { id: "quota", label: "Quota" };
9580
9796
  }
9581
9797
  function parseZaiQuotaPayload(payload, now) {
9582
- if (!isRecord7(payload)) return null;
9583
- const data = isRecord7(payload["data"]) ? payload["data"] : payload;
9798
+ if (!isRecord8(payload)) return null;
9799
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
9584
9800
  if (payload["success"] === false) return null;
9585
9801
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
9586
9802
  const byWindow = /* @__PURE__ */ new Map();
9587
9803
  for (const raw of limits) {
9588
- if (!isRecord7(raw)) continue;
9804
+ if (!isRecord8(raw)) continue;
9589
9805
  const item = raw;
9590
9806
  if (item.type === void 0) continue;
9591
9807
  const details = raw["usageDetails"];
9592
- if (Array.isArray(details) && details.some((d) => isRecord7(d) && d["modelCode"] === "zread")) {
9808
+ if (Array.isArray(details) && details.some((d) => isRecord8(d) && d["modelCode"] === "zread")) {
9593
9809
  continue;
9594
9810
  }
9595
9811
  const durationMs = zaiWindowDurationMs(item);
@@ -9608,7 +9824,7 @@ function parseZaiQuotaPayload(payload, now) {
9608
9824
  usedPercent,
9609
9825
  ...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS3) } : {},
9610
9826
  ...resetsAt !== void 0 ? { resetsAt } : {},
9611
- remainingSeconds: secondsUntil7(resetsAt, now),
9827
+ remainingSeconds: secondsUntil8(resetsAt, now),
9612
9828
  state: "fresh"
9613
9829
  };
9614
9830
  const existing = byWindow.get(id);
@@ -9622,7 +9838,7 @@ function parseZaiQuotaPayload(payload, now) {
9622
9838
  var MINIMAX_STATUS_EXHAUSTED = 2;
9623
9839
  var MINIMAX_SHARED_BUCKET = "general";
9624
9840
  function parseMiniMaxBucket(value) {
9625
- if (!isRecord7(value)) return null;
9841
+ if (!isRecord8(value)) return null;
9626
9842
  const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
9627
9843
  if (!modelName) return null;
9628
9844
  const instant = (v) => {
@@ -9649,14 +9865,14 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
9649
9865
  usedPercent,
9650
9866
  ...windowMinutes !== void 0 ? { windowMinutes } : {},
9651
9867
  ...resetsAt !== void 0 ? { resetsAt } : {},
9652
- remainingSeconds: secondsUntil7(resetsAt, now),
9868
+ remainingSeconds: secondsUntil8(resetsAt, now),
9653
9869
  state: usedPercent !== null ? "fresh" : "unavailable"
9654
9870
  };
9655
9871
  }
9656
9872
  function parseMiniMaxTokenPlanPayload(payload, now) {
9657
- if (!isRecord7(payload)) return null;
9873
+ if (!isRecord8(payload)) return null;
9658
9874
  const baseResp = payload["base_resp"];
9659
- if (!isRecord7(baseResp) || baseResp["status_code"] !== 0) return null;
9875
+ if (!isRecord8(baseResp) || baseResp["status_code"] !== 0) return null;
9660
9876
  const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
9661
9877
  let general = null;
9662
9878
  for (const raw of buckets) {
@@ -9689,11 +9905,11 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
9689
9905
  ];
9690
9906
  }
9691
9907
  function parseUmansUsagePayload(payload, now) {
9692
- if (!isRecord7(payload)) return null;
9693
- const limits = isRecord7(payload["limits"]) ? payload["limits"] : void 0;
9694
- const requests = limits && isRecord7(limits["requests"]) ? limits["requests"] : void 0;
9695
- const usage = isRecord7(payload["usage"]) ? payload["usage"] : void 0;
9696
- const window = isRecord7(payload["window"]) ? payload["window"] : void 0;
9908
+ if (!isRecord8(payload)) return null;
9909
+ const limits = isRecord8(payload["limits"]) ? payload["limits"] : void 0;
9910
+ const requests = limits && isRecord8(limits["requests"]) ? limits["requests"] : void 0;
9911
+ const usage = isRecord8(payload["usage"]) ? payload["usage"] : void 0;
9912
+ const window = isRecord8(payload["window"]) ? payload["window"] : void 0;
9697
9913
  const hardCap = finiteNumber5(requests?.["hard_cap"]);
9698
9914
  const softLimit = finiteNumber5(requests?.["limit"]);
9699
9915
  const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
@@ -9714,15 +9930,15 @@ function parseUmansUsagePayload(payload, now) {
9714
9930
  usedPercent,
9715
9931
  windowMinutes: 5 * 60,
9716
9932
  ...resetsAt !== void 0 ? { resetsAt } : {},
9717
- remainingSeconds: secondsUntil7(resetsAt, now),
9933
+ remainingSeconds: secondsUntil8(resetsAt, now),
9718
9934
  state: "fresh"
9719
9935
  }
9720
9936
  ];
9721
9937
  }
9722
9938
  function parseSyntheticQuotasPayload(payload, now) {
9723
- if (!isRecord7(payload)) return null;
9724
- const fiveHour = isRecord7(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
9725
- const weekly = isRecord7(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
9939
+ if (!isRecord8(payload)) return null;
9940
+ const fiveHour = isRecord8(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
9941
+ const weekly = isRecord8(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
9726
9942
  const windows = [];
9727
9943
  if (fiveHour) {
9728
9944
  const max = finiteNumber5(fiveHour["max"]);
@@ -9736,7 +9952,7 @@ function parseSyntheticQuotasPayload(payload, now) {
9736
9952
  usedPercent,
9737
9953
  windowMinutes: 5 * 60,
9738
9954
  ...resetsAt !== void 0 ? { resetsAt } : {},
9739
- remainingSeconds: secondsUntil7(resetsAt, now),
9955
+ remainingSeconds: secondsUntil8(resetsAt, now),
9740
9956
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9741
9957
  });
9742
9958
  }
@@ -9751,7 +9967,7 @@ function parseSyntheticQuotasPayload(payload, now) {
9751
9967
  usedPercent,
9752
9968
  windowMinutes: 7 * 24 * 60,
9753
9969
  ...resetsAt !== void 0 ? { resetsAt } : {},
9754
- remainingSeconds: secondsUntil7(resetsAt, now),
9970
+ remainingSeconds: secondsUntil8(resetsAt, now),
9755
9971
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9756
9972
  });
9757
9973
  }
@@ -9763,12 +9979,12 @@ var CLINE_WINDOW_CONFIG = {
9763
9979
  monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
9764
9980
  };
9765
9981
  function parseClinePassUsageLimitsPayload(payload, now) {
9766
- if (!isRecord7(payload)) return null;
9767
- const data = isRecord7(payload["data"]) ? payload["data"] : payload;
9982
+ if (!isRecord8(payload)) return null;
9983
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
9768
9984
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
9769
9985
  const windows = [];
9770
9986
  for (const raw of limits) {
9771
- if (!isRecord7(raw)) continue;
9987
+ if (!isRecord8(raw)) continue;
9772
9988
  const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
9773
9989
  if (!config) continue;
9774
9990
  const usedPercent = finitePercent4(raw["percentUsed"]);
@@ -9781,7 +9997,7 @@ function parseClinePassUsageLimitsPayload(payload, now) {
9781
9997
  usedPercent,
9782
9998
  windowMinutes: config.minutes,
9783
9999
  ...resetsAt !== void 0 ? { resetsAt } : {},
9784
- remainingSeconds: secondsUntil7(resetsAt, now),
10000
+ remainingSeconds: secondsUntil8(resetsAt, now),
9785
10001
  state: "fresh"
9786
10002
  });
9787
10003
  }
@@ -9820,7 +10036,7 @@ function rowKeyEntries(row) {
9820
10036
  return [];
9821
10037
  }
9822
10038
  var ProviderKeyQuotaService = class {
9823
- constructor(box, fetchImpl = (url, init) => fetchUpstream8(url, init, { redactBodies: true }), now = Date.now) {
10039
+ constructor(box, fetchImpl = (url, init) => fetchUpstream9(url, init, { redactBodies: true }), now = Date.now) {
9824
10040
  this.box = box;
9825
10041
  this.fetchImpl = fetchImpl;
9826
10042
  this.now = now;
@@ -16643,7 +16859,7 @@ import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as re
16643
16859
  import { dirname as dirname15 } from "path";
16644
16860
  import { getSharedAccountHealth as getSharedAccountHealth2 } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
16645
16861
  import { getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling3 } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
16646
- import { fetchUpstream as fetchUpstream9 } from "@omnicross/core/pipeline/upstreamFetch";
16862
+ import { fetchUpstream as fetchUpstream10 } from "@omnicross/core/pipeline/upstreamFetch";
16647
16863
  import { getSharedIdentityStore as getSharedIdentityStore2 } from "@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore";
16648
16864
  import {
16649
16865
  claudeOAuth as claudeOAuth2,
@@ -16799,7 +17015,7 @@ var JsonSubscriptionCredentialStore = class {
16799
17015
  * a plaintext token pair into `upstream-trace.jsonl`.
16800
17016
  */
16801
17017
  buildRefreshFetch(providerId, accountId) {
16802
- return this.fetchImpl ?? ((url, init) => fetchUpstream9(url, init, { providerId, accountId, redactBodies: true }));
17018
+ return this.fetchImpl ?? ((url, init) => fetchUpstream10(url, init, { providerId, accountId, redactBodies: true }));
16803
17019
  }
16804
17020
  /**
16805
17021
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -17529,7 +17745,7 @@ var JsonSubscriptionCredentialStore = class {
17529
17745
  };
17530
17746
 
17531
17747
  // src/AccountHealthProbeScheduler.ts
17532
- import { fetchUpstream as fetchUpstream10 } from "@omnicross/core/pipeline/upstreamFetch";
17748
+ import { fetchUpstream as fetchUpstream11 } from "@omnicross/core/pipeline/upstreamFetch";
17533
17749
 
17534
17750
  // src/probe/CodexGenerationProbe.ts
17535
17751
  import {
@@ -17706,7 +17922,7 @@ var AccountHealthProbeScheduler = class {
17706
17922
  this.logger = logger;
17707
17923
  this.config = config;
17708
17924
  this.now = opts.now ?? Date.now;
17709
- this.fetchImpl = opts.fetchImpl ?? fetchUpstream10;
17925
+ this.fetchImpl = opts.fetchImpl ?? fetchUpstream11;
17710
17926
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
17711
17927
  this.planFor = opts.planFor ?? probePlanFor;
17712
17928
  }
@@ -19411,7 +19627,7 @@ var AuditWriter = class {
19411
19627
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync8 } from "fs";
19412
19628
  import { createHmac as createHmac5 } from "crypto";
19413
19629
  import { join as join26 } from "path";
19414
- import { fetchUpstream as fetchUpstream11 } from "@omnicross/core/pipeline/upstreamFetch";
19630
+ import { fetchUpstream as fetchUpstream12 } from "@omnicross/core/pipeline/upstreamFetch";
19415
19631
 
19416
19632
  // src/billing/billingFiles.ts
19417
19633
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -19434,7 +19650,7 @@ var BillingPublisher = class {
19434
19650
  constructor(billingDir, logger, opts = {}) {
19435
19651
  this.billingDir = billingDir;
19436
19652
  this.logger = logger;
19437
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream11(url, init));
19653
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream12(url, init));
19438
19654
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
19439
19655
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
19440
19656
  this.now = opts.now ?? Date.now;
@@ -19853,7 +20069,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
19853
20069
 
19854
20070
  // src/webhook/WebhookDispatcher.ts
19855
20071
  import { createHmac as createHmac6 } from "crypto";
19856
- import { fetchUpstream as fetchUpstream12 } from "@omnicross/core/pipeline/upstreamFetch";
20072
+ import { fetchUpstream as fetchUpstream13 } from "@omnicross/core/pipeline/upstreamFetch";
19857
20073
  var WEBHOOK_MAX_ATTEMPTS = 3;
19858
20074
  var WEBHOOK_QUEUE_MAX = 1e3;
19859
20075
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -19873,7 +20089,7 @@ var WebhookDispatcher = class {
19873
20089
  sleep;
19874
20090
  now;
19875
20091
  constructor(opts = {}) {
19876
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream12(url, init));
20092
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream13(url, init));
19877
20093
  this.logger = opts.logger;
19878
20094
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
19879
20095
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -20102,7 +20318,7 @@ function buildDaemon(config, paths) {
20102
20318
  setSecretBox(secretBox3);
20103
20319
  setSecretBox2(secretBox3);
20104
20320
  const decryptedConfig = decryptConfigSecrets(config, secretBox3);
20105
- const accountAllowanceStore = new AccountAllowanceStore8(
20321
+ const accountAllowanceStore = new AccountAllowanceStore9(
20106
20322
  Date.now,
20107
20323
  void 0,
20108
20324
  new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
@@ -20145,7 +20361,7 @@ function buildDaemon(config, paths) {
20145
20361
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
20146
20362
  })
20147
20363
  );
20148
- setGeminiCodeAssistResolver(getGeminiCodeAssistProjectResolver());
20364
+ setGeminiCodeAssistResolver(getGeminiCodeAssistProjectResolver2());
20149
20365
  const autoDisableStore = new AutoDisableStore();
20150
20366
  const providerKeyQuotaService = new ProviderKeyQuotaService(secretBox3);
20151
20367
  const apiKeyPool = new ApiKeyPoolService(
@@ -20164,7 +20380,7 @@ function buildDaemon(config, paths) {
20164
20380
  const pricingEngine = new PricingEngine(pricingStore, logger, {
20165
20381
  // Catalog egress follows the same global/env proxy policy as every other
20166
20382
  // daemon upstream call; no provider/account override applies here.
20167
- fetchImpl: ((input, init) => fetchUpstream13(String(input), init ?? {}))
20383
+ fetchImpl: ((input, init) => fetchUpstream14(String(input), init ?? {}))
20168
20384
  });
20169
20385
  const pricingRefreshScheduler = new PricingRefreshScheduler(
20170
20386
  pricingEngine,
@@ -20449,7 +20665,7 @@ function buildDaemon(config, paths) {
20449
20665
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
20450
20666
  // excluded from the upstream trace, so a failing login left no evidence.
20451
20667
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
20452
- oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => fetchUpstream13(url, init, { providerId, redactBodies: true }),
20668
+ oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => fetchUpstream14(url, init, { providerId, redactBodies: true }),
20453
20669
  subscriptionAccountAppender: credentialStore,
20454
20670
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
20455
20671
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -20522,7 +20738,7 @@ function buildDaemon(config, paths) {
20522
20738
  });
20523
20739
  const webhookDispatcher = new WebhookDispatcher({
20524
20740
  logger,
20525
- fetchImpl: (url, init) => fetchUpstream13(url, init)
20741
+ fetchImpl: (url, init) => fetchUpstream14(url, init)
20526
20742
  });
20527
20743
  setWebhookRuntime(webhookDispatcher, getSharedAccountHealth4());
20528
20744
  const auditWriter = new AuditWriter(auditDir, logger);