@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.cjs CHANGED
@@ -63,14 +63,14 @@ var import_node_path35 = require("path");
63
63
  var import_audit_types = require("@omnicross/contracts/audit-types");
64
64
  var import_billing_types = require("@omnicross/contracts/billing-types");
65
65
  var import_core7 = require("@omnicross/core");
66
- var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
66
+ var import_GeminiCodeAssistProjectResolver2 = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
67
67
  var import_ApiKeyPoolService = require("@omnicross/core/completion/ApiKeyPoolService");
68
68
  var import_outbound_api10 = require("@omnicross/core/outbound-api");
69
69
  var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subscriptionRegistryPort");
70
70
  var import_SubscriptionAccountHealth4 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
71
- var import_AccountAllowanceStore9 = require("@omnicross/core/pipeline/AccountAllowanceStore");
71
+ var import_AccountAllowanceStore10 = require("@omnicross/core/pipeline/AccountAllowanceStore");
72
72
  var import_AccountAllowanceScheduling5 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
73
- var import_upstreamFetch15 = require("@omnicross/core/pipeline/upstreamFetch");
73
+ var import_upstreamFetch16 = require("@omnicross/core/pipeline/upstreamFetch");
74
74
  var import_SubscriptionIdentityStore3 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
75
75
  var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-code-assist-resolver");
76
76
  var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
@@ -439,7 +439,7 @@ function handleCopilotOAuthStatus(sessionId, deps) {
439
439
  }
440
440
 
441
441
  // src/allowance/AccountAllowanceService.ts
442
- var import_AccountAllowanceStore7 = require("@omnicross/core/pipeline/AccountAllowanceStore");
442
+ var import_AccountAllowanceStore8 = require("@omnicross/core/pipeline/AccountAllowanceStore");
443
443
  var import_AccountAllowanceScheduling = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
444
444
 
445
445
  // src/allowance/ClaudeAllowanceCollector.ts
@@ -1627,9 +1627,191 @@ var CopilotAllowanceCollector = class {
1627
1627
  }
1628
1628
  };
1629
1629
 
1630
- // src/allowance/OpenCodeGoAllowanceCollector.ts
1630
+ // src/allowance/GeminiAllowanceCollector.ts
1631
+ var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
1631
1632
  var import_AccountAllowanceStore6 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1632
1633
  var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
1634
+ var import_transformers = require("@omnicross/core/transformer/transformers");
1635
+ var GEMINI_ALLOWANCE_CACHE_MS = 5 * 6e4;
1636
+ function isRecord4(value) {
1637
+ return !!value && typeof value === "object" && !Array.isArray(value);
1638
+ }
1639
+ function secondsUntil6(instant, now) {
1640
+ if (!instant) return void 0;
1641
+ return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
1642
+ }
1643
+ function parseGeminiQuotaPayload(payload, now) {
1644
+ if (!isRecord4(payload)) return null;
1645
+ const buckets = Array.isArray(payload["buckets"]) ? payload["buckets"] : [];
1646
+ const windows = [];
1647
+ const seen = /* @__PURE__ */ new Set();
1648
+ for (const raw of buckets) {
1649
+ if (!isRecord4(raw)) continue;
1650
+ const modelId = typeof raw["modelId"] === "string" && raw["modelId"].trim() ? raw["modelId"].trim() : void 0;
1651
+ const id = `gemini:${modelId ?? "all"}`;
1652
+ if (seen.has(id)) continue;
1653
+ seen.add(id);
1654
+ const fractionRaw = typeof raw["remainingFraction"] === "number" ? raw["remainingFraction"] : Number(raw["remainingFraction"]);
1655
+ 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;
1656
+ const resetRaw = typeof raw["resetTime"] === "string" && raw["resetTime"].trim() ? raw["resetTime"] : void 0;
1657
+ const resetsAt = resetRaw !== void 0 && Number.isFinite(Date.parse(resetRaw)) ? new Date(Date.parse(resetRaw)).toISOString() : void 0;
1658
+ windows.push({
1659
+ id,
1660
+ label: modelId ? `Gemini ${modelId}` : "Gemini quota",
1661
+ scope: modelId ? "model-family" : "all",
1662
+ ...modelId ? { modelFamily: modelId } : {},
1663
+ usedPercent,
1664
+ ...resetsAt !== void 0 ? { resetsAt } : {},
1665
+ remainingSeconds: secondsUntil6(resetsAt, now),
1666
+ state: "fresh"
1667
+ });
1668
+ }
1669
+ return windows.length > 0 ? windows : null;
1670
+ }
1671
+ var GeminiAllowanceCollector = class {
1672
+ constructor(credentials, store = (0, import_AccountAllowanceStore6.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch6.fetchUpstream)(url, init, { providerId: "gemini", accountId, redactBodies: true }), now = Date.now, projectResolver = (0, import_GeminiCodeAssistProjectResolver.getGeminiCodeAssistProjectResolver)()) {
1673
+ this.credentials = credentials;
1674
+ this.store = store;
1675
+ this.fetchImpl = fetchImpl;
1676
+ this.now = now;
1677
+ this.projectResolver = projectResolver;
1678
+ }
1679
+ credentials;
1680
+ store;
1681
+ fetchImpl;
1682
+ now;
1683
+ projectResolver;
1684
+ inFlight = /* @__PURE__ */ new Map();
1685
+ async collectMany(accounts, options = {}) {
1686
+ const settled = await Promise.allSettled(
1687
+ accounts.map((account) => this.collect(account, options))
1688
+ );
1689
+ return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
1690
+ }
1691
+ collect(account, options = {}) {
1692
+ const now = this.now();
1693
+ if (account.tokens.authMethod !== "oauth") {
1694
+ const existing = this.store.get("gemini", account.id, now);
1695
+ if (existing?.windows.every((window) => window.state === "unsupported")) {
1696
+ return Promise.resolve(existing);
1697
+ }
1698
+ const snapshot = this.unsupportedSnapshot(account.id, now);
1699
+ this.store.set(snapshot);
1700
+ return Promise.resolve(snapshot);
1701
+ }
1702
+ const cached = this.store.get("gemini", account.id, now);
1703
+ if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
1704
+ return Promise.resolve(cached);
1705
+ }
1706
+ const running = this.inFlight.get(account.id);
1707
+ if (running) return running;
1708
+ const promise = this.fetchAccount(account.id).catch(() => this.failureSnapshot(account.id, "gemini_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
1709
+ this.inFlight.set(account.id, promise);
1710
+ return promise;
1711
+ }
1712
+ isCacheValid(snapshot, now, refreshAheadMs) {
1713
+ if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
1714
+ const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
1715
+ const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
1716
+ return Number.isFinite(expiresAt) && expiresAt > now + ahead;
1717
+ }
1718
+ async fetchAccount(accountId) {
1719
+ let accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
1720
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
1721
+ let project;
1722
+ try {
1723
+ project = await this.projectResolver.resolveProject(accessToken);
1724
+ } catch {
1725
+ project = void 0;
1726
+ }
1727
+ let response = await this.request(accountId, accessToken, project);
1728
+ if (response.status === 401 || response.status === 403) {
1729
+ const refreshed = await this.credentials.refreshAccountToken("gemini", accountId);
1730
+ if (!refreshed) return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
1731
+ accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
1732
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
1733
+ response = await this.request(accountId, accessToken, project);
1734
+ if (response.status === 401 || response.status === 403) {
1735
+ return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
1736
+ }
1737
+ }
1738
+ if (!response.ok) return this.failureSnapshot(accountId, "gemini_usage_http_error", this.now());
1739
+ let payload;
1740
+ try {
1741
+ payload = await response.json();
1742
+ } catch {
1743
+ return this.failureSnapshot(accountId, "gemini_usage_invalid_response", this.now());
1744
+ }
1745
+ const now = this.now();
1746
+ const windows = parseGeminiQuotaPayload(payload, now);
1747
+ const snapshot = {
1748
+ providerId: "gemini",
1749
+ accountId,
1750
+ source: "oauth-usage-api",
1751
+ observedAt: new Date(now).toISOString(),
1752
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1753
+ windows: windows ?? [
1754
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
1755
+ ],
1756
+ ...windows ? {} : { lastErrorCode: "gemini_usage_invalid_response" }
1757
+ };
1758
+ this.store.set(snapshot);
1759
+ return snapshot;
1760
+ }
1761
+ request(accountId, accessToken, project) {
1762
+ return this.fetchImpl(`${(0, import_transformers.resolveCodeAssistEndpoint)()}/v1internal:retrieveUserQuota`, {
1763
+ method: "POST",
1764
+ headers: {
1765
+ Authorization: `Bearer ${accessToken}`,
1766
+ Accept: "application/json",
1767
+ "Content-Type": "application/json",
1768
+ ...(0, import_transformers.getGeminiCliIdentityHeaders)()
1769
+ },
1770
+ body: JSON.stringify(project ? { project } : {}),
1771
+ signal: AbortSignal.timeout(15e3)
1772
+ }, accountId);
1773
+ }
1774
+ failureSnapshot(accountId, code, now) {
1775
+ const existing = this.store.get("gemini", accountId, now);
1776
+ const snapshot = existing ? {
1777
+ ...existing,
1778
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1779
+ windows: existing.windows.map((window) => ({
1780
+ ...window,
1781
+ state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
1782
+ })),
1783
+ lastErrorCode: code
1784
+ } : {
1785
+ providerId: "gemini",
1786
+ accountId,
1787
+ source: "oauth-usage-api",
1788
+ observedAt: new Date(now).toISOString(),
1789
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
1790
+ windows: [
1791
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
1792
+ ],
1793
+ lastErrorCode: code
1794
+ };
1795
+ this.store.set(snapshot);
1796
+ return snapshot;
1797
+ }
1798
+ unsupportedSnapshot(accountId, now) {
1799
+ return {
1800
+ providerId: "gemini",
1801
+ accountId,
1802
+ source: "oauth-usage-api",
1803
+ observedAt: new Date(now).toISOString(),
1804
+ windows: [
1805
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unsupported" }
1806
+ ],
1807
+ lastErrorCode: "gemini_usage_unsupported_auth"
1808
+ };
1809
+ }
1810
+ };
1811
+
1812
+ // src/allowance/OpenCodeGoAllowanceCollector.ts
1813
+ var import_AccountAllowanceStore7 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1814
+ var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
1633
1815
  var import_subscriptions7 = require("@omnicross/subscriptions");
1634
1816
  var OPENCODEGO_ALLOWANCE_CACHE_MS = 5 * 6e4;
1635
1817
  var OPENCODEGO_DEFAULT_GO_BASE = "https://opencode.ai/zen/go";
@@ -1643,7 +1825,7 @@ function isoInstant2(value) {
1643
1825
  const time = Date.parse(value);
1644
1826
  return Number.isFinite(time) ? new Date(time).toISOString() : void 0;
1645
1827
  }
1646
- function secondsUntil6(instant, now) {
1828
+ function secondsUntil7(instant, now) {
1647
1829
  if (!instant) return void 0;
1648
1830
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
1649
1831
  }
@@ -1658,12 +1840,12 @@ function windowFromPayload3(id, label, minutes, payload, now) {
1658
1840
  usedPercent,
1659
1841
  windowMinutes: minutes,
1660
1842
  ...resetsAt !== void 0 ? { resetsAt } : {},
1661
- remainingSeconds: secondsUntil6(resetsAt, now),
1843
+ remainingSeconds: secondsUntil7(resetsAt, now),
1662
1844
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
1663
1845
  };
1664
1846
  }
1665
1847
  var OpenCodeGoAllowanceCollector = class {
1666
- constructor(credentials, store = (0, import_AccountAllowanceStore6.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch6.fetchUpstream)(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
1848
+ constructor(credentials, store = (0, import_AccountAllowanceStore7.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch7.fetchUpstream)(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
1667
1849
  this.credentials = credentials;
1668
1850
  this.store = store;
1669
1851
  this.fetchImpl = fetchImpl;
@@ -1768,7 +1950,7 @@ function codexUnavailable(accountId, now) {
1768
1950
  };
1769
1951
  }
1770
1952
  var AccountAllowanceService = class {
1771
- constructor(credentials, store = (0, import_AccountAllowanceStore7.getSharedAccountAllowanceStore)(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, now = Date.now) {
1953
+ constructor(credentials, store = (0, import_AccountAllowanceStore8.getSharedAccountAllowanceStore)(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, geminiCollector, now = Date.now) {
1772
1954
  this.credentials = credentials;
1773
1955
  this.store = store;
1774
1956
  this.now = now;
@@ -1778,6 +1960,7 @@ var AccountAllowanceService = class {
1778
1960
  this.opencodegoCollector = opencodegoCollector ?? new OpenCodeGoAllowanceCollector(credentials, store);
1779
1961
  this.grokCollector = grokCollector ?? new GrokAllowanceCollector(credentials, store);
1780
1962
  this.copilotCollector = copilotCollector ?? new CopilotAllowanceCollector(credentials, store);
1963
+ this.geminiCollector = geminiCollector ?? new GeminiAllowanceCollector(credentials, store);
1781
1964
  }
1782
1965
  credentials;
1783
1966
  store;
@@ -1788,6 +1971,7 @@ var AccountAllowanceService = class {
1788
1971
  grokCollector;
1789
1972
  copilotCollector;
1790
1973
  opencodegoCollector;
1974
+ geminiCollector;
1791
1975
  /**
1792
1976
  * Read all/filtered snapshots. Claude's and Codex's five-minute caches are
1793
1977
  * refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
@@ -1831,6 +2015,11 @@ var AccountAllowanceService = class {
1831
2015
  (account) => !filter.accountId || account.id === filter.accountId
1832
2016
  );
1833
2017
  if (wantsCopilot) await this.copilotCollector.collectMany(copilotAccounts);
2018
+ const wantsGemini = !filter.providerId || filter.providerId === "gemini";
2019
+ const geminiAccounts = (config.geminiAccounts ?? []).filter(
2020
+ (account) => !filter.accountId || account.id === filter.accountId
2021
+ );
2022
+ if (wantsGemini) await this.geminiCollector.collectMany(geminiAccounts);
1834
2023
  const known = /* @__PURE__ */ new Set();
1835
2024
  if (wantsClaude) for (const account of claudeAccounts) known.add(`claude\0${account.id}`);
1836
2025
  if (wantsCodex) for (const account of codexAccounts) known.add(`codex\0${account.id}`);
@@ -1838,6 +2027,7 @@ var AccountAllowanceService = class {
1838
2027
  if (wantsOpenCodeGo) for (const account of opencodegoAccounts) known.add(`opencodego\0${account.id}`);
1839
2028
  if (wantsGrok) for (const account of grokAccounts) known.add(`grok\0${account.id}`);
1840
2029
  if (wantsCopilot) for (const account of copilotAccounts) known.add(`copilot\0${account.id}`);
2030
+ if (wantsGemini) for (const account of geminiAccounts) known.add(`gemini\0${account.id}`);
1841
2031
  return this.store.list(filter).filter((snapshot) => known.has(`${snapshot.providerId}\0${snapshot.accountId}`));
1842
2032
  }
1843
2033
  knownAccounts(config) {
@@ -1847,7 +2037,8 @@ var AccountAllowanceService = class {
1847
2037
  ...(config.kimiAccounts ?? []).map((account) => ({ providerId: "kimi", accountId: account.id })),
1848
2038
  ...(config.opencodegoAccounts ?? []).map((account) => ({ providerId: "opencodego", accountId: account.id })),
1849
2039
  ...(config.grokAccounts ?? []).map((account) => ({ providerId: "grok", accountId: account.id })),
1850
- ...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id }))
2040
+ ...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id })),
2041
+ ...(config.geminiAccounts ?? []).map((account) => ({ providerId: "gemini", accountId: account.id }))
1851
2042
  ];
1852
2043
  }
1853
2044
  /** Force-refresh Claude usage for one account or every stored Claude account. */
@@ -1908,6 +2099,15 @@ var AccountAllowanceService = class {
1908
2099
  );
1909
2100
  return this.grokCollector.collectMany(accounts, { force: true });
1910
2101
  }
2102
+ /** Force-refresh Gemini usage (Code Assist retrieveUserQuota) for one/all accounts. */
2103
+ async refreshGemini(accountId) {
2104
+ const config = await this.credentials.getFullConfig();
2105
+ this.store.pruneToKnownAccounts(this.knownAccounts(config));
2106
+ const accounts = (config.geminiAccounts ?? []).filter(
2107
+ (account) => !accountId || account.id === accountId
2108
+ );
2109
+ return this.geminiCollector.collectMany(accounts, { force: true });
2110
+ }
1911
2111
  /**
1912
2112
  * Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
1913
2113
  * collectors preserve their cache + per-account in-flight coalescing; a tick
@@ -1924,6 +2124,7 @@ var AccountAllowanceService = class {
1924
2124
  await this.opencodegoCollector.collectMany(config.opencodegoAccounts ?? [], { refreshAheadMs });
1925
2125
  await this.grokCollector.collectMany(config.grokAccounts ?? [], { refreshAheadMs });
1926
2126
  await this.copilotCollector.collectMany(config.copilotAccounts ?? [], { refreshAheadMs });
2127
+ await this.geminiCollector.collectMany(config.geminiAccounts ?? [], { refreshAheadMs });
1927
2128
  }
1928
2129
  /** Remove a cache row as soon as an account is deleted by the admin path. */
1929
2130
  removeAccountSnapshot(providerId, accountId) {
@@ -2018,7 +2219,7 @@ var ClaudeAllowanceRefreshScheduler = class {
2018
2219
  var import_node_crypto2 = require("crypto");
2019
2220
  var import_node_fs = require("fs");
2020
2221
  var import_node_path = require("path");
2021
- var import_AccountAllowanceStore8 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2222
+ var import_AccountAllowanceStore9 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2022
2223
  var ACCOUNT_ALLOWANCE_CACHE_VERSION = 1;
2023
2224
  var MAX_PERSISTED_ALLOWANCE_SNAPSHOTS = 256;
2024
2225
  var MAX_ALLOWANCE_CACHE_BYTES = 1e6;
@@ -2047,7 +2248,7 @@ var JsonAccountAllowancePersistence = class {
2047
2248
  save(snapshots) {
2048
2249
  const rows = [];
2049
2250
  for (const snapshot of snapshots) {
2050
- const normalized2 = (0, import_AccountAllowanceStore8.normalizeAccountAllowanceSnapshot)(snapshot);
2251
+ const normalized2 = (0, import_AccountAllowanceStore9.normalizeAccountAllowanceSnapshot)(snapshot);
2051
2252
  if (!normalized2) continue;
2052
2253
  rows.push(normalized2);
2053
2254
  if (rows.length >= MAX_PERSISTED_ALLOWANCE_SNAPSHOTS) break;
@@ -2330,7 +2531,7 @@ var import_outbound_api5 = require("@omnicross/core/outbound-api");
2330
2531
  var import_image_generation_types = require("@omnicross/contracts/image-generation-types");
2331
2532
  var import_AccountAllowanceScheduling2 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
2332
2533
  var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
2333
- var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
2534
+ var import_upstreamFetch10 = require("@omnicross/core/pipeline/upstreamFetch");
2334
2535
  var import_core3 = require("@omnicross/core");
2335
2536
 
2336
2537
  // src/image-generation/imagesConfigValidation.ts
@@ -4316,11 +4517,11 @@ function preserveOutboundProxySecrets(incoming, current) {
4316
4517
  }
4317
4518
 
4318
4519
  // src/proxy/upstreamProxyResolver.ts
4319
- var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
4520
+ var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
4320
4521
  var serverProxy;
4321
4522
  function setServerProxyConfig(proxy) {
4322
4523
  serverProxy = proxy;
4323
- (0, import_upstreamFetch7.bumpUpstreamProxyGeneration)();
4524
+ (0, import_upstreamFetch8.bumpUpstreamProxyGeneration)();
4324
4525
  }
4325
4526
  function getServerProxyConfig() {
4326
4527
  return serverProxy;
@@ -5369,7 +5570,7 @@ function classifySearchFailure(stage, code) {
5369
5570
  }
5370
5571
 
5371
5572
  // src/search/SearchAssembly.ts
5372
- var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
5573
+ var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
5373
5574
  var import_search = require("@omnicross/core/search");
5374
5575
  var import_api2 = require("@omnicross/core/search/api");
5375
5576
  var import_http2 = require("@omnicross/core/search/http");
@@ -5387,7 +5588,7 @@ function searchPolicyFrom(config) {
5387
5588
  };
5388
5589
  }
5389
5590
  function resolveSearchUpstreamDispatcher(url) {
5390
- return (0, import_upstreamFetch8.resolveUpstreamDispatcher)({ url });
5591
+ return (0, import_upstreamFetch9.resolveUpstreamDispatcher)({ url });
5391
5592
  }
5392
5593
  var searchUpstreamProxyConfig = createUpstreamProxyResolver();
5393
5594
  function resolveSearchUpstreamProxyConfig(url) {
@@ -5669,7 +5870,7 @@ async function handleSearchQuery(req, res, deps) {
5669
5870
  // src/admin/searchAdminView.ts
5670
5871
  var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
5671
5872
  var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
5672
- function isRecord4(value) {
5873
+ function isRecord5(value) {
5673
5874
  return value !== null && typeof value === "object" && !Array.isArray(value);
5674
5875
  }
5675
5876
  function redactSearchServerConfig(search) {
@@ -5719,13 +5920,13 @@ function resolveSecretField(entry, field, stored) {
5719
5920
  else delete entry[field];
5720
5921
  }
5721
5922
  function preserveSearchSecrets(incoming, current) {
5722
- if (!isRecord4(incoming)) return incoming;
5923
+ if (!isRecord5(incoming)) return incoming;
5723
5924
  const section = { ...incoming };
5724
5925
  const providersValue = section["providers"];
5725
- if (!isRecord4(providersValue)) return section;
5926
+ if (!isRecord5(providersValue)) return section;
5726
5927
  const providers = {};
5727
5928
  for (const [id, entryValue] of Object.entries(providersValue)) {
5728
- if (!isRecord4(entryValue)) {
5929
+ if (!isRecord5(entryValue)) {
5729
5930
  providers[id] = entryValue;
5730
5931
  continue;
5731
5932
  }
@@ -5803,7 +6004,7 @@ function parseKeyPolicyBody(body) {
5803
6004
  var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
5804
6005
  var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
5805
6006
  var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
5806
- function isRecord5(value) {
6007
+ function isRecord6(value) {
5807
6008
  return !!value && typeof value === "object" && !Array.isArray(value);
5808
6009
  }
5809
6010
  function nonBlank(value) {
@@ -5823,7 +6024,7 @@ function validateGatewayBindingsSegment(patch) {
5823
6024
  const ids = /* @__PURE__ */ new Set();
5824
6025
  raw.forEach((entry, index) => {
5825
6026
  const path2 = `bindings[${index}]`;
5826
- if (!isRecord5(entry)) {
6027
+ if (!isRecord6(entry)) {
5827
6028
  errors.push(`${path2} must be an object`);
5828
6029
  return;
5829
6030
  }
@@ -5852,12 +6053,12 @@ function validateGatewayBindingsSegment(patch) {
5852
6053
  } else if (entry.modelMappings.length > 100) {
5853
6054
  errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
5854
6055
  } else if (entry.modelMappings.some(
5855
- (mapping) => !isRecord5(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
6056
+ (mapping) => !isRecord6(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
5856
6057
  )) {
5857
6058
  errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
5858
6059
  }
5859
6060
  }
5860
- if (!isRecord5(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
6061
+ if (!isRecord6(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
5861
6062
  errors.push(`${path2}.target is invalid`);
5862
6063
  } else {
5863
6064
  if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
@@ -5872,7 +6073,7 @@ function validateGatewayBindingsSegment(patch) {
5872
6073
  }
5873
6074
  }
5874
6075
  if (entry.modelMap !== void 0) {
5875
- if (!isRecord5(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
6076
+ if (!isRecord6(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
5876
6077
  errors.push(`${path2}.modelMap must contain string values`);
5877
6078
  }
5878
6079
  }
@@ -6949,7 +7150,7 @@ function query(req) {
6949
7150
  }
6950
7151
  function allowanceProvider(value) {
6951
7152
  if (!value) return void 0;
6952
- return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" ? value : null;
7153
+ return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" || value === "gemini" ? value : null;
6953
7154
  }
6954
7155
  async function handleAccountAllowanceApi(req, res, method, rest, service) {
6955
7156
  if (!service) return writeError2(res, 501, "account allowance service is not available");
@@ -6964,7 +7165,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
6964
7165
  const pathProvider = rest.length >= 2 ? rest[0] : null;
6965
7166
  const providerId = allowanceProvider(pathProvider ?? params.get("providerId") ?? params.get("provider"));
6966
7167
  if (providerId === null) {
6967
- return writeError2(res, 400, "providerId must be claude, codex, kimi, opencodego, grok, or copilot");
7168
+ return writeError2(res, 400, "providerId must be claude, codex, kimi, opencodego, grok, copilot, or gemini");
6968
7169
  }
6969
7170
  const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
6970
7171
  const allowances = await service.list({ providerId, accountId });
@@ -7026,6 +7227,16 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7026
7227
  }
7027
7228
  return writeJson3(res, 200, { allowances: allowances2 });
7028
7229
  }
7230
+ if (requestedProvider === "gemini") {
7231
+ if (!service.refreshGemini) {
7232
+ return writeError2(res, 501, "gemini allowance refresh is not available");
7233
+ }
7234
+ const allowances2 = await service.refreshGemini(accountId);
7235
+ if (accountId && allowances2.length === 0) {
7236
+ return writeError2(res, 404, `Gemini account '${accountId}' not found`);
7237
+ }
7238
+ return writeJson3(res, 200, { allowances: allowances2 });
7239
+ }
7029
7240
  const allowances = await service.refreshClaude(accountId);
7030
7241
  if (accountId && allowances.length === 0) {
7031
7242
  return writeError2(res, 404, `Claude account '${accountId}' not found`);
@@ -7372,7 +7583,7 @@ async function handleDiscoverModels(res, id, cfg) {
7372
7583
  const headers = { Accept: "application/json" };
7373
7584
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
7374
7585
  Object.assign(headers, expandRowExtraHeaders(row));
7375
- const response = await (0, import_upstreamFetch9.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
7586
+ const response = await (0, import_upstreamFetch10.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
7376
7587
  if (!response.ok) {
7377
7588
  const text = await response.text().catch(() => "");
7378
7589
  let message = text.slice(0, 300);
@@ -7432,7 +7643,7 @@ async function handleTestModel(req, res, id, cfg) {
7432
7643
  Object.assign(headers, expandRowExtraHeaders(row));
7433
7644
  const startedAt = Date.now();
7434
7645
  try {
7435
- const response = await (0, import_upstreamFetch9.fetchUpstream)(
7646
+ const response = await (0, import_upstreamFetch10.fetchUpstream)(
7436
7647
  url,
7437
7648
  { method: "POST", headers, body: JSON.stringify(payload) },
7438
7649
  { providerId: "byo" }
@@ -8839,12 +9050,12 @@ async function handlePlayground(req, res, method, deps) {
8839
9050
  const payload = body["body"];
8840
9051
  const status = deps.outboundApiServer.getStatus();
8841
9052
  if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
8842
- const path2 = resolvePlaygroundPath(endpoint, isRecord6(payload) ? payload : {});
9053
+ const path2 = resolvePlaygroundPath(endpoint, isRecord7(payload) ? payload : {});
8843
9054
  if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
8844
9055
  const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
8845
9056
  await proxyToOutbound(res, status.port, path2, key, upstreamBody);
8846
9057
  }
8847
- function isRecord6(v) {
9058
+ function isRecord7(v) {
8848
9059
  return !!v && typeof v === "object" && !Array.isArray(v);
8849
9060
  }
8850
9061
  function proxyToOutbound(res, outboundPort, path2, key, body) {
@@ -8980,7 +9191,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
8980
9191
  }
8981
9192
 
8982
9193
  // src/admin/version.ts
8983
- var DAEMON_VERSION = true ? "0.4.0" : "0.0.0-dev";
9194
+ var DAEMON_VERSION = true ? "0.4.1" : "0.0.0-dev";
8984
9195
 
8985
9196
  // src/admin/AdminServer.ts
8986
9197
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -9400,7 +9611,7 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
9400
9611
 
9401
9612
  // src/allowance/ProviderKeyQuotaService.ts
9402
9613
  var import_core4 = require("@omnicross/core");
9403
- var import_upstreamFetch10 = require("@omnicross/core/pipeline/upstreamFetch");
9614
+ var import_upstreamFetch11 = require("@omnicross/core/pipeline/upstreamFetch");
9404
9615
 
9405
9616
  // src/allowance/ProviderKeyQuota.ts
9406
9617
  var MINUTE_MS3 = 6e4;
@@ -9429,11 +9640,11 @@ function isoInstant3(value) {
9429
9640
  }
9430
9641
  return void 0;
9431
9642
  }
9432
- function secondsUntil7(instant, now) {
9643
+ function secondsUntil8(instant, now) {
9433
9644
  if (!instant) return void 0;
9434
9645
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
9435
9646
  }
9436
- function isRecord7(value) {
9647
+ function isRecord8(value) {
9437
9648
  return !!value && typeof value === "object" && !Array.isArray(value);
9438
9649
  }
9439
9650
  function detectProviderKeyQuotaAdapter(baseUrl) {
@@ -9446,7 +9657,7 @@ function detectProviderKeyQuotaAdapter(baseUrl) {
9446
9657
  }
9447
9658
  const host = url.hostname.toLowerCase();
9448
9659
  const path2 = url.pathname.toLowerCase();
9449
- if ((host === "api.z.ai" || host === "open.bigmodel.cn") && path2.includes("/coding")) {
9660
+ if ((host === "api.z.ai" || host === "open.bigmodel.cn") && (path2.includes("/coding") || path2.includes("/anthropic"))) {
9450
9661
  return "zai";
9451
9662
  }
9452
9663
  if ((host === "api.minimax.io" || host === "api.minimaxi.com") && // Token Plan rides the plain openai `/v1` (chat completions) surface; the
@@ -9500,17 +9711,17 @@ function zaiWindowIdLabel(durationMs) {
9500
9711
  return { id: "quota", label: "Quota" };
9501
9712
  }
9502
9713
  function parseZaiQuotaPayload(payload, now) {
9503
- if (!isRecord7(payload)) return null;
9504
- const data = isRecord7(payload["data"]) ? payload["data"] : payload;
9714
+ if (!isRecord8(payload)) return null;
9715
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
9505
9716
  if (payload["success"] === false) return null;
9506
9717
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
9507
9718
  const byWindow = /* @__PURE__ */ new Map();
9508
9719
  for (const raw of limits) {
9509
- if (!isRecord7(raw)) continue;
9720
+ if (!isRecord8(raw)) continue;
9510
9721
  const item = raw;
9511
9722
  if (item.type === void 0) continue;
9512
9723
  const details = raw["usageDetails"];
9513
- if (Array.isArray(details) && details.some((d) => isRecord7(d) && d["modelCode"] === "zread")) {
9724
+ if (Array.isArray(details) && details.some((d) => isRecord8(d) && d["modelCode"] === "zread")) {
9514
9725
  continue;
9515
9726
  }
9516
9727
  const durationMs = zaiWindowDurationMs(item);
@@ -9529,7 +9740,7 @@ function parseZaiQuotaPayload(payload, now) {
9529
9740
  usedPercent,
9530
9741
  ...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS3) } : {},
9531
9742
  ...resetsAt !== void 0 ? { resetsAt } : {},
9532
- remainingSeconds: secondsUntil7(resetsAt, now),
9743
+ remainingSeconds: secondsUntil8(resetsAt, now),
9533
9744
  state: "fresh"
9534
9745
  };
9535
9746
  const existing = byWindow.get(id);
@@ -9543,7 +9754,7 @@ function parseZaiQuotaPayload(payload, now) {
9543
9754
  var MINIMAX_STATUS_EXHAUSTED = 2;
9544
9755
  var MINIMAX_SHARED_BUCKET = "general";
9545
9756
  function parseMiniMaxBucket(value) {
9546
- if (!isRecord7(value)) return null;
9757
+ if (!isRecord8(value)) return null;
9547
9758
  const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
9548
9759
  if (!modelName) return null;
9549
9760
  const instant = (v) => {
@@ -9570,14 +9781,14 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
9570
9781
  usedPercent,
9571
9782
  ...windowMinutes !== void 0 ? { windowMinutes } : {},
9572
9783
  ...resetsAt !== void 0 ? { resetsAt } : {},
9573
- remainingSeconds: secondsUntil7(resetsAt, now),
9784
+ remainingSeconds: secondsUntil8(resetsAt, now),
9574
9785
  state: usedPercent !== null ? "fresh" : "unavailable"
9575
9786
  };
9576
9787
  }
9577
9788
  function parseMiniMaxTokenPlanPayload(payload, now) {
9578
- if (!isRecord7(payload)) return null;
9789
+ if (!isRecord8(payload)) return null;
9579
9790
  const baseResp = payload["base_resp"];
9580
- if (!isRecord7(baseResp) || baseResp["status_code"] !== 0) return null;
9791
+ if (!isRecord8(baseResp) || baseResp["status_code"] !== 0) return null;
9581
9792
  const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
9582
9793
  let general = null;
9583
9794
  for (const raw of buckets) {
@@ -9610,11 +9821,11 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
9610
9821
  ];
9611
9822
  }
9612
9823
  function parseUmansUsagePayload(payload, now) {
9613
- if (!isRecord7(payload)) return null;
9614
- const limits = isRecord7(payload["limits"]) ? payload["limits"] : void 0;
9615
- const requests = limits && isRecord7(limits["requests"]) ? limits["requests"] : void 0;
9616
- const usage = isRecord7(payload["usage"]) ? payload["usage"] : void 0;
9617
- const window = isRecord7(payload["window"]) ? payload["window"] : void 0;
9824
+ if (!isRecord8(payload)) return null;
9825
+ const limits = isRecord8(payload["limits"]) ? payload["limits"] : void 0;
9826
+ const requests = limits && isRecord8(limits["requests"]) ? limits["requests"] : void 0;
9827
+ const usage = isRecord8(payload["usage"]) ? payload["usage"] : void 0;
9828
+ const window = isRecord8(payload["window"]) ? payload["window"] : void 0;
9618
9829
  const hardCap = finiteNumber5(requests?.["hard_cap"]);
9619
9830
  const softLimit = finiteNumber5(requests?.["limit"]);
9620
9831
  const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
@@ -9635,15 +9846,15 @@ function parseUmansUsagePayload(payload, now) {
9635
9846
  usedPercent,
9636
9847
  windowMinutes: 5 * 60,
9637
9848
  ...resetsAt !== void 0 ? { resetsAt } : {},
9638
- remainingSeconds: secondsUntil7(resetsAt, now),
9849
+ remainingSeconds: secondsUntil8(resetsAt, now),
9639
9850
  state: "fresh"
9640
9851
  }
9641
9852
  ];
9642
9853
  }
9643
9854
  function parseSyntheticQuotasPayload(payload, now) {
9644
- if (!isRecord7(payload)) return null;
9645
- const fiveHour = isRecord7(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
9646
- const weekly = isRecord7(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
9855
+ if (!isRecord8(payload)) return null;
9856
+ const fiveHour = isRecord8(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
9857
+ const weekly = isRecord8(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
9647
9858
  const windows = [];
9648
9859
  if (fiveHour) {
9649
9860
  const max = finiteNumber5(fiveHour["max"]);
@@ -9657,7 +9868,7 @@ function parseSyntheticQuotasPayload(payload, now) {
9657
9868
  usedPercent,
9658
9869
  windowMinutes: 5 * 60,
9659
9870
  ...resetsAt !== void 0 ? { resetsAt } : {},
9660
- remainingSeconds: secondsUntil7(resetsAt, now),
9871
+ remainingSeconds: secondsUntil8(resetsAt, now),
9661
9872
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9662
9873
  });
9663
9874
  }
@@ -9672,7 +9883,7 @@ function parseSyntheticQuotasPayload(payload, now) {
9672
9883
  usedPercent,
9673
9884
  windowMinutes: 7 * 24 * 60,
9674
9885
  ...resetsAt !== void 0 ? { resetsAt } : {},
9675
- remainingSeconds: secondsUntil7(resetsAt, now),
9886
+ remainingSeconds: secondsUntil8(resetsAt, now),
9676
9887
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9677
9888
  });
9678
9889
  }
@@ -9684,12 +9895,12 @@ var CLINE_WINDOW_CONFIG = {
9684
9895
  monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
9685
9896
  };
9686
9897
  function parseClinePassUsageLimitsPayload(payload, now) {
9687
- if (!isRecord7(payload)) return null;
9688
- const data = isRecord7(payload["data"]) ? payload["data"] : payload;
9898
+ if (!isRecord8(payload)) return null;
9899
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
9689
9900
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
9690
9901
  const windows = [];
9691
9902
  for (const raw of limits) {
9692
- if (!isRecord7(raw)) continue;
9903
+ if (!isRecord8(raw)) continue;
9693
9904
  const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
9694
9905
  if (!config) continue;
9695
9906
  const usedPercent = finitePercent4(raw["percentUsed"]);
@@ -9702,7 +9913,7 @@ function parseClinePassUsageLimitsPayload(payload, now) {
9702
9913
  usedPercent,
9703
9914
  windowMinutes: config.minutes,
9704
9915
  ...resetsAt !== void 0 ? { resetsAt } : {},
9705
- remainingSeconds: secondsUntil7(resetsAt, now),
9916
+ remainingSeconds: secondsUntil8(resetsAt, now),
9706
9917
  state: "fresh"
9707
9918
  });
9708
9919
  }
@@ -9741,7 +9952,7 @@ function rowKeyEntries(row) {
9741
9952
  return [];
9742
9953
  }
9743
9954
  var ProviderKeyQuotaService = class {
9744
- constructor(box, fetchImpl = (url, init) => (0, import_upstreamFetch10.fetchUpstream)(url, init, { redactBodies: true }), now = Date.now) {
9955
+ constructor(box, fetchImpl = (url, init) => (0, import_upstreamFetch11.fetchUpstream)(url, init, { redactBodies: true }), now = Date.now) {
9745
9956
  this.box = box;
9746
9957
  this.fetchImpl = fetchImpl;
9747
9958
  this.now = now;
@@ -16438,7 +16649,7 @@ var import_node_fs24 = require("fs");
16438
16649
  var import_node_path24 = require("path");
16439
16650
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
16440
16651
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
16441
- var import_upstreamFetch11 = require("@omnicross/core/pipeline/upstreamFetch");
16652
+ var import_upstreamFetch12 = require("@omnicross/core/pipeline/upstreamFetch");
16442
16653
  var import_SubscriptionIdentityStore2 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
16443
16654
  var import_subscriptions11 = require("@omnicross/subscriptions");
16444
16655
 
@@ -16588,7 +16799,7 @@ var JsonSubscriptionCredentialStore = class {
16588
16799
  * a plaintext token pair into `upstream-trace.jsonl`.
16589
16800
  */
16590
16801
  buildRefreshFetch(providerId, accountId) {
16591
- return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch11.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
16802
+ return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch12.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
16592
16803
  }
16593
16804
  /**
16594
16805
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -17318,7 +17529,7 @@ var JsonSubscriptionCredentialStore = class {
17318
17529
  };
17319
17530
 
17320
17531
  // src/AccountHealthProbeScheduler.ts
17321
- var import_upstreamFetch12 = require("@omnicross/core/pipeline/upstreamFetch");
17532
+ var import_upstreamFetch13 = require("@omnicross/core/pipeline/upstreamFetch");
17322
17533
 
17323
17534
  // src/probe/CodexGenerationProbe.ts
17324
17535
  var import_codexCliHeaders = require("@omnicross/core/provider-proxy/identity/codexCliHeaders");
@@ -17492,7 +17703,7 @@ var AccountHealthProbeScheduler = class {
17492
17703
  this.logger = logger;
17493
17704
  this.config = config;
17494
17705
  this.now = opts.now ?? Date.now;
17495
- this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch12.fetchUpstream;
17706
+ this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch13.fetchUpstream;
17496
17707
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
17497
17708
  this.planFor = opts.planFor ?? probePlanFor;
17498
17709
  }
@@ -19190,7 +19401,7 @@ var AuditWriter = class {
19190
19401
  var import_node_fs33 = require("fs");
19191
19402
  var import_node_crypto24 = require("crypto");
19192
19403
  var import_node_path33 = require("path");
19193
- var import_upstreamFetch13 = require("@omnicross/core/pipeline/upstreamFetch");
19404
+ var import_upstreamFetch14 = require("@omnicross/core/pipeline/upstreamFetch");
19194
19405
 
19195
19406
  // src/billing/billingFiles.ts
19196
19407
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -19213,7 +19424,7 @@ var BillingPublisher = class {
19213
19424
  constructor(billingDir, logger, opts = {}) {
19214
19425
  this.billingDir = billingDir;
19215
19426
  this.logger = logger;
19216
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch13.fetchUpstream)(url, init));
19427
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch14.fetchUpstream)(url, init));
19217
19428
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
19218
19429
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
19219
19430
  this.now = opts.now ?? Date.now;
@@ -19630,7 +19841,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
19630
19841
 
19631
19842
  // src/webhook/WebhookDispatcher.ts
19632
19843
  var import_node_crypto25 = require("crypto");
19633
- var import_upstreamFetch14 = require("@omnicross/core/pipeline/upstreamFetch");
19844
+ var import_upstreamFetch15 = require("@omnicross/core/pipeline/upstreamFetch");
19634
19845
  var WEBHOOK_MAX_ATTEMPTS = 3;
19635
19846
  var WEBHOOK_QUEUE_MAX = 1e3;
19636
19847
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -19650,7 +19861,7 @@ var WebhookDispatcher = class {
19650
19861
  sleep;
19651
19862
  now;
19652
19863
  constructor(opts = {}) {
19653
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch14.fetchUpstream)(url, init));
19864
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch15.fetchUpstream)(url, init));
19654
19865
  this.logger = opts.logger;
19655
19866
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
19656
19867
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -19879,12 +20090,12 @@ function buildDaemon(config, paths) {
19879
20090
  setSecretBox(secretBox3);
19880
20091
  setSecretBox2(secretBox3);
19881
20092
  const decryptedConfig = decryptConfigSecrets(config, secretBox3);
19882
- const accountAllowanceStore = new import_AccountAllowanceStore9.AccountAllowanceStore(
20093
+ const accountAllowanceStore = new import_AccountAllowanceStore10.AccountAllowanceStore(
19883
20094
  Date.now,
19884
20095
  void 0,
19885
20096
  new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
19886
20097
  );
19887
- (0, import_AccountAllowanceStore9.setSharedAccountAllowanceStore)(accountAllowanceStore);
20098
+ (0, import_AccountAllowanceStore10.setSharedAccountAllowanceStore)(accountAllowanceStore);
19888
20099
  (0, import_AccountAllowanceScheduling5.getSharedAccountAllowanceScheduling)().configure(
19889
20100
  (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
19890
20101
  );
@@ -19917,12 +20128,12 @@ function buildDaemon(config, paths) {
19917
20128
  );
19918
20129
  (0, import_subscriptions12.setSubscriptionProviderRegistry)(subscriptionRegistry);
19919
20130
  setServerProxyConfig(decryptedConfig.server?.proxy);
19920
- (0, import_upstreamFetch15.setUpstreamProxyResolver)(
20131
+ (0, import_upstreamFetch16.setUpstreamProxyResolver)(
19921
20132
  createUpstreamProxyResolver({
19922
20133
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
19923
20134
  })
19924
20135
  );
19925
- (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)((0, import_GeminiCodeAssistProjectResolver.getGeminiCodeAssistProjectResolver)());
20136
+ (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)((0, import_GeminiCodeAssistProjectResolver2.getGeminiCodeAssistProjectResolver)());
19926
20137
  const autoDisableStore = new AutoDisableStore();
19927
20138
  const providerKeyQuotaService = new ProviderKeyQuotaService(secretBox3);
19928
20139
  const apiKeyPool = new import_ApiKeyPoolService.ApiKeyPoolService(
@@ -19941,7 +20152,7 @@ function buildDaemon(config, paths) {
19941
20152
  const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
19942
20153
  // Catalog egress follows the same global/env proxy policy as every other
19943
20154
  // daemon upstream call; no provider/account override applies here.
19944
- fetchImpl: ((input, init) => (0, import_upstreamFetch15.fetchUpstream)(String(input), init ?? {}))
20155
+ fetchImpl: ((input, init) => (0, import_upstreamFetch16.fetchUpstream)(String(input), init ?? {}))
19945
20156
  });
19946
20157
  const pricingRefreshScheduler = new PricingRefreshScheduler(
19947
20158
  pricingEngine,
@@ -20226,7 +20437,7 @@ function buildDaemon(config, paths) {
20226
20437
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
20227
20438
  // excluded from the upstream trace, so a failing login left no evidence.
20228
20439
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
20229
- oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch15.fetchUpstream)(url, init, { providerId, redactBodies: true }),
20440
+ oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch16.fetchUpstream)(url, init, { providerId, redactBodies: true }),
20230
20441
  subscriptionAccountAppender: credentialStore,
20231
20442
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
20232
20443
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -20299,7 +20510,7 @@ function buildDaemon(config, paths) {
20299
20510
  });
20300
20511
  const webhookDispatcher = new WebhookDispatcher({
20301
20512
  logger,
20302
- fetchImpl: (url, init) => (0, import_upstreamFetch15.fetchUpstream)(url, init)
20513
+ fetchImpl: (url, init) => (0, import_upstreamFetch16.fetchUpstream)(url, init)
20303
20514
  });
20304
20515
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
20305
20516
  const auditWriter = new AuditWriter(auditDir, logger);
@@ -20381,7 +20592,7 @@ function resetDaemonSingletonsForTests() {
20381
20592
  (0, import_subscriptionRegistryPort.setSubscriptionRegistryForOutbound)(null);
20382
20593
  (0, import_subscriptions12.setSubscriptionProviderRegistry)(null);
20383
20594
  (0, import_subscriptions12.setSubscriptionAccountService)(null);
20384
- (0, import_upstreamFetch15.setUpstreamProxyResolver)(null);
20595
+ (0, import_upstreamFetch16.setUpstreamProxyResolver)(null);
20385
20596
  setServerProxyConfig(void 0);
20386
20597
  (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)(null);
20387
20598
  setSecretBox(null);
@@ -20390,7 +20601,7 @@ function resetDaemonSingletonsForTests() {
20390
20601
  resetAuditRuntimeForTests();
20391
20602
  resetBillingRuntimeForTests();
20392
20603
  (0, import_SubscriptionIdentityStore3.__resetSharedIdentityStoreForTests)();
20393
- (0, import_AccountAllowanceStore9.__resetSharedAccountAllowanceStoreForTests)();
20604
+ (0, import_AccountAllowanceStore10.__resetSharedAccountAllowanceStoreForTests)();
20394
20605
  (0, import_AccountAllowanceScheduling5.__resetSharedAccountAllowanceSchedulingForTests)();
20395
20606
  (0, import_usage2.__resetSharedUsageThroughputTrackerForTests)();
20396
20607
  }