@omnicross/daemon 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1128 -271
- package/dist/cli.js +1076 -211
- package/dist/index.cjs +921 -228
- package/dist/index.d.cts +186 -10
- package/dist/index.d.ts +186 -10
- package/dist/index.js +889 -189
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -18,16 +18,18 @@ 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
|
|
21
|
+
AccountAllowanceStore as AccountAllowanceStore10,
|
|
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
|
|
28
|
+
import { fetchUpstream as fetchUpstream16, 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
|
+
import { setAntigravitySandboxFailover } from "@omnicross/core/transformer/transformers/antigravityFailover";
|
|
32
|
+
import { setOpenCodeGoUserAgent } from "@omnicross/core/provider-proxy/identity/openCodeGoHeaders";
|
|
31
33
|
import {
|
|
32
34
|
__resetProviderProxyForTests,
|
|
33
35
|
createNativeResponsesHostedImageIngress,
|
|
@@ -411,7 +413,7 @@ function handleCopilotOAuthStatus(sessionId, deps) {
|
|
|
411
413
|
|
|
412
414
|
// src/allowance/AccountAllowanceService.ts
|
|
413
415
|
import {
|
|
414
|
-
getSharedAccountAllowanceStore as
|
|
416
|
+
getSharedAccountAllowanceStore as getSharedAccountAllowanceStore9
|
|
415
417
|
} from "@omnicross/core/pipeline/AccountAllowanceStore";
|
|
416
418
|
import {
|
|
417
419
|
getSharedAccountAllowanceScheduling
|
|
@@ -1801,11 +1803,328 @@ var GeminiAllowanceCollector = class {
|
|
|
1801
1803
|
}
|
|
1802
1804
|
};
|
|
1803
1805
|
|
|
1804
|
-
// src/allowance/
|
|
1806
|
+
// src/allowance/AntigravityAllowanceCollector.ts
|
|
1807
|
+
import { ANTIGRAVITY_CODE_ASSIST_ENDPOINT } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
|
|
1808
|
+
import {
|
|
1809
|
+
ANTIGRAVITY_COUNTER_TO_MODEL_FAMILY,
|
|
1810
|
+
antigravityCounterFamiliesForBucketId
|
|
1811
|
+
} from "@omnicross/core/pipeline/antigravityQuotaFamily";
|
|
1805
1812
|
import {
|
|
1806
1813
|
getSharedAccountAllowanceStore as getSharedAccountAllowanceStore7
|
|
1807
1814
|
} from "@omnicross/core/pipeline/AccountAllowanceStore";
|
|
1808
1815
|
import { fetchUpstream as fetchUpstream7 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
1816
|
+
import { getAntigravityUserAgent } from "@omnicross/core/transformer/transformers/antigravityIdentity";
|
|
1817
|
+
var ANTIGRAVITY_ALLOWANCE_CACHE_MS = 5 * 6e4;
|
|
1818
|
+
var RETRIEVE_USER_QUOTA_SUMMARY_PATH = "/v1internal:retrieveUserQuotaSummary";
|
|
1819
|
+
var FETCH_AVAILABLE_MODELS_PATH = "/v1internal:fetchAvailableModels";
|
|
1820
|
+
var ANTIGRAVITY_DISCOVERY_DENYLIST = /* @__PURE__ */ new Set([
|
|
1821
|
+
"chat_20706",
|
|
1822
|
+
"chat_23310",
|
|
1823
|
+
"gemini-2.5-pro"
|
|
1824
|
+
]);
|
|
1825
|
+
function isRecord5(value) {
|
|
1826
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1827
|
+
}
|
|
1828
|
+
function secondsUntil7(instant, now) {
|
|
1829
|
+
if (!instant) return void 0;
|
|
1830
|
+
return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
|
|
1831
|
+
}
|
|
1832
|
+
var WINDOW_LABELS = {
|
|
1833
|
+
"five-hour": "5 Hour",
|
|
1834
|
+
weekly: "Weekly",
|
|
1835
|
+
daily: "Daily"
|
|
1836
|
+
};
|
|
1837
|
+
function classifyWindowId(...sources) {
|
|
1838
|
+
for (const source of sources) {
|
|
1839
|
+
if (!source) continue;
|
|
1840
|
+
const text = source.toLowerCase();
|
|
1841
|
+
if (text.includes("week") || text.includes("7d") || /7[\s_-]*day/.test(text)) return "weekly";
|
|
1842
|
+
if (text.includes("5h") || text.includes("five hour") || /5[\s_-]*hour/.test(text)) return "five-hour";
|
|
1843
|
+
if (text.includes("day") || text.includes("daily") || text.includes("24h")) return "daily";
|
|
1844
|
+
}
|
|
1845
|
+
return void 0;
|
|
1846
|
+
}
|
|
1847
|
+
function inferWindowFromReset(resetsAt, now) {
|
|
1848
|
+
if (resetsAt !== void 0 && Date.parse(resetsAt) - now > 24 * 60 * 60 * 1e3) return "weekly";
|
|
1849
|
+
return "daily";
|
|
1850
|
+
}
|
|
1851
|
+
function clampFraction(value) {
|
|
1852
|
+
if (value === void 0 || !Number.isFinite(value)) return void 0;
|
|
1853
|
+
return Math.min(1, Math.max(0, value));
|
|
1854
|
+
}
|
|
1855
|
+
function usedPercentFromFraction(fraction) {
|
|
1856
|
+
const clamped = clampFraction(fraction);
|
|
1857
|
+
if (clamped === void 0) return null;
|
|
1858
|
+
return Math.round((1 - clamped) * 1e3) / 10;
|
|
1859
|
+
}
|
|
1860
|
+
function toResetsAt(resetTime) {
|
|
1861
|
+
if (!resetTime || !Number.isFinite(Date.parse(resetTime))) return void 0;
|
|
1862
|
+
return new Date(Date.parse(resetTime)).toISOString();
|
|
1863
|
+
}
|
|
1864
|
+
function parseAntigravityQuotaSummary(payload, now) {
|
|
1865
|
+
if (!isRecord5(payload)) return null;
|
|
1866
|
+
const groups = Array.isArray(payload["groups"]) ? payload["groups"] : [];
|
|
1867
|
+
const topBuckets = Array.isArray(payload["buckets"]) ? payload["buckets"] : [];
|
|
1868
|
+
const hasGrouped = groups.some((group) => Array.isArray(group.buckets) && group.buckets.length > 0);
|
|
1869
|
+
if (!hasGrouped && topBuckets.length === 0) return null;
|
|
1870
|
+
const windows = /* @__PURE__ */ new Map();
|
|
1871
|
+
const addBucket = (bucket, groupName) => {
|
|
1872
|
+
const families = antigravityCounterFamiliesForBucketId(bucket.bucketId, groupName);
|
|
1873
|
+
if (families.length === 0) return;
|
|
1874
|
+
const resetsAt = toResetsAt(bucket.resetTime);
|
|
1875
|
+
const windowId = classifyWindowId(bucket.window, bucket.displayName, bucket.bucketId) ?? (resetsAt !== void 0 ? inferWindowFromReset(resetsAt, now) : void 0);
|
|
1876
|
+
if (windowId === void 0) return;
|
|
1877
|
+
const usedPercent = usedPercentFromFraction(bucket.remainingFraction) ?? (bucket.disabled === true || bucket.resetTime ? bucket.disabled === true ? 100 : null : null);
|
|
1878
|
+
for (const family of families) {
|
|
1879
|
+
const id = `antigravity:${family}:${windowId}`;
|
|
1880
|
+
const candidate = {
|
|
1881
|
+
id,
|
|
1882
|
+
label: `${WINDOW_LABELS[windowId]} (${family})`,
|
|
1883
|
+
scope: "model-family",
|
|
1884
|
+
// The window carries the MODEL family (gemini/claude/gpt-oss) — the
|
|
1885
|
+
// scheduling gate compares it against the requested model's family.
|
|
1886
|
+
modelFamily: ANTIGRAVITY_COUNTER_TO_MODEL_FAMILY[family],
|
|
1887
|
+
usedPercent,
|
|
1888
|
+
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
1889
|
+
remainingSeconds: secondsUntil7(resetsAt, now),
|
|
1890
|
+
state: "fresh",
|
|
1891
|
+
...bucket.disabled === true ? { disabled: true } : {}
|
|
1892
|
+
};
|
|
1893
|
+
const existing = windows.get(id);
|
|
1894
|
+
if (!existing || candidate.disabled === true || existing.disabled !== true && (candidate.usedPercent ?? -1) > (existing.usedPercent ?? -1)) {
|
|
1895
|
+
windows.set(id, candidate);
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
};
|
|
1899
|
+
if (hasGrouped) {
|
|
1900
|
+
for (const group of groups) {
|
|
1901
|
+
for (const bucket of group.buckets ?? []) addBucket(bucket, group.displayName);
|
|
1902
|
+
}
|
|
1903
|
+
} else {
|
|
1904
|
+
for (const bucket of topBuckets) addBucket(bucket);
|
|
1905
|
+
}
|
|
1906
|
+
const result = [...windows.values()];
|
|
1907
|
+
return result.length > 0 ? result : null;
|
|
1908
|
+
}
|
|
1909
|
+
function legacyQuotaInfos(model) {
|
|
1910
|
+
const out = [];
|
|
1911
|
+
const source = {
|
|
1912
|
+
...model.apiProvider ? { apiProvider: model.apiProvider } : {},
|
|
1913
|
+
...model.modelProvider ? { modelProvider: model.modelProvider } : {}
|
|
1914
|
+
};
|
|
1915
|
+
const add = (value, windowDefault) => {
|
|
1916
|
+
if (!value) return;
|
|
1917
|
+
const list = Array.isArray(value) ? value : [value];
|
|
1918
|
+
for (const info of list) {
|
|
1919
|
+
out.push({ ...source, ...windowDefault ? { windowId: windowDefault } : {}, ...info });
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
add(model.quotaInfo);
|
|
1923
|
+
add(model.quotaInfos);
|
|
1924
|
+
add(model.dailyQuotaInfo, "daily");
|
|
1925
|
+
add(model.dailyQuotaInfos, "daily");
|
|
1926
|
+
add(model.weeklyQuotaInfo, "weekly");
|
|
1927
|
+
add(model.weeklyQuotaInfos, "weekly");
|
|
1928
|
+
return out;
|
|
1929
|
+
}
|
|
1930
|
+
function legacyCounterFamily(info) {
|
|
1931
|
+
switch (info.modelProvider ?? info.apiProvider) {
|
|
1932
|
+
case "MODEL_PROVIDER_ANTHROPIC":
|
|
1933
|
+
case "API_PROVIDER_ANTHROPIC_VERTEX":
|
|
1934
|
+
return "anthropic";
|
|
1935
|
+
case "MODEL_PROVIDER_GOOGLE":
|
|
1936
|
+
case "API_PROVIDER_GOOGLE_GEMINI":
|
|
1937
|
+
return "google";
|
|
1938
|
+
case "MODEL_PROVIDER_OPENAI":
|
|
1939
|
+
case "API_PROVIDER_OPENAI_VERTEX":
|
|
1940
|
+
return "openai";
|
|
1941
|
+
default:
|
|
1942
|
+
return void 0;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
function parseAntigravityLegacyQuota(payload, now) {
|
|
1946
|
+
if (!isRecord5(payload)) return null;
|
|
1947
|
+
const models = payload["models"];
|
|
1948
|
+
if (!isRecord5(models)) return null;
|
|
1949
|
+
const windows = /* @__PURE__ */ new Map();
|
|
1950
|
+
for (const info of Object.values(models).flatMap(legacyQuotaInfos)) {
|
|
1951
|
+
const family = legacyCounterFamily(info);
|
|
1952
|
+
if (!family) continue;
|
|
1953
|
+
const resetsAt = toResetsAt(info.resetTime);
|
|
1954
|
+
const windowId = classifyWindowId(info.windowId, info.windowLabel) ?? (resetsAt !== void 0 ? inferWindowFromReset(resetsAt, now) : void 0);
|
|
1955
|
+
if (windowId === void 0) continue;
|
|
1956
|
+
const id = `antigravity:${family}:${windowId}`;
|
|
1957
|
+
const candidate = {
|
|
1958
|
+
id,
|
|
1959
|
+
label: `${WINDOW_LABELS[windowId]} (${family})`,
|
|
1960
|
+
scope: "model-family",
|
|
1961
|
+
modelFamily: ANTIGRAVITY_COUNTER_TO_MODEL_FAMILY[family],
|
|
1962
|
+
usedPercent: usedPercentFromFraction(info.remainingFraction),
|
|
1963
|
+
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
1964
|
+
remainingSeconds: secondsUntil7(resetsAt, now),
|
|
1965
|
+
state: "fresh"
|
|
1966
|
+
};
|
|
1967
|
+
const existing = windows.get(id);
|
|
1968
|
+
if (!existing || (candidate.usedPercent ?? -1) > (existing.usedPercent ?? -1)) {
|
|
1969
|
+
windows.set(id, candidate);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
const result = [...windows.values()];
|
|
1973
|
+
return result.length > 0 ? result : null;
|
|
1974
|
+
}
|
|
1975
|
+
var AntigravityAllowanceCollector = class {
|
|
1976
|
+
constructor(credentials, store = getSharedAccountAllowanceStore7(), fetchImpl = (url, init, accountId) => fetchUpstream7(url, init, { providerId: "antigravity", accountId, redactBodies: true }), now = Date.now) {
|
|
1977
|
+
this.credentials = credentials;
|
|
1978
|
+
this.store = store;
|
|
1979
|
+
this.fetchImpl = fetchImpl;
|
|
1980
|
+
this.now = now;
|
|
1981
|
+
}
|
|
1982
|
+
credentials;
|
|
1983
|
+
store;
|
|
1984
|
+
fetchImpl;
|
|
1985
|
+
now;
|
|
1986
|
+
inFlight = /* @__PURE__ */ new Map();
|
|
1987
|
+
async collectMany(accounts, options = {}) {
|
|
1988
|
+
const settled = await Promise.allSettled(
|
|
1989
|
+
accounts.map((account) => this.collect(account, options))
|
|
1990
|
+
);
|
|
1991
|
+
return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
|
|
1992
|
+
}
|
|
1993
|
+
collect(account, options = {}) {
|
|
1994
|
+
const now = this.now();
|
|
1995
|
+
if (account.tokens.authMethod !== "oauth") {
|
|
1996
|
+
const existing = this.store.get("antigravity", account.id, now);
|
|
1997
|
+
if (existing?.windows.every((window) => window.state === "unsupported")) {
|
|
1998
|
+
return Promise.resolve(existing);
|
|
1999
|
+
}
|
|
2000
|
+
const snapshot = this.unsupportedSnapshot(account.id, now);
|
|
2001
|
+
this.store.set(snapshot);
|
|
2002
|
+
return Promise.resolve(snapshot);
|
|
2003
|
+
}
|
|
2004
|
+
const cached = this.store.get("antigravity", account.id, now);
|
|
2005
|
+
if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
|
|
2006
|
+
return Promise.resolve(cached);
|
|
2007
|
+
}
|
|
2008
|
+
const running = this.inFlight.get(account.id);
|
|
2009
|
+
if (running) return running;
|
|
2010
|
+
const promise = this.fetchAccount(account.id).catch(() => this.failureSnapshot(account.id, "antigravity_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
|
|
2011
|
+
this.inFlight.set(account.id, promise);
|
|
2012
|
+
return promise;
|
|
2013
|
+
}
|
|
2014
|
+
isCacheValid(snapshot, now, refreshAheadMs) {
|
|
2015
|
+
if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
|
|
2016
|
+
const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
|
|
2017
|
+
const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
|
|
2018
|
+
return Number.isFinite(expiresAt) && expiresAt > now + ahead;
|
|
2019
|
+
}
|
|
2020
|
+
async fetchAccount(accountId) {
|
|
2021
|
+
let accessToken = await this.credentials.getAccessTokenForAccount("antigravity", accountId);
|
|
2022
|
+
if (!accessToken) return this.failureSnapshot(accountId, "antigravity_usage_token_unavailable", this.now());
|
|
2023
|
+
let response = await this.request(accountId, accessToken, RETRIEVE_USER_QUOTA_SUMMARY_PATH, {
|
|
2024
|
+
project: void 0
|
|
2025
|
+
});
|
|
2026
|
+
if (response.status === 401 || response.status === 403) {
|
|
2027
|
+
const refreshed = await this.credentials.refreshAccountToken("antigravity", accountId);
|
|
2028
|
+
if (!refreshed) return this.failureSnapshot(accountId, "antigravity_usage_unauthorized", this.now());
|
|
2029
|
+
accessToken = await this.credentials.getAccessTokenForAccount("antigravity", accountId);
|
|
2030
|
+
if (!accessToken) return this.failureSnapshot(accountId, "antigravity_usage_token_unavailable", this.now());
|
|
2031
|
+
response = await this.request(accountId, accessToken, RETRIEVE_USER_QUOTA_SUMMARY_PATH, {
|
|
2032
|
+
project: void 0
|
|
2033
|
+
});
|
|
2034
|
+
if (response.status === 401 || response.status === 403) {
|
|
2035
|
+
return this.failureSnapshot(accountId, "antigravity_usage_unauthorized", this.now());
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
if (response.ok) {
|
|
2039
|
+
const payload = await response.json().catch(() => null);
|
|
2040
|
+
const windows = parseAntigravityQuotaSummary(payload, this.now());
|
|
2041
|
+
if (windows) {
|
|
2042
|
+
const snapshot2 = this.snapshot(accountId, windows);
|
|
2043
|
+
this.store.set(snapshot2);
|
|
2044
|
+
return snapshot2;
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
const legacy = await this.request(accountId, accessToken, FETCH_AVAILABLE_MODELS_PATH, {});
|
|
2048
|
+
if (!legacy.ok) {
|
|
2049
|
+
return this.failureSnapshot(accountId, "antigravity_usage_http_error", this.now());
|
|
2050
|
+
}
|
|
2051
|
+
const legacyPayload = await legacy.json().catch(() => null);
|
|
2052
|
+
const legacyWindows = parseAntigravityLegacyQuota(legacyPayload, this.now());
|
|
2053
|
+
if (!legacyWindows) {
|
|
2054
|
+
return this.failureSnapshot(accountId, "antigravity_usage_invalid_response", this.now());
|
|
2055
|
+
}
|
|
2056
|
+
const snapshot = this.snapshot(accountId, legacyWindows);
|
|
2057
|
+
this.store.set(snapshot);
|
|
2058
|
+
return snapshot;
|
|
2059
|
+
}
|
|
2060
|
+
/** One upstream round-trip with the antigravity/hub masquerade UA. */
|
|
2061
|
+
request(accountId, accessToken, path2, body) {
|
|
2062
|
+
return this.fetchImpl(`${ANTIGRAVITY_CODE_ASSIST_ENDPOINT}${path2}`, {
|
|
2063
|
+
method: "POST",
|
|
2064
|
+
headers: {
|
|
2065
|
+
Authorization: `Bearer ${accessToken}`,
|
|
2066
|
+
Accept: "application/json",
|
|
2067
|
+
"Content-Type": "application/json",
|
|
2068
|
+
"User-Agent": getAntigravityUserAgent()
|
|
2069
|
+
},
|
|
2070
|
+
body: JSON.stringify(body),
|
|
2071
|
+
signal: AbortSignal.timeout(15e3)
|
|
2072
|
+
}, accountId);
|
|
2073
|
+
}
|
|
2074
|
+
snapshot(accountId, windows, now = this.now()) {
|
|
2075
|
+
return {
|
|
2076
|
+
providerId: "antigravity",
|
|
2077
|
+
accountId,
|
|
2078
|
+
source: "oauth-usage-api",
|
|
2079
|
+
observedAt: new Date(now).toISOString(),
|
|
2080
|
+
expiresAt: new Date(now + ANTIGRAVITY_ALLOWANCE_CACHE_MS).toISOString(),
|
|
2081
|
+
windows
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
failureSnapshot(accountId, code, now) {
|
|
2085
|
+
const existing = this.store.get("antigravity", accountId, now);
|
|
2086
|
+
const snapshot = existing ? {
|
|
2087
|
+
...existing,
|
|
2088
|
+
expiresAt: new Date(now + ANTIGRAVITY_ALLOWANCE_CACHE_MS).toISOString(),
|
|
2089
|
+
windows: existing.windows.map((window) => ({
|
|
2090
|
+
...window,
|
|
2091
|
+
state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt || window.disabled ? "stale" : "unavailable"
|
|
2092
|
+
})),
|
|
2093
|
+
lastErrorCode: code
|
|
2094
|
+
} : {
|
|
2095
|
+
providerId: "antigravity",
|
|
2096
|
+
accountId,
|
|
2097
|
+
source: "oauth-usage-api",
|
|
2098
|
+
observedAt: new Date(now).toISOString(),
|
|
2099
|
+
expiresAt: new Date(now + ANTIGRAVITY_ALLOWANCE_CACHE_MS).toISOString(),
|
|
2100
|
+
windows: [
|
|
2101
|
+
{ id: "antigravity-quota", label: "Antigravity quota", scope: "all", usedPercent: null, state: "unavailable" }
|
|
2102
|
+
],
|
|
2103
|
+
lastErrorCode: code
|
|
2104
|
+
};
|
|
2105
|
+
this.store.set(snapshot);
|
|
2106
|
+
return snapshot;
|
|
2107
|
+
}
|
|
2108
|
+
unsupportedSnapshot(accountId, now) {
|
|
2109
|
+
return {
|
|
2110
|
+
providerId: "antigravity",
|
|
2111
|
+
accountId,
|
|
2112
|
+
source: "oauth-usage-api",
|
|
2113
|
+
observedAt: new Date(now).toISOString(),
|
|
2114
|
+
windows: [
|
|
2115
|
+
{ id: "antigravity-quota", label: "Antigravity quota", scope: "all", usedPercent: null, state: "unsupported" }
|
|
2116
|
+
],
|
|
2117
|
+
lastErrorCode: "antigravity_usage_unsupported_auth"
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
|
|
2122
|
+
// src/allowance/OpenCodeGoAllowanceCollector.ts
|
|
2123
|
+
import {
|
|
2124
|
+
getSharedAccountAllowanceStore as getSharedAccountAllowanceStore8
|
|
2125
|
+
} from "@omnicross/core/pipeline/AccountAllowanceStore";
|
|
2126
|
+
import { fetchUpstream as fetchUpstream8 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
2127
|
+
import { getOpenCodeGoUserAgent } from "@omnicross/core/provider-proxy/identity/openCodeGoHeaders";
|
|
1809
2128
|
import { normalizeOpenCodeGoBaseUrl } from "@omnicross/subscriptions";
|
|
1810
2129
|
var OPENCODEGO_ALLOWANCE_CACHE_MS = 5 * 6e4;
|
|
1811
2130
|
var OPENCODEGO_DEFAULT_GO_BASE = "https://opencode.ai/zen/go";
|
|
@@ -1819,7 +2138,7 @@ function isoInstant2(value) {
|
|
|
1819
2138
|
const time = Date.parse(value);
|
|
1820
2139
|
return Number.isFinite(time) ? new Date(time).toISOString() : void 0;
|
|
1821
2140
|
}
|
|
1822
|
-
function
|
|
2141
|
+
function secondsUntil8(instant, now) {
|
|
1823
2142
|
if (!instant) return void 0;
|
|
1824
2143
|
return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
|
|
1825
2144
|
}
|
|
@@ -1834,12 +2153,12 @@ function windowFromPayload3(id, label, minutes, payload, now) {
|
|
|
1834
2153
|
usedPercent,
|
|
1835
2154
|
windowMinutes: minutes,
|
|
1836
2155
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
1837
|
-
remainingSeconds:
|
|
2156
|
+
remainingSeconds: secondsUntil8(resetsAt, now),
|
|
1838
2157
|
state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
|
|
1839
2158
|
};
|
|
1840
2159
|
}
|
|
1841
2160
|
var OpenCodeGoAllowanceCollector = class {
|
|
1842
|
-
constructor(credentials, store =
|
|
2161
|
+
constructor(credentials, store = getSharedAccountAllowanceStore8(), fetchImpl = (url, init, accountId) => fetchUpstream8(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
|
|
1843
2162
|
this.credentials = credentials;
|
|
1844
2163
|
this.store = store;
|
|
1845
2164
|
this.fetchImpl = fetchImpl;
|
|
@@ -1872,7 +2191,14 @@ var OpenCodeGoAllowanceCollector = class {
|
|
|
1872
2191
|
const base = account.tokens.baseUrl ? normalizeOpenCodeGoBaseUrl(account.tokens.baseUrl) : OPENCODEGO_DEFAULT_GO_BASE;
|
|
1873
2192
|
const response = await this.fetchImpl(`${base}/v1/usage`, {
|
|
1874
2193
|
method: "GET",
|
|
1875
|
-
|
|
2194
|
+
// opencodego-egress-identity: the background poll identifies itself with
|
|
2195
|
+
// the same configured/default UA the relay carries (no session header —
|
|
2196
|
+
// a poll has no conversation).
|
|
2197
|
+
headers: {
|
|
2198
|
+
Authorization: `Bearer ${apiKey}`,
|
|
2199
|
+
Accept: "application/json",
|
|
2200
|
+
"User-Agent": getOpenCodeGoUserAgent()
|
|
2201
|
+
},
|
|
1876
2202
|
signal: AbortSignal.timeout(15e3)
|
|
1877
2203
|
}, account.id);
|
|
1878
2204
|
if (response.status === 401 || response.status === 403) {
|
|
@@ -1944,7 +2270,7 @@ function codexUnavailable(accountId, now) {
|
|
|
1944
2270
|
};
|
|
1945
2271
|
}
|
|
1946
2272
|
var AccountAllowanceService = class {
|
|
1947
|
-
constructor(credentials, store =
|
|
2273
|
+
constructor(credentials, store = getSharedAccountAllowanceStore9(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, geminiCollector, antigravityCollector, now = Date.now) {
|
|
1948
2274
|
this.credentials = credentials;
|
|
1949
2275
|
this.store = store;
|
|
1950
2276
|
this.now = now;
|
|
@@ -1955,6 +2281,7 @@ var AccountAllowanceService = class {
|
|
|
1955
2281
|
this.grokCollector = grokCollector ?? new GrokAllowanceCollector(credentials, store);
|
|
1956
2282
|
this.copilotCollector = copilotCollector ?? new CopilotAllowanceCollector(credentials, store);
|
|
1957
2283
|
this.geminiCollector = geminiCollector ?? new GeminiAllowanceCollector(credentials, store);
|
|
2284
|
+
this.antigravityCollector = antigravityCollector ?? new AntigravityAllowanceCollector(credentials, store);
|
|
1958
2285
|
}
|
|
1959
2286
|
credentials;
|
|
1960
2287
|
store;
|
|
@@ -1966,6 +2293,7 @@ var AccountAllowanceService = class {
|
|
|
1966
2293
|
copilotCollector;
|
|
1967
2294
|
opencodegoCollector;
|
|
1968
2295
|
geminiCollector;
|
|
2296
|
+
antigravityCollector;
|
|
1969
2297
|
/**
|
|
1970
2298
|
* Read all/filtered snapshots. Claude's and Codex's five-minute caches are
|
|
1971
2299
|
* refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
|
|
@@ -2014,6 +2342,11 @@ var AccountAllowanceService = class {
|
|
|
2014
2342
|
(account) => !filter.accountId || account.id === filter.accountId
|
|
2015
2343
|
);
|
|
2016
2344
|
if (wantsGemini) await this.geminiCollector.collectMany(geminiAccounts);
|
|
2345
|
+
const wantsAntigravity = !filter.providerId || filter.providerId === "antigravity";
|
|
2346
|
+
const antigravityAccounts = (config.antigravityAccounts ?? []).filter(
|
|
2347
|
+
(account) => !filter.accountId || account.id === filter.accountId
|
|
2348
|
+
);
|
|
2349
|
+
if (wantsAntigravity) await this.antigravityCollector.collectMany(antigravityAccounts);
|
|
2017
2350
|
const known = /* @__PURE__ */ new Set();
|
|
2018
2351
|
if (wantsClaude) for (const account of claudeAccounts) known.add(`claude\0${account.id}`);
|
|
2019
2352
|
if (wantsCodex) for (const account of codexAccounts) known.add(`codex\0${account.id}`);
|
|
@@ -2022,6 +2355,7 @@ var AccountAllowanceService = class {
|
|
|
2022
2355
|
if (wantsGrok) for (const account of grokAccounts) known.add(`grok\0${account.id}`);
|
|
2023
2356
|
if (wantsCopilot) for (const account of copilotAccounts) known.add(`copilot\0${account.id}`);
|
|
2024
2357
|
if (wantsGemini) for (const account of geminiAccounts) known.add(`gemini\0${account.id}`);
|
|
2358
|
+
if (wantsAntigravity) for (const account of antigravityAccounts) known.add(`antigravity\0${account.id}`);
|
|
2025
2359
|
return this.store.list(filter).filter((snapshot) => known.has(`${snapshot.providerId}\0${snapshot.accountId}`));
|
|
2026
2360
|
}
|
|
2027
2361
|
knownAccounts(config) {
|
|
@@ -2032,7 +2366,8 @@ var AccountAllowanceService = class {
|
|
|
2032
2366
|
...(config.opencodegoAccounts ?? []).map((account) => ({ providerId: "opencodego", accountId: account.id })),
|
|
2033
2367
|
...(config.grokAccounts ?? []).map((account) => ({ providerId: "grok", accountId: account.id })),
|
|
2034
2368
|
...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id })),
|
|
2035
|
-
...(config.geminiAccounts ?? []).map((account) => ({ providerId: "gemini", accountId: account.id }))
|
|
2369
|
+
...(config.geminiAccounts ?? []).map((account) => ({ providerId: "gemini", accountId: account.id })),
|
|
2370
|
+
...(config.antigravityAccounts ?? []).map((account) => ({ providerId: "antigravity", accountId: account.id }))
|
|
2036
2371
|
];
|
|
2037
2372
|
}
|
|
2038
2373
|
/** Force-refresh Claude usage for one account or every stored Claude account. */
|
|
@@ -2102,6 +2437,15 @@ var AccountAllowanceService = class {
|
|
|
2102
2437
|
);
|
|
2103
2438
|
return this.geminiCollector.collectMany(accounts, { force: true });
|
|
2104
2439
|
}
|
|
2440
|
+
/** Force-refresh Antigravity usage (quotaSummary dual buckets) for one/all accounts. */
|
|
2441
|
+
async refreshAntigravity(accountId) {
|
|
2442
|
+
const config = await this.credentials.getFullConfig();
|
|
2443
|
+
this.store.pruneToKnownAccounts(this.knownAccounts(config));
|
|
2444
|
+
const accounts = (config.antigravityAccounts ?? []).filter(
|
|
2445
|
+
(account) => !accountId || account.id === accountId
|
|
2446
|
+
);
|
|
2447
|
+
return this.antigravityCollector.collectMany(accounts, { force: true });
|
|
2448
|
+
}
|
|
2105
2449
|
/**
|
|
2106
2450
|
* Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
|
|
2107
2451
|
* collectors preserve their cache + per-account in-flight coalescing; a tick
|
|
@@ -2119,6 +2463,7 @@ var AccountAllowanceService = class {
|
|
|
2119
2463
|
await this.grokCollector.collectMany(config.grokAccounts ?? [], { refreshAheadMs });
|
|
2120
2464
|
await this.copilotCollector.collectMany(config.copilotAccounts ?? [], { refreshAheadMs });
|
|
2121
2465
|
await this.geminiCollector.collectMany(config.geminiAccounts ?? [], { refreshAheadMs });
|
|
2466
|
+
await this.antigravityCollector.collectMany(config.antigravityAccounts ?? [], { refreshAheadMs });
|
|
2122
2467
|
}
|
|
2123
2468
|
/** Remove a cache row as soon as an account is deleted by the admin path. */
|
|
2124
2469
|
removeAccountSnapshot(providerId, accountId) {
|
|
@@ -2555,7 +2900,7 @@ import {
|
|
|
2555
2900
|
} from "@omnicross/contracts/image-generation-types";
|
|
2556
2901
|
import { getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling2 } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
|
|
2557
2902
|
import { getSharedAccountHealth } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
|
|
2558
|
-
import { fetchUpstream as
|
|
2903
|
+
import { fetchUpstream as fetchUpstream10 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
2559
2904
|
import { mergeExtraHeaders } from "@omnicross/core";
|
|
2560
2905
|
|
|
2561
2906
|
// src/image-generation/imagesConfigValidation.ts
|
|
@@ -3172,7 +3517,11 @@ var TOKEN_FIELDS = {
|
|
|
3172
3517
|
claude: ["accessToken", "refreshToken"],
|
|
3173
3518
|
codex: ["accessToken", "refreshToken", "idToken"],
|
|
3174
3519
|
gemini: ["accessToken", "refreshToken"],
|
|
3175
|
-
opencodego: ["apiKey"]
|
|
3520
|
+
opencodego: ["apiKey"],
|
|
3521
|
+
kimi: ["accessToken", "refreshToken"],
|
|
3522
|
+
grok: ["accessToken", "refreshToken"],
|
|
3523
|
+
copilot: ["accessToken", "refreshToken"],
|
|
3524
|
+
antigravity: ["accessToken", "refreshToken"]
|
|
3176
3525
|
};
|
|
3177
3526
|
function transformTokenBlock(block, fields, fn) {
|
|
3178
3527
|
const next = { ...block };
|
|
@@ -3244,6 +3593,19 @@ function resolveAdminConfig(admin) {
|
|
|
3244
3593
|
token: typeof admin?.token === "string" && admin.token.length > 0 ? admin.token : void 0
|
|
3245
3594
|
};
|
|
3246
3595
|
}
|
|
3596
|
+
function validateAntigravity(raw) {
|
|
3597
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
3598
|
+
const a = raw;
|
|
3599
|
+
if (typeof a["sandboxFailover"] !== "boolean") return void 0;
|
|
3600
|
+
return { sandboxFailover: a["sandboxFailover"] };
|
|
3601
|
+
}
|
|
3602
|
+
function validateOpenCodeGo(raw) {
|
|
3603
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
3604
|
+
const o = raw;
|
|
3605
|
+
const ua = o["userAgent"];
|
|
3606
|
+
if (typeof ua !== "string" || ua.trim().length === 0) return void 0;
|
|
3607
|
+
return { userAgent: ua.trim() };
|
|
3608
|
+
}
|
|
3247
3609
|
function validateUsage(raw) {
|
|
3248
3610
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
3249
3611
|
const u = raw;
|
|
@@ -3537,7 +3899,9 @@ function validateConfig(raw) {
|
|
|
3537
3899
|
const admin = validateAdmin(obj["admin"]);
|
|
3538
3900
|
const logging = validateLogging(obj["logging"]);
|
|
3539
3901
|
const usage = validateUsage(obj["usage"]);
|
|
3540
|
-
|
|
3902
|
+
const antigravity = validateAntigravity(obj["antigravity"]);
|
|
3903
|
+
const opencodego = validateOpenCodeGo(obj["opencodego"]);
|
|
3904
|
+
return { providers, server, admin, logging, usage, antigravity, opencodego };
|
|
3541
3905
|
}
|
|
3542
3906
|
var secretBox = null;
|
|
3543
3907
|
function setSecretBox(box) {
|
|
@@ -4642,6 +5006,167 @@ function createUpstreamProxyResolver(src = {}) {
|
|
|
4642
5006
|
};
|
|
4643
5007
|
}
|
|
4644
5008
|
|
|
5009
|
+
// src/admin/accountsAntigravityOAuth.ts
|
|
5010
|
+
import { getAntigravityProjectResolver } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
|
|
5011
|
+
import { antigravityOAuth } from "@omnicross/subscriptions";
|
|
5012
|
+
function err5(status, message) {
|
|
5013
|
+
return { status, body: { error: { type: "admin_api_error", message } } };
|
|
5014
|
+
}
|
|
5015
|
+
var DEFAULT_ANTIGRAVITY_OAUTH_TTL_MS = 10 * 6e4;
|
|
5016
|
+
function handleAntigravityOAuthStart(deps) {
|
|
5017
|
+
if (deps.antigravitySessions.isBusy()) {
|
|
5018
|
+
return err5(
|
|
5019
|
+
409,
|
|
5020
|
+
"an antigravity sign-in is already in progress (loopback 127.0.0.1:51121 is held) \u2014 finish it in the browser or wait for it to time out"
|
|
5021
|
+
);
|
|
5022
|
+
}
|
|
5023
|
+
const { authUrl, state } = antigravityOAuth.generateAuthParams();
|
|
5024
|
+
const { sessionId, signal } = deps.antigravitySessions.begin();
|
|
5025
|
+
void runAntigravityLoopback(sessionId, state, signal, deps);
|
|
5026
|
+
return { status: 200, body: { authUrl, sessionId } };
|
|
5027
|
+
}
|
|
5028
|
+
async function runAntigravityLoopback(sessionId, state, signal, deps) {
|
|
5029
|
+
const isPending = () => !signal.aborted && deps.antigravitySessions.get(sessionId)?.status === "pending";
|
|
5030
|
+
try {
|
|
5031
|
+
const code = await deps.antigravityAwaitLoopback(state, void 0, signal);
|
|
5032
|
+
if (!isPending()) return;
|
|
5033
|
+
const exchangeFetch = deps.oauthExchangeFetch("antigravity");
|
|
5034
|
+
const result = await antigravityOAuth.exchangeCodeForTokens(code, exchangeFetch);
|
|
5035
|
+
if (!isPending()) return;
|
|
5036
|
+
const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
|
|
5037
|
+
const email = await antigravityOAuth.fetchUserEmail(result.accessToken, exchangeFetch);
|
|
5038
|
+
if (!isPending()) return;
|
|
5039
|
+
const projectId = await getAntigravityProjectResolver().resolveProject(result.accessToken);
|
|
5040
|
+
if (!isPending()) return;
|
|
5041
|
+
const block = {
|
|
5042
|
+
authMethod: "oauth",
|
|
5043
|
+
status: "authorized",
|
|
5044
|
+
accessToken: result.accessToken,
|
|
5045
|
+
refreshToken: result.refreshToken,
|
|
5046
|
+
expiresAt,
|
|
5047
|
+
...email ? { email } : {},
|
|
5048
|
+
...projectId ? { projectId } : {},
|
|
5049
|
+
lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5050
|
+
};
|
|
5051
|
+
await deps.subscriptionAccountAppender.appendProviderAccount("antigravity", block);
|
|
5052
|
+
if (isPending()) deps.antigravitySessions.settle(sessionId, "done");
|
|
5053
|
+
} catch (e) {
|
|
5054
|
+
if (!isPending()) return;
|
|
5055
|
+
const reason = e instanceof Error ? e.message : "antigravity sign-in failed";
|
|
5056
|
+
deps.antigravitySessions.settle(sessionId, "error", reason);
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
function handleAntigravityOAuthCancel(sessionId, deps) {
|
|
5060
|
+
if (!deps.antigravitySessions.cancel(sessionId)) {
|
|
5061
|
+
return err5(404, "unknown or expired antigravity sign-in session");
|
|
5062
|
+
}
|
|
5063
|
+
return { status: 200, body: { ok: true } };
|
|
5064
|
+
}
|
|
5065
|
+
function handleAntigravityOAuthStatus(sessionId, deps) {
|
|
5066
|
+
const s = deps.antigravitySessions.get(sessionId);
|
|
5067
|
+
if (!s) return err5(404, "unknown or expired antigravity sign-in session");
|
|
5068
|
+
return { status: 200, body: { state: s.status, ...s.error ? { message: s.error } : {} } };
|
|
5069
|
+
}
|
|
5070
|
+
|
|
5071
|
+
// src/allowance/AntigravityModelDiscovery.ts
|
|
5072
|
+
import { lookupCanonicalCapabilities } from "@omnicross/contracts/canonical-models";
|
|
5073
|
+
import { SUBSCRIPTION_MODEL_CATALOG } from "@omnicross/contracts/subscription-model-catalog";
|
|
5074
|
+
import { ANTIGRAVITY_CODE_ASSIST_ENDPOINT as ANTIGRAVITY_CODE_ASSIST_ENDPOINT2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
|
|
5075
|
+
import { fetchUpstream as fetchUpstream9 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
5076
|
+
import { getAntigravityUserAgent as getAntigravityUserAgent2 } from "@omnicross/core/transformer/transformers/antigravityIdentity";
|
|
5077
|
+
function isRecord6(value) {
|
|
5078
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5079
|
+
}
|
|
5080
|
+
function optionalString(value) {
|
|
5081
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
5082
|
+
}
|
|
5083
|
+
function optionalNumber(value) {
|
|
5084
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
5085
|
+
}
|
|
5086
|
+
function optionalBoolean(value) {
|
|
5087
|
+
return typeof value === "boolean" ? value : void 0;
|
|
5088
|
+
}
|
|
5089
|
+
function parseAntigravityAvailableModels(payload) {
|
|
5090
|
+
if (!isRecord6(payload)) return [];
|
|
5091
|
+
const models = payload["models"];
|
|
5092
|
+
if (!isRecord6(models)) return [];
|
|
5093
|
+
const out = [];
|
|
5094
|
+
for (const [id, raw] of Object.entries(models)) {
|
|
5095
|
+
if (ANTIGRAVITY_DISCOVERY_DENYLIST.has(id)) continue;
|
|
5096
|
+
if (!isRecord6(raw)) continue;
|
|
5097
|
+
if (raw["isInternal"] === true) continue;
|
|
5098
|
+
out.push({
|
|
5099
|
+
id,
|
|
5100
|
+
...optionalString(raw["displayName"]) ? { displayName: optionalString(raw["displayName"]) } : {},
|
|
5101
|
+
...optionalBoolean(raw["supportsImages"]) !== void 0 ? { supportsImages: optionalBoolean(raw["supportsImages"]) } : {},
|
|
5102
|
+
...optionalBoolean(raw["supportsThinking"]) !== void 0 ? { supportsThinking: optionalBoolean(raw["supportsThinking"]) } : {},
|
|
5103
|
+
...optionalNumber(raw["thinkingBudget"]) !== void 0 ? { thinkingBudget: optionalNumber(raw["thinkingBudget"]) } : {},
|
|
5104
|
+
...optionalNumber(raw["maxTokens"]) !== void 0 ? { maxTokens: optionalNumber(raw["maxTokens"]) } : {},
|
|
5105
|
+
...optionalNumber(raw["maxOutputTokens"]) !== void 0 ? { maxOutputTokens: optionalNumber(raw["maxOutputTokens"]) } : {}
|
|
5106
|
+
});
|
|
5107
|
+
}
|
|
5108
|
+
out.sort((a, b) => a.id.localeCompare(b.id));
|
|
5109
|
+
return out;
|
|
5110
|
+
}
|
|
5111
|
+
function mergeAntigravityCatalog(discovered, log = (line) => console.warn(line), staticIds = SUBSCRIPTION_MODEL_CATALOG.antigravity) {
|
|
5112
|
+
const entries = staticIds.map((id) => {
|
|
5113
|
+
const capabilities = lookupCanonicalCapabilities(id);
|
|
5114
|
+
return {
|
|
5115
|
+
id,
|
|
5116
|
+
origin: "static",
|
|
5117
|
+
displayName: id,
|
|
5118
|
+
...capabilities?.vision !== void 0 ? { supportsImages: capabilities.vision } : {},
|
|
5119
|
+
...capabilities?.reasoning !== void 0 ? { supportsThinking: capabilities.reasoning } : {},
|
|
5120
|
+
...capabilities?.thinkingTokenLimit ? { thinkingBudget: capabilities.thinkingTokenLimit.max } : {},
|
|
5121
|
+
// Discovery calls the context window maxTokens, not the output ceiling.
|
|
5122
|
+
...capabilities?.contextLength !== void 0 ? { maxTokens: capabilities.contextLength } : {},
|
|
5123
|
+
...capabilities?.maxTokens !== void 0 ? { maxOutputTokens: capabilities.maxTokens } : {}
|
|
5124
|
+
};
|
|
5125
|
+
});
|
|
5126
|
+
const staticSet = new Set(staticIds);
|
|
5127
|
+
for (const model of discovered) {
|
|
5128
|
+
if (staticSet.has(model.id)) {
|
|
5129
|
+
log(
|
|
5130
|
+
`[AntigravityModelDiscovery] dynamic model '${model.id}' conflicts with the static catalog \u2014 static entry kept`
|
|
5131
|
+
);
|
|
5132
|
+
continue;
|
|
5133
|
+
}
|
|
5134
|
+
entries.push({ ...model, origin: "discovered" });
|
|
5135
|
+
}
|
|
5136
|
+
return entries;
|
|
5137
|
+
}
|
|
5138
|
+
async function fetchAntigravityAvailableModels(accessToken, fetchImpl = (url, init) => fetchUpstream9(url, init, { providerId: "antigravity", redactBodies: true })) {
|
|
5139
|
+
let response;
|
|
5140
|
+
try {
|
|
5141
|
+
response = await fetchImpl(`${ANTIGRAVITY_CODE_ASSIST_ENDPOINT2}/v1internal:fetchAvailableModels`, {
|
|
5142
|
+
method: "POST",
|
|
5143
|
+
headers: {
|
|
5144
|
+
Authorization: `Bearer ${accessToken}`,
|
|
5145
|
+
Accept: "application/json",
|
|
5146
|
+
"Content-Type": "application/json",
|
|
5147
|
+
"User-Agent": getAntigravityUserAgent2()
|
|
5148
|
+
},
|
|
5149
|
+
body: JSON.stringify({}),
|
|
5150
|
+
signal: AbortSignal.timeout(15e3)
|
|
5151
|
+
});
|
|
5152
|
+
} catch {
|
|
5153
|
+
return null;
|
|
5154
|
+
}
|
|
5155
|
+
if (!response.ok) return null;
|
|
5156
|
+
const payload = await response.json().catch(() => null);
|
|
5157
|
+
if (!isRecord6(payload) || !isRecord6(payload["models"])) return null;
|
|
5158
|
+
return parseAntigravityAvailableModels(payload);
|
|
5159
|
+
}
|
|
5160
|
+
async function handleAntigravityModelsRoute(deps) {
|
|
5161
|
+
const accessToken = await deps.resolveAntigravityAccessToken().catch(() => null);
|
|
5162
|
+
const discovered = accessToken ? await fetchAntigravityAvailableModels(accessToken, deps.fetchImpl) : null;
|
|
5163
|
+
const models = mergeAntigravityCatalog(discovered ?? []);
|
|
5164
|
+
return {
|
|
5165
|
+
status: 200,
|
|
5166
|
+
body: { models, discovered: discovered !== null }
|
|
5167
|
+
};
|
|
5168
|
+
}
|
|
5169
|
+
|
|
4645
5170
|
// src/admin/accountsOAuth.ts
|
|
4646
5171
|
import { claudeOAuth, geminiOAuth } from "@omnicross/subscriptions";
|
|
4647
5172
|
|
|
@@ -4653,7 +5178,8 @@ var VALID_PROVIDER_IDS = [
|
|
|
4653
5178
|
"opencodego",
|
|
4654
5179
|
"kimi",
|
|
4655
5180
|
"grok",
|
|
4656
|
-
"copilot"
|
|
5181
|
+
"copilot",
|
|
5182
|
+
"antigravity"
|
|
4657
5183
|
];
|
|
4658
5184
|
function asSubscriptionProviderId(id) {
|
|
4659
5185
|
return VALID_PROVIDER_IDS.includes(id) ? id : null;
|
|
@@ -4835,7 +5361,7 @@ function validateCopilot(body) {
|
|
|
4835
5361
|
]);
|
|
4836
5362
|
return out;
|
|
4837
5363
|
}
|
|
4838
|
-
function
|
|
5364
|
+
function validateOpenCodeGo2(body) {
|
|
4839
5365
|
const authMethod = str(body["authMethod"]);
|
|
4840
5366
|
const status = str(body["status"]);
|
|
4841
5367
|
if (authMethod !== "manual") return null;
|
|
@@ -4869,7 +5395,7 @@ function validateTokenBody(providerId, body) {
|
|
|
4869
5395
|
case "gemini":
|
|
4870
5396
|
return validateGemini(body);
|
|
4871
5397
|
case "opencodego":
|
|
4872
|
-
return
|
|
5398
|
+
return validateOpenCodeGo2(body);
|
|
4873
5399
|
case "kimi":
|
|
4874
5400
|
return validateKimi(body);
|
|
4875
5401
|
case "grok":
|
|
@@ -4905,12 +5431,12 @@ async function statusEntryFor(reader, providerId) {
|
|
|
4905
5431
|
|
|
4906
5432
|
// src/admin/accountsOAuth.ts
|
|
4907
5433
|
var OAUTH_HTTP_PROVIDERS = /* @__PURE__ */ new Set(["claude", "gemini"]);
|
|
4908
|
-
function
|
|
5434
|
+
function err6(status, message) {
|
|
4909
5435
|
return { status, body: { error: { type: "admin_api_error", message } } };
|
|
4910
5436
|
}
|
|
4911
5437
|
function handleOAuthStart(providerId, deps) {
|
|
4912
5438
|
if (!OAUTH_HTTP_PROVIDERS.has(providerId)) {
|
|
4913
|
-
return
|
|
5439
|
+
return err6(400, `oauth not available for provider '${providerId}'`);
|
|
4914
5440
|
}
|
|
4915
5441
|
const flow = providerId === "claude" ? claudeOAuth : geminiOAuth;
|
|
4916
5442
|
const { authUrl, codeVerifier, state } = flow.generateAuthParams();
|
|
@@ -4919,23 +5445,23 @@ function handleOAuthStart(providerId, deps) {
|
|
|
4919
5445
|
}
|
|
4920
5446
|
async function handleOAuthComplete(providerId, body, deps) {
|
|
4921
5447
|
if (!OAUTH_HTTP_PROVIDERS.has(providerId)) {
|
|
4922
|
-
return
|
|
5448
|
+
return err6(400, `oauth not available for provider '${providerId}'`);
|
|
4923
5449
|
}
|
|
4924
5450
|
const sessionId = typeof body["sessionId"] === "string" ? body["sessionId"] : "";
|
|
4925
5451
|
const rawCode = typeof body["code"] === "string" ? body["code"] : "";
|
|
4926
|
-
if (!sessionId) return
|
|
4927
|
-
if (!rawCode) return
|
|
5452
|
+
if (!sessionId) return err6(400, "oauth complete requires { sessionId }");
|
|
5453
|
+
if (!rawCode) return err6(400, "oauth complete requires { code }");
|
|
4928
5454
|
const session = deps.oauthSessions.peek(sessionId);
|
|
4929
|
-
if (!session) return
|
|
5455
|
+
if (!session) return err6(410, "oauth session is unknown, expired, or already used");
|
|
4930
5456
|
if (session.providerId !== providerId) {
|
|
4931
|
-
return
|
|
5457
|
+
return err6(400, `oauth session does not match provider '${providerId}'`);
|
|
4932
5458
|
}
|
|
4933
5459
|
let code = rawCode.trim();
|
|
4934
5460
|
if (providerId === "claude") {
|
|
4935
5461
|
const [splitCode, pastedState] = code.split("#");
|
|
4936
|
-
if (!splitCode) return
|
|
5462
|
+
if (!splitCode) return err6(400, "no authorization code was provided");
|
|
4937
5463
|
if (pastedState && pastedState !== session.state) {
|
|
4938
|
-
return
|
|
5464
|
+
return err6(400, "oauth state did not match (possible CSRF) \u2014 aborting");
|
|
4939
5465
|
}
|
|
4940
5466
|
code = splitCode;
|
|
4941
5467
|
}
|
|
@@ -4945,7 +5471,7 @@ async function handleOAuthComplete(providerId, body, deps) {
|
|
|
4945
5471
|
block = providerId === "claude" ? await exchangeClaude(code, session.codeVerifier, session.state, exchangeFetch) : await exchangeGemini(code, session.codeVerifier, exchangeFetch);
|
|
4946
5472
|
} catch (exchangeError) {
|
|
4947
5473
|
const reason = exchangeError instanceof Error ? exchangeError.message : "token exchange failed";
|
|
4948
|
-
return
|
|
5474
|
+
return err6(502, `oauth token exchange failed for '${providerId}': ${reason}`);
|
|
4949
5475
|
}
|
|
4950
5476
|
deps.oauthSessions.consume(sessionId);
|
|
4951
5477
|
const label = typeof body["label"] === "string" && body["label"].trim() ? body["label"].trim() : void 0;
|
|
@@ -5283,8 +5809,8 @@ function errBody(message) {
|
|
|
5283
5809
|
return { error: { type: "admin_api_error", message } };
|
|
5284
5810
|
}
|
|
5285
5811
|
var defaultCommandRunner = (command) => new Promise((resolve10) => {
|
|
5286
|
-
exec(command, { timeout: 18e4 }, (
|
|
5287
|
-
if (
|
|
5812
|
+
exec(command, { timeout: 18e4 }, (err9, _stdout, stderr) => {
|
|
5813
|
+
if (err9) resolve10({ ok: false, error: stderr.trim() || err9.message });
|
|
5288
5814
|
else resolve10({ ok: true });
|
|
5289
5815
|
});
|
|
5290
5816
|
});
|
|
@@ -5330,8 +5856,8 @@ async function handleCliLaunch(cli, body, ctx) {
|
|
|
5330
5856
|
providerId: typeof body["providerId"] === "string" ? body["providerId"] : void 0,
|
|
5331
5857
|
model: typeof body["model"] === "string" ? body["model"] : void 0
|
|
5332
5858
|
});
|
|
5333
|
-
} catch (
|
|
5334
|
-
return { status: 400, body: errBody(
|
|
5859
|
+
} catch (err9) {
|
|
5860
|
+
return { status: 400, body: errBody(err9 instanceof Error ? err9.message : "no launch target") };
|
|
5335
5861
|
}
|
|
5336
5862
|
const id = randomUUID2();
|
|
5337
5863
|
let leaseId2;
|
|
@@ -5359,9 +5885,9 @@ async function handleCliLaunch(cli, body, ctx) {
|
|
|
5359
5885
|
} else {
|
|
5360
5886
|
launch = await buildLaunchEnv(cli, ctx.llmConfig, target);
|
|
5361
5887
|
}
|
|
5362
|
-
} catch (
|
|
5363
|
-
const status =
|
|
5364
|
-
return { status, body: errBody(
|
|
5888
|
+
} catch (err9) {
|
|
5889
|
+
const status = err9 instanceof RouteLeaseError2 ? err9.status : 400;
|
|
5890
|
+
return { status, body: errBody(err9 instanceof Error ? err9.message : "failed to build launch env") };
|
|
5365
5891
|
}
|
|
5366
5892
|
const cwd = typeof body["cwd"] === "string" && body["cwd"].trim() ? body["cwd"].trim() : void 0;
|
|
5367
5893
|
const opener = ctx.opener ?? defaultTerminalOpener;
|
|
@@ -5389,9 +5915,9 @@ async function handleCliLaunch(cli, body, ctx) {
|
|
|
5389
5915
|
onFailure: onSessionEnd
|
|
5390
5916
|
});
|
|
5391
5917
|
if (cleanup) openerCleanup = cleanup;
|
|
5392
|
-
} catch (
|
|
5918
|
+
} catch (err9) {
|
|
5393
5919
|
onSessionEnd();
|
|
5394
|
-
return { status: 500, body: errBody(
|
|
5920
|
+
return { status: 500, body: errBody(err9 instanceof Error ? err9.message : "failed to open terminal") };
|
|
5395
5921
|
}
|
|
5396
5922
|
if (ended) {
|
|
5397
5923
|
openerCleanup?.();
|
|
@@ -5940,7 +6466,7 @@ async function handleSearchQuery(req, res, deps) {
|
|
|
5940
6466
|
// src/admin/searchAdminView.ts
|
|
5941
6467
|
var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
|
|
5942
6468
|
var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
|
|
5943
|
-
function
|
|
6469
|
+
function isRecord7(value) {
|
|
5944
6470
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5945
6471
|
}
|
|
5946
6472
|
function redactSearchServerConfig(search) {
|
|
@@ -5990,13 +6516,13 @@ function resolveSecretField(entry, field, stored) {
|
|
|
5990
6516
|
else delete entry[field];
|
|
5991
6517
|
}
|
|
5992
6518
|
function preserveSearchSecrets(incoming, current) {
|
|
5993
|
-
if (!
|
|
6519
|
+
if (!isRecord7(incoming)) return incoming;
|
|
5994
6520
|
const section = { ...incoming };
|
|
5995
6521
|
const providersValue = section["providers"];
|
|
5996
|
-
if (!
|
|
6522
|
+
if (!isRecord7(providersValue)) return section;
|
|
5997
6523
|
const providers = {};
|
|
5998
6524
|
for (const [id, entryValue] of Object.entries(providersValue)) {
|
|
5999
|
-
if (!
|
|
6525
|
+
if (!isRecord7(entryValue)) {
|
|
6000
6526
|
providers[id] = entryValue;
|
|
6001
6527
|
continue;
|
|
6002
6528
|
}
|
|
@@ -6074,7 +6600,7 @@ function parseKeyPolicyBody(body) {
|
|
|
6074
6600
|
var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
|
|
6075
6601
|
var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
|
|
6076
6602
|
var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
|
|
6077
|
-
function
|
|
6603
|
+
function isRecord8(value) {
|
|
6078
6604
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
6079
6605
|
}
|
|
6080
6606
|
function nonBlank(value) {
|
|
@@ -6094,7 +6620,7 @@ function validateGatewayBindingsSegment(patch) {
|
|
|
6094
6620
|
const ids = /* @__PURE__ */ new Set();
|
|
6095
6621
|
raw.forEach((entry, index) => {
|
|
6096
6622
|
const path2 = `bindings[${index}]`;
|
|
6097
|
-
if (!
|
|
6623
|
+
if (!isRecord8(entry)) {
|
|
6098
6624
|
errors.push(`${path2} must be an object`);
|
|
6099
6625
|
return;
|
|
6100
6626
|
}
|
|
@@ -6123,12 +6649,12 @@ function validateGatewayBindingsSegment(patch) {
|
|
|
6123
6649
|
} else if (entry.modelMappings.length > 100) {
|
|
6124
6650
|
errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
|
|
6125
6651
|
} else if (entry.modelMappings.some(
|
|
6126
|
-
(mapping) => !
|
|
6652
|
+
(mapping) => !isRecord8(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
|
|
6127
6653
|
)) {
|
|
6128
6654
|
errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
|
|
6129
6655
|
}
|
|
6130
6656
|
}
|
|
6131
|
-
if (!
|
|
6657
|
+
if (!isRecord8(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
|
|
6132
6658
|
errors.push(`${path2}.target is invalid`);
|
|
6133
6659
|
} else {
|
|
6134
6660
|
if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
|
|
@@ -6143,7 +6669,7 @@ function validateGatewayBindingsSegment(patch) {
|
|
|
6143
6669
|
}
|
|
6144
6670
|
}
|
|
6145
6671
|
if (entry.modelMap !== void 0) {
|
|
6146
|
-
if (!
|
|
6672
|
+
if (!isRecord8(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
|
|
6147
6673
|
errors.push(`${path2}.modelMap must contain string values`);
|
|
6148
6674
|
}
|
|
6149
6675
|
}
|
|
@@ -6456,7 +6982,12 @@ var PROVIDER_KEYS = {
|
|
|
6456
6982
|
},
|
|
6457
6983
|
kimi: { block: "kimi", accounts: "kimiAccounts", active: "activeKimiAccountId" },
|
|
6458
6984
|
grok: { block: "grok", accounts: "grokAccounts", active: "activeGrokAccountId" },
|
|
6459
|
-
copilot: { block: "copilot", accounts: "copilotAccounts", active: "activeCopilotAccountId" }
|
|
6985
|
+
copilot: { block: "copilot", accounts: "copilotAccounts", active: "activeCopilotAccountId" },
|
|
6986
|
+
antigravity: {
|
|
6987
|
+
block: "antigravity",
|
|
6988
|
+
accounts: "antigravityAccounts",
|
|
6989
|
+
active: "activeAntigravityAccountId"
|
|
6990
|
+
}
|
|
6460
6991
|
};
|
|
6461
6992
|
function clone(value) {
|
|
6462
6993
|
return JSON.parse(JSON.stringify(value));
|
|
@@ -6978,7 +7509,7 @@ async function applyImport(packString, passphrase, mode, deps, parseProviderInpu
|
|
|
6978
7509
|
}
|
|
6979
7510
|
|
|
6980
7511
|
// src/admin/adminMigration.ts
|
|
6981
|
-
function
|
|
7512
|
+
function err7(status, message) {
|
|
6982
7513
|
return { status, body: { error: { type: "admin_api_error", message } } };
|
|
6983
7514
|
}
|
|
6984
7515
|
async function handleExport(body, deps) {
|
|
@@ -6988,30 +7519,30 @@ async function handleExport(body, deps) {
|
|
|
6988
7519
|
return { status: 200, body: { pack, version: BUNDLE_VERSION } };
|
|
6989
7520
|
} catch (error) {
|
|
6990
7521
|
if (error instanceof WeakPassphraseError) {
|
|
6991
|
-
return
|
|
7522
|
+
return err7(400, error.message);
|
|
6992
7523
|
}
|
|
6993
|
-
return
|
|
7524
|
+
return err7(500, "failed to build the migration pack");
|
|
6994
7525
|
}
|
|
6995
7526
|
}
|
|
6996
7527
|
async function handleImport(body, deps) {
|
|
6997
7528
|
const blob = typeof body["blob"] === "string" ? body["blob"] : "";
|
|
6998
7529
|
const passphrase = typeof body["passphrase"] === "string" ? body["passphrase"] : "";
|
|
6999
7530
|
const mode = body["mode"] === "overwrite" ? "overwrite" : "merge";
|
|
7000
|
-
if (!blob) return
|
|
7531
|
+
if (!blob) return err7(400, "import requires { blob }");
|
|
7001
7532
|
try {
|
|
7002
7533
|
const counts = await applyImport(blob, passphrase, mode, deps, deps.parseProviderInput);
|
|
7003
7534
|
return { status: 200, body: counts };
|
|
7004
7535
|
} catch (error) {
|
|
7005
7536
|
if (error instanceof WeakPassphraseError) {
|
|
7006
|
-
return
|
|
7537
|
+
return err7(400, error.message);
|
|
7007
7538
|
}
|
|
7008
|
-
return
|
|
7539
|
+
return err7(400, error instanceof Error ? error.message : "import failed");
|
|
7009
7540
|
}
|
|
7010
7541
|
}
|
|
7011
7542
|
|
|
7012
7543
|
// src/admin/usagePricing.ts
|
|
7013
7544
|
import { getSharedUsageThroughputTracker } from "@omnicross/core/usage";
|
|
7014
|
-
var
|
|
7545
|
+
var err8 = (status, message) => ({
|
|
7015
7546
|
status,
|
|
7016
7547
|
body: { error: { type: "admin_api_error", message } }
|
|
7017
7548
|
});
|
|
@@ -7024,7 +7555,7 @@ function parseRange(query2) {
|
|
|
7024
7555
|
const startTs = parseFiniteInt(query2.get("startTs"));
|
|
7025
7556
|
const endTs = parseFiniteInt(query2.get("endTs"));
|
|
7026
7557
|
if (startTs === null || endTs === null) {
|
|
7027
|
-
return
|
|
7558
|
+
return err8(400, "startTs and endTs are required finite-integer unix-millis query params");
|
|
7028
7559
|
}
|
|
7029
7560
|
return { startTs, endTs };
|
|
7030
7561
|
}
|
|
@@ -7049,14 +7580,14 @@ async function handleUsageGet(view, query2, deps) {
|
|
|
7049
7580
|
case "timeseries": {
|
|
7050
7581
|
const bucket = query2.get("bucket");
|
|
7051
7582
|
if (bucket !== "hour" && bucket !== "day" && bucket !== "month") {
|
|
7052
|
-
return
|
|
7583
|
+
return err8(400, "bucket must be one of 'hour', 'day', 'month'");
|
|
7053
7584
|
}
|
|
7054
7585
|
const now = Date.now();
|
|
7055
7586
|
const clamped = { startTs: range.startTs, endTs: Math.min(range.endTs, now) };
|
|
7056
7587
|
if (clamped.startTs < clamped.endTs) {
|
|
7057
7588
|
const projected = Math.ceil((clamped.endTs - clamped.startTs) / BUCKET_SPAN_MS[bucket]) + 1;
|
|
7058
7589
|
if (projected > MAX_TIMESERIES_BUCKETS) {
|
|
7059
|
-
return
|
|
7590
|
+
return err8(
|
|
7060
7591
|
400,
|
|
7061
7592
|
`requested range projects ~${projected} '${bucket}' buckets (max ${MAX_TIMESERIES_BUCKETS}); narrow the range or use a coarser bucket`
|
|
7062
7593
|
);
|
|
@@ -7079,7 +7610,7 @@ async function handleUsageGet(view, query2, deps) {
|
|
|
7079
7610
|
};
|
|
7080
7611
|
}
|
|
7081
7612
|
default:
|
|
7082
|
-
return
|
|
7613
|
+
return err8(404, `unknown usage view '${view ?? ""}'`);
|
|
7083
7614
|
}
|
|
7084
7615
|
}
|
|
7085
7616
|
function poolKeyLabels(cfg) {
|
|
@@ -7128,7 +7659,7 @@ async function handlePricingList(deps) {
|
|
|
7128
7659
|
async function handlePricingUpsert(body, deps) {
|
|
7129
7660
|
const input = parsePricingEntryInput(body);
|
|
7130
7661
|
if (!input) {
|
|
7131
|
-
return
|
|
7662
|
+
return err8(400, "invalid pricing entry (providerId, modelId, finite numeric inputPricePer1m/outputPricePer1m required)");
|
|
7132
7663
|
}
|
|
7133
7664
|
const entry = await deps.pricingEngine.upsertManual(input);
|
|
7134
7665
|
return { status: 200, body: { entry } };
|
|
@@ -7137,7 +7668,7 @@ async function handlePricingDelete(query2, deps) {
|
|
|
7137
7668
|
const providerId = query2.get("providerId")?.trim() ?? "";
|
|
7138
7669
|
const modelId = query2.get("modelId")?.trim() ?? "";
|
|
7139
7670
|
if (!providerId || !modelId) {
|
|
7140
|
-
return
|
|
7671
|
+
return err8(400, "delete requires providerId and modelId query params");
|
|
7141
7672
|
}
|
|
7142
7673
|
const deleted = await deps.pricingStore.delete(providerId, modelId);
|
|
7143
7674
|
if (deleted) await deps.pricingEngine.invalidateCache();
|
|
@@ -7157,13 +7688,13 @@ async function handlePricingFetchLatest(deps) {
|
|
|
7157
7688
|
}
|
|
7158
7689
|
};
|
|
7159
7690
|
} catch (e) {
|
|
7160
|
-
return
|
|
7691
|
+
return err8(502, `pricing-source fetch failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
7161
7692
|
}
|
|
7162
7693
|
}
|
|
7163
7694
|
async function handlePricingResolveConflicts(body, deps) {
|
|
7164
7695
|
const raw = body["resolutions"];
|
|
7165
7696
|
if (!Array.isArray(raw)) {
|
|
7166
|
-
return
|
|
7697
|
+
return err8(400, "resolve-conflicts requires { resolutions: [...] }");
|
|
7167
7698
|
}
|
|
7168
7699
|
const currentRows = await deps.pricingStore.getAll();
|
|
7169
7700
|
const userEditedKeys = new Set(
|
|
@@ -7173,21 +7704,21 @@ async function handlePricingResolveConflicts(body, deps) {
|
|
|
7173
7704
|
const pendingIncoming = /* @__PURE__ */ new Map();
|
|
7174
7705
|
let staleCount = 0;
|
|
7175
7706
|
for (const item of raw) {
|
|
7176
|
-
if (!item || typeof item !== "object") return
|
|
7707
|
+
if (!item || typeof item !== "object") return err8(400, "invalid resolution entry");
|
|
7177
7708
|
const r = item;
|
|
7178
7709
|
const action = r["action"];
|
|
7179
7710
|
if (action !== "overwrite" && action !== "skip") {
|
|
7180
|
-
return
|
|
7711
|
+
return err8(400, "resolution action must be 'overwrite' or 'skip'");
|
|
7181
7712
|
}
|
|
7182
7713
|
const providerId = typeof r["providerId"] === "string" && r["providerId"].trim() ? r["providerId"].trim() : "";
|
|
7183
7714
|
const modelId = typeof r["modelId"] === "string" && r["modelId"].trim() ? r["modelId"].trim() : "";
|
|
7184
7715
|
if (!providerId || !modelId) {
|
|
7185
|
-
return
|
|
7716
|
+
return err8(400, "each resolution requires top-level providerId and modelId");
|
|
7186
7717
|
}
|
|
7187
7718
|
const incoming = parsePricingEntryInput(r["incoming"]);
|
|
7188
|
-
if (!incoming) return
|
|
7719
|
+
if (!incoming) return err8(400, "each resolution must echo a valid incoming pricing entry");
|
|
7189
7720
|
if (incoming.providerId !== providerId || incoming.modelId !== modelId) {
|
|
7190
|
-
return
|
|
7721
|
+
return err8(400, "resolution providerId/modelId must match the echoed incoming entry");
|
|
7191
7722
|
}
|
|
7192
7723
|
const key = `${providerId}::${modelId}`;
|
|
7193
7724
|
if (action === "overwrite" && !userEditedKeys.has(key)) {
|
|
@@ -7232,7 +7763,7 @@ function query(req) {
|
|
|
7232
7763
|
}
|
|
7233
7764
|
function allowanceProvider(value) {
|
|
7234
7765
|
if (!value) return void 0;
|
|
7235
|
-
return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" || value === "gemini" ? value : null;
|
|
7766
|
+
return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" || value === "gemini" || value === "antigravity" ? value : null;
|
|
7236
7767
|
}
|
|
7237
7768
|
async function handleAccountAllowanceApi(req, res, method, rest, service) {
|
|
7238
7769
|
if (!service) return writeError2(res, 501, "account allowance service is not available");
|
|
@@ -7309,6 +7840,16 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
|
|
|
7309
7840
|
}
|
|
7310
7841
|
return writeJson3(res, 200, { allowances: allowances2 });
|
|
7311
7842
|
}
|
|
7843
|
+
if (requestedProvider === "antigravity") {
|
|
7844
|
+
if (!service.refreshAntigravity) {
|
|
7845
|
+
return writeError2(res, 501, "antigravity allowance refresh is not available");
|
|
7846
|
+
}
|
|
7847
|
+
const allowances2 = await service.refreshAntigravity(accountId);
|
|
7848
|
+
if (accountId && allowances2.length === 0) {
|
|
7849
|
+
return writeError2(res, 404, `Antigravity account '${accountId}' not found`);
|
|
7850
|
+
}
|
|
7851
|
+
return writeJson3(res, 200, { allowances: allowances2 });
|
|
7852
|
+
}
|
|
7312
7853
|
if (requestedProvider === "gemini") {
|
|
7313
7854
|
if (!service.refreshGemini) {
|
|
7314
7855
|
return writeError2(res, 501, "gemini allowance refresh is not available");
|
|
@@ -7492,8 +8033,8 @@ async function handleAdminApi(req, res, path2, deps) {
|
|
|
7492
8033
|
default:
|
|
7493
8034
|
return writeJsonError(res, 404, `unknown admin resource '${resource}'`);
|
|
7494
8035
|
}
|
|
7495
|
-
} catch (
|
|
7496
|
-
writeJsonError(res, 500,
|
|
8036
|
+
} catch (err9) {
|
|
8037
|
+
writeJsonError(res, 500, err9 instanceof Error ? err9.message : String(err9));
|
|
7497
8038
|
}
|
|
7498
8039
|
}
|
|
7499
8040
|
function requestQuery(req) {
|
|
@@ -7668,7 +8209,7 @@ async function handleDiscoverModels(res, id, cfg) {
|
|
|
7668
8209
|
const headers = { Accept: "application/json" };
|
|
7669
8210
|
if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
|
|
7670
8211
|
Object.assign(headers, expandRowExtraHeaders(row));
|
|
7671
|
-
const response = await
|
|
8212
|
+
const response = await fetchUpstream10(url, { method: "GET", headers }, { providerId: "byo" });
|
|
7672
8213
|
if (!response.ok) {
|
|
7673
8214
|
const text = await response.text().catch(() => "");
|
|
7674
8215
|
let message = text.slice(0, 300);
|
|
@@ -7685,8 +8226,8 @@ async function handleDiscoverModels(res, id, cfg) {
|
|
|
7685
8226
|
const data = await response.json();
|
|
7686
8227
|
const models = Array.isArray(data?.data) ? data.data.map((m) => typeof m?.id === "string" ? m.id : "").filter((m) => m.length > 0) : [];
|
|
7687
8228
|
return writeJson4(res, 200, { models });
|
|
7688
|
-
} catch (
|
|
7689
|
-
const message =
|
|
8229
|
+
} catch (err9) {
|
|
8230
|
+
const message = err9 instanceof Error ? err9.message : String(err9);
|
|
7690
8231
|
return writeJson4(res, 200, { models: [], error: `discovery failed: ${message}` });
|
|
7691
8232
|
}
|
|
7692
8233
|
}
|
|
@@ -7728,7 +8269,7 @@ async function handleTestModel(req, res, id, cfg) {
|
|
|
7728
8269
|
Object.assign(headers, expandRowExtraHeaders(row));
|
|
7729
8270
|
const startedAt = Date.now();
|
|
7730
8271
|
try {
|
|
7731
|
-
const response = await
|
|
8272
|
+
const response = await fetchUpstream10(
|
|
7732
8273
|
url,
|
|
7733
8274
|
{ method: "POST", headers, body: JSON.stringify(payload) },
|
|
7734
8275
|
{ providerId: "byo" }
|
|
@@ -7750,8 +8291,8 @@ async function handleTestModel(req, res, id, cfg) {
|
|
|
7750
8291
|
latencyMs,
|
|
7751
8292
|
sample: extractSampleText(text, row.apiFormat)
|
|
7752
8293
|
});
|
|
7753
|
-
} catch (
|
|
7754
|
-
const message =
|
|
8294
|
+
} catch (err9) {
|
|
8295
|
+
const message = err9 instanceof Error ? err9.message : String(err9);
|
|
7755
8296
|
return writeJson4(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
|
|
7756
8297
|
}
|
|
7757
8298
|
}
|
|
@@ -8336,8 +8877,8 @@ function imageConfigurationAuditFields(previous, next) {
|
|
|
8336
8877
|
const after = next ?? DEFAULT_IMAGES_SERVER_CONFIG;
|
|
8337
8878
|
const fields = [];
|
|
8338
8879
|
if (before.enabled !== after.enabled) fields.push("enablement");
|
|
8339
|
-
if (before.
|
|
8340
|
-
if (before.defaultModel !== after.defaultModel || !sameConfigValue(before.
|
|
8880
|
+
if (!sameConfigValue(before.models, after.models)) fields.push("provider");
|
|
8881
|
+
if (before.defaultModel !== after.defaultModel || !sameConfigValue(before.aliases, after.aliases) || !sameConfigValue(before.codex, after.codex)) fields.push("model");
|
|
8341
8882
|
if (!sameConfigValue(before.account, after.account)) fields.push("account");
|
|
8342
8883
|
if (!sameConfigValue(before.queue, after.queue)) fields.push("queue");
|
|
8343
8884
|
if (!sameConfigValue(before.temporary, after.temporary)) fields.push("temporary");
|
|
@@ -8541,6 +9082,12 @@ async function handleAccounts(req, res, method, rest, deps) {
|
|
|
8541
9082
|
deps.accountAllowanceService
|
|
8542
9083
|
);
|
|
8543
9084
|
}
|
|
9085
|
+
if (method === "GET" && rest[0] === "antigravity" && rest[1] === "models") {
|
|
9086
|
+
const result = await handleAntigravityModelsRoute({
|
|
9087
|
+
resolveAntigravityAccessToken: deps.resolveAntigravityAccessToken ?? (async () => null)
|
|
9088
|
+
});
|
|
9089
|
+
return writeJson4(res, result.status, result.body);
|
|
9090
|
+
}
|
|
8544
9091
|
if (method === "GET" && rest.length === 0) {
|
|
8545
9092
|
const accounts = await deps.subscriptionAccounts.listAll();
|
|
8546
9093
|
const providerAccounts = await deps.subscriptionTokenWriter.listSanitizedAccounts();
|
|
@@ -8566,12 +9113,12 @@ async function handleAccounts(req, res, method, rest, deps) {
|
|
|
8566
9113
|
}
|
|
8567
9114
|
return writeJson4(res, 200, { ok: true, affected: result.affected });
|
|
8568
9115
|
}
|
|
8569
|
-
if (method === "GET" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot") && rest[1] === "oauth" && rest[3] === "status") {
|
|
8570
|
-
const result = rest[0] === "codex" ? handleCodexOAuthStatus(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthStatus(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthStatus(rest[2], deps) : handleCopilotOAuthStatus(rest[2], deps);
|
|
9116
|
+
if (method === "GET" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot" || rest[0] === "antigravity") && rest[1] === "oauth" && rest[3] === "status") {
|
|
9117
|
+
const result = rest[0] === "codex" ? handleCodexOAuthStatus(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthStatus(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthStatus(rest[2], deps) : rest[0] === "copilot" ? handleCopilotOAuthStatus(rest[2], deps) : handleAntigravityOAuthStatus(rest[2], deps);
|
|
8571
9118
|
return writeJson4(res, result.status, result.body);
|
|
8572
9119
|
}
|
|
8573
|
-
if (method === "DELETE" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot") && rest[1] === "oauth" && rest[2]) {
|
|
8574
|
-
const result = rest[0] === "codex" ? handleCodexOAuthCancel(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthCancel(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthCancel(rest[2], deps) : handleCopilotOAuthCancel(rest[2], deps);
|
|
9120
|
+
if (method === "DELETE" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot" || rest[0] === "antigravity") && rest[1] === "oauth" && rest[2]) {
|
|
9121
|
+
const result = rest[0] === "codex" ? handleCodexOAuthCancel(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthCancel(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthCancel(rest[2], deps) : rest[0] === "copilot" ? handleCopilotOAuthCancel(rest[2], deps) : handleAntigravityOAuthCancel(rest[2], deps);
|
|
8575
9122
|
return writeJson4(res, result.status, result.body);
|
|
8576
9123
|
}
|
|
8577
9124
|
if (method === "GET" && rest.length === 3 && rest[2] === "diagnostics") {
|
|
@@ -8641,6 +9188,10 @@ async function handleAccounts(req, res, method, rest, deps) {
|
|
|
8641
9188
|
const result2 = await handleCopilotOAuthStart(deps, body2["enterpriseUrl"]);
|
|
8642
9189
|
return writeJson4(res, result2.status, result2.body);
|
|
8643
9190
|
}
|
|
9191
|
+
if (providerId === "antigravity") {
|
|
9192
|
+
const result2 = handleAntigravityOAuthStart(deps);
|
|
9193
|
+
return writeJson4(res, result2.status, result2.body);
|
|
9194
|
+
}
|
|
8644
9195
|
const result = handleOAuthStart(providerId, deps);
|
|
8645
9196
|
return writeJson4(res, result.status, result.body);
|
|
8646
9197
|
}
|
|
@@ -9035,7 +9586,7 @@ async function handleImages(res, method, rest, deps) {
|
|
|
9035
9586
|
return writeJson4(res, 200, {
|
|
9036
9587
|
configured: {
|
|
9037
9588
|
enabled: images.enabled,
|
|
9038
|
-
provider: images.
|
|
9589
|
+
provider: images.models[images.defaultModel] ?? "codex-subscription",
|
|
9039
9590
|
model: images.defaultModel,
|
|
9040
9591
|
remoteUrlsEnabled: images.remote.enabled,
|
|
9041
9592
|
referenceTtlMs: images.references.ttlMs
|
|
@@ -9135,12 +9686,12 @@ async function handlePlayground(req, res, method, deps) {
|
|
|
9135
9686
|
const payload = body["body"];
|
|
9136
9687
|
const status = deps.outboundApiServer.getStatus();
|
|
9137
9688
|
if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
|
|
9138
|
-
const path2 = resolvePlaygroundPath(endpoint,
|
|
9689
|
+
const path2 = resolvePlaygroundPath(endpoint, isRecord9(payload) ? payload : {});
|
|
9139
9690
|
if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
|
|
9140
9691
|
const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
|
|
9141
9692
|
await proxyToOutbound(res, status.port, path2, key, upstreamBody);
|
|
9142
9693
|
}
|
|
9143
|
-
function
|
|
9694
|
+
function isRecord9(v) {
|
|
9144
9695
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
9145
9696
|
}
|
|
9146
9697
|
function proxyToOutbound(res, outboundPort, path2, key, body) {
|
|
@@ -9169,8 +9720,8 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
|
|
|
9169
9720
|
});
|
|
9170
9721
|
}
|
|
9171
9722
|
);
|
|
9172
|
-
upstream.on("error", (
|
|
9173
|
-
if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${
|
|
9723
|
+
upstream.on("error", (err9) => {
|
|
9724
|
+
if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${err9.message}`);
|
|
9174
9725
|
else res.end();
|
|
9175
9726
|
resolve10();
|
|
9176
9727
|
});
|
|
@@ -9275,7 +9826,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
|
|
|
9275
9826
|
}
|
|
9276
9827
|
|
|
9277
9828
|
// src/admin/version.ts
|
|
9278
|
-
var DAEMON_VERSION = true ? "0.4.
|
|
9829
|
+
var DAEMON_VERSION = true ? "0.4.3" : "0.0.0-dev";
|
|
9279
9830
|
|
|
9280
9831
|
// src/admin/AdminServer.ts
|
|
9281
9832
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
@@ -9318,13 +9869,13 @@ var AdminServer = class {
|
|
|
9318
9869
|
const server = http2.createServer((req, res) => {
|
|
9319
9870
|
this.onRequest(req, res);
|
|
9320
9871
|
});
|
|
9321
|
-
const onError = (
|
|
9322
|
-
if (
|
|
9872
|
+
const onError = (err9) => {
|
|
9873
|
+
if (err9.code === "EADDRINUSE" && port !== 0) {
|
|
9323
9874
|
server.removeListener("error", onError);
|
|
9324
9875
|
this.listen(bindAddr, 0).then(resolve10, reject);
|
|
9325
9876
|
return;
|
|
9326
9877
|
}
|
|
9327
|
-
reject(
|
|
9878
|
+
reject(err9);
|
|
9328
9879
|
};
|
|
9329
9880
|
server.on("error", onError);
|
|
9330
9881
|
server.listen(port, bindAddr, () => {
|
|
@@ -9342,8 +9893,8 @@ var AdminServer = class {
|
|
|
9342
9893
|
}
|
|
9343
9894
|
/** Per-request handler: auth gate (when a token is set) → routing. */
|
|
9344
9895
|
onRequest(req, res) {
|
|
9345
|
-
void this.dispatch(req, res).catch((
|
|
9346
|
-
const message =
|
|
9896
|
+
void this.dispatch(req, res).catch((err9) => {
|
|
9897
|
+
const message = err9 instanceof Error ? err9.message : String(err9);
|
|
9347
9898
|
this.deps.logger.error("[AdminServer] unhandled error:", message);
|
|
9348
9899
|
if (!res.headersSent) {
|
|
9349
9900
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
@@ -9566,7 +10117,10 @@ var HTML_HEADERS = {
|
|
|
9566
10117
|
function pageHtml(message) {
|
|
9567
10118
|
return `<!doctype html><meta charset="utf-8"><title>omnicross login</title><body style="font-family:sans-serif;padding:2rem"><h2>${message}</h2><p>You can close this window and return to the terminal.</p></body>`;
|
|
9568
10119
|
}
|
|
9569
|
-
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
|
|
10120
|
+
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal, binding = {}) {
|
|
10121
|
+
const port = binding.port ?? LOOPBACK_PORT;
|
|
10122
|
+
const callbackPath = binding.path ?? CALLBACK_PATH;
|
|
10123
|
+
const label = binding.label ?? "codex";
|
|
9570
10124
|
return new Promise((resolve10, reject) => {
|
|
9571
10125
|
let settled = false;
|
|
9572
10126
|
const finish = (server2, fn) => {
|
|
@@ -9577,8 +10131,8 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
|
|
|
9577
10131
|
server2.close();
|
|
9578
10132
|
};
|
|
9579
10133
|
const server = createServer2((req, res) => {
|
|
9580
|
-
const url = new URL(req.url ?? "", `http://${LOOPBACK_HOST}:${
|
|
9581
|
-
if (url.pathname !==
|
|
10134
|
+
const url = new URL(req.url ?? "", `http://${LOOPBACK_HOST}:${port}`);
|
|
10135
|
+
if (url.pathname !== callbackPath) {
|
|
9582
10136
|
res.writeHead(404, HTML_HEADERS);
|
|
9583
10137
|
res.end(pageHtml("Not found"));
|
|
9584
10138
|
return;
|
|
@@ -9607,25 +10161,25 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
|
|
|
9607
10161
|
return;
|
|
9608
10162
|
}
|
|
9609
10163
|
signal?.addEventListener("abort", abort, { once: true });
|
|
9610
|
-
server.on("error", (
|
|
10164
|
+
server.on("error", (err9) => {
|
|
9611
10165
|
if (settled) return;
|
|
9612
10166
|
settled = true;
|
|
9613
10167
|
clearTimeout(timer);
|
|
9614
|
-
if (
|
|
10168
|
+
if (err9.code === "EADDRINUSE") {
|
|
9615
10169
|
reject(
|
|
9616
10170
|
new Error(
|
|
9617
|
-
`login: cannot bind ${LOOPBACK_HOST}:${
|
|
10171
|
+
`login: cannot bind ${LOOPBACK_HOST}:${port} (address in use) \u2014 another ${label} login or process is holding the port`
|
|
9618
10172
|
)
|
|
9619
10173
|
);
|
|
9620
10174
|
} else {
|
|
9621
|
-
reject(
|
|
10175
|
+
reject(err9);
|
|
9622
10176
|
}
|
|
9623
10177
|
});
|
|
9624
10178
|
const timer = setTimeout(() => {
|
|
9625
10179
|
finish(server, () => reject(new Error(`login: timed out after ${Math.round(timeoutMs / 1e3)}s waiting for the callback`)));
|
|
9626
10180
|
}, timeoutMs);
|
|
9627
10181
|
if (typeof timer.unref === "function") timer.unref();
|
|
9628
|
-
server.listen(
|
|
10182
|
+
server.listen(port, LOOPBACK_HOST);
|
|
9629
10183
|
});
|
|
9630
10184
|
}
|
|
9631
10185
|
|
|
@@ -9695,7 +10249,7 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
|
|
|
9695
10249
|
|
|
9696
10250
|
// src/allowance/ProviderKeyQuotaService.ts
|
|
9697
10251
|
import { mergeExtraHeaders as mergeExtraHeaders2 } from "@omnicross/core";
|
|
9698
|
-
import { fetchUpstream as
|
|
10252
|
+
import { fetchUpstream as fetchUpstream11 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
9699
10253
|
|
|
9700
10254
|
// src/allowance/ProviderKeyQuota.ts
|
|
9701
10255
|
var MINUTE_MS3 = 6e4;
|
|
@@ -9724,11 +10278,11 @@ function isoInstant3(value) {
|
|
|
9724
10278
|
}
|
|
9725
10279
|
return void 0;
|
|
9726
10280
|
}
|
|
9727
|
-
function
|
|
10281
|
+
function secondsUntil9(instant, now) {
|
|
9728
10282
|
if (!instant) return void 0;
|
|
9729
10283
|
return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
|
|
9730
10284
|
}
|
|
9731
|
-
function
|
|
10285
|
+
function isRecord10(value) {
|
|
9732
10286
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9733
10287
|
}
|
|
9734
10288
|
function detectProviderKeyQuotaAdapter(baseUrl) {
|
|
@@ -9795,17 +10349,17 @@ function zaiWindowIdLabel(durationMs) {
|
|
|
9795
10349
|
return { id: "quota", label: "Quota" };
|
|
9796
10350
|
}
|
|
9797
10351
|
function parseZaiQuotaPayload(payload, now) {
|
|
9798
|
-
if (!
|
|
9799
|
-
const data =
|
|
10352
|
+
if (!isRecord10(payload)) return null;
|
|
10353
|
+
const data = isRecord10(payload["data"]) ? payload["data"] : payload;
|
|
9800
10354
|
if (payload["success"] === false) return null;
|
|
9801
10355
|
const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
|
|
9802
10356
|
const byWindow = /* @__PURE__ */ new Map();
|
|
9803
10357
|
for (const raw of limits) {
|
|
9804
|
-
if (!
|
|
10358
|
+
if (!isRecord10(raw)) continue;
|
|
9805
10359
|
const item = raw;
|
|
9806
10360
|
if (item.type === void 0) continue;
|
|
9807
10361
|
const details = raw["usageDetails"];
|
|
9808
|
-
if (Array.isArray(details) && details.some((d) =>
|
|
10362
|
+
if (Array.isArray(details) && details.some((d) => isRecord10(d) && d["modelCode"] === "zread")) {
|
|
9809
10363
|
continue;
|
|
9810
10364
|
}
|
|
9811
10365
|
const durationMs = zaiWindowDurationMs(item);
|
|
@@ -9824,7 +10378,7 @@ function parseZaiQuotaPayload(payload, now) {
|
|
|
9824
10378
|
usedPercent,
|
|
9825
10379
|
...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS3) } : {},
|
|
9826
10380
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9827
|
-
remainingSeconds:
|
|
10381
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9828
10382
|
state: "fresh"
|
|
9829
10383
|
};
|
|
9830
10384
|
const existing = byWindow.get(id);
|
|
@@ -9838,7 +10392,7 @@ function parseZaiQuotaPayload(payload, now) {
|
|
|
9838
10392
|
var MINIMAX_STATUS_EXHAUSTED = 2;
|
|
9839
10393
|
var MINIMAX_SHARED_BUCKET = "general";
|
|
9840
10394
|
function parseMiniMaxBucket(value) {
|
|
9841
|
-
if (!
|
|
10395
|
+
if (!isRecord10(value)) return null;
|
|
9842
10396
|
const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
|
|
9843
10397
|
if (!modelName) return null;
|
|
9844
10398
|
const instant = (v) => {
|
|
@@ -9865,14 +10419,14 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
|
|
|
9865
10419
|
usedPercent,
|
|
9866
10420
|
...windowMinutes !== void 0 ? { windowMinutes } : {},
|
|
9867
10421
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9868
|
-
remainingSeconds:
|
|
10422
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9869
10423
|
state: usedPercent !== null ? "fresh" : "unavailable"
|
|
9870
10424
|
};
|
|
9871
10425
|
}
|
|
9872
10426
|
function parseMiniMaxTokenPlanPayload(payload, now) {
|
|
9873
|
-
if (!
|
|
10427
|
+
if (!isRecord10(payload)) return null;
|
|
9874
10428
|
const baseResp = payload["base_resp"];
|
|
9875
|
-
if (!
|
|
10429
|
+
if (!isRecord10(baseResp) || baseResp["status_code"] !== 0) return null;
|
|
9876
10430
|
const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
|
|
9877
10431
|
let general = null;
|
|
9878
10432
|
for (const raw of buckets) {
|
|
@@ -9905,11 +10459,11 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
|
|
|
9905
10459
|
];
|
|
9906
10460
|
}
|
|
9907
10461
|
function parseUmansUsagePayload(payload, now) {
|
|
9908
|
-
if (!
|
|
9909
|
-
const limits =
|
|
9910
|
-
const requests = limits &&
|
|
9911
|
-
const usage =
|
|
9912
|
-
const window =
|
|
10462
|
+
if (!isRecord10(payload)) return null;
|
|
10463
|
+
const limits = isRecord10(payload["limits"]) ? payload["limits"] : void 0;
|
|
10464
|
+
const requests = limits && isRecord10(limits["requests"]) ? limits["requests"] : void 0;
|
|
10465
|
+
const usage = isRecord10(payload["usage"]) ? payload["usage"] : void 0;
|
|
10466
|
+
const window = isRecord10(payload["window"]) ? payload["window"] : void 0;
|
|
9913
10467
|
const hardCap = finiteNumber5(requests?.["hard_cap"]);
|
|
9914
10468
|
const softLimit = finiteNumber5(requests?.["limit"]);
|
|
9915
10469
|
const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
|
|
@@ -9930,15 +10484,15 @@ function parseUmansUsagePayload(payload, now) {
|
|
|
9930
10484
|
usedPercent,
|
|
9931
10485
|
windowMinutes: 5 * 60,
|
|
9932
10486
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9933
|
-
remainingSeconds:
|
|
10487
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9934
10488
|
state: "fresh"
|
|
9935
10489
|
}
|
|
9936
10490
|
];
|
|
9937
10491
|
}
|
|
9938
10492
|
function parseSyntheticQuotasPayload(payload, now) {
|
|
9939
|
-
if (!
|
|
9940
|
-
const fiveHour =
|
|
9941
|
-
const weekly =
|
|
10493
|
+
if (!isRecord10(payload)) return null;
|
|
10494
|
+
const fiveHour = isRecord10(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
|
|
10495
|
+
const weekly = isRecord10(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
|
|
9942
10496
|
const windows = [];
|
|
9943
10497
|
if (fiveHour) {
|
|
9944
10498
|
const max = finiteNumber5(fiveHour["max"]);
|
|
@@ -9952,7 +10506,7 @@ function parseSyntheticQuotasPayload(payload, now) {
|
|
|
9952
10506
|
usedPercent,
|
|
9953
10507
|
windowMinutes: 5 * 60,
|
|
9954
10508
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9955
|
-
remainingSeconds:
|
|
10509
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9956
10510
|
state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
|
|
9957
10511
|
});
|
|
9958
10512
|
}
|
|
@@ -9967,7 +10521,7 @@ function parseSyntheticQuotasPayload(payload, now) {
|
|
|
9967
10521
|
usedPercent,
|
|
9968
10522
|
windowMinutes: 7 * 24 * 60,
|
|
9969
10523
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9970
|
-
remainingSeconds:
|
|
10524
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9971
10525
|
state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
|
|
9972
10526
|
});
|
|
9973
10527
|
}
|
|
@@ -9979,12 +10533,12 @@ var CLINE_WINDOW_CONFIG = {
|
|
|
9979
10533
|
monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
|
|
9980
10534
|
};
|
|
9981
10535
|
function parseClinePassUsageLimitsPayload(payload, now) {
|
|
9982
|
-
if (!
|
|
9983
|
-
const data =
|
|
10536
|
+
if (!isRecord10(payload)) return null;
|
|
10537
|
+
const data = isRecord10(payload["data"]) ? payload["data"] : payload;
|
|
9984
10538
|
const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
|
|
9985
10539
|
const windows = [];
|
|
9986
10540
|
for (const raw of limits) {
|
|
9987
|
-
if (!
|
|
10541
|
+
if (!isRecord10(raw)) continue;
|
|
9988
10542
|
const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
|
|
9989
10543
|
if (!config) continue;
|
|
9990
10544
|
const usedPercent = finitePercent4(raw["percentUsed"]);
|
|
@@ -9997,7 +10551,7 @@ function parseClinePassUsageLimitsPayload(payload, now) {
|
|
|
9997
10551
|
usedPercent,
|
|
9998
10552
|
windowMinutes: config.minutes,
|
|
9999
10553
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
10000
|
-
remainingSeconds:
|
|
10554
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
10001
10555
|
state: "fresh"
|
|
10002
10556
|
});
|
|
10003
10557
|
}
|
|
@@ -10036,7 +10590,7 @@ function rowKeyEntries(row) {
|
|
|
10036
10590
|
return [];
|
|
10037
10591
|
}
|
|
10038
10592
|
var ProviderKeyQuotaService = class {
|
|
10039
|
-
constructor(box, fetchImpl = (url, init) =>
|
|
10593
|
+
constructor(box, fetchImpl = (url, init) => fetchUpstream11(url, init, { redactBodies: true }), now = Date.now) {
|
|
10040
10594
|
this.box = box;
|
|
10041
10595
|
this.fetchImpl = fetchImpl;
|
|
10042
10596
|
this.now = now;
|
|
@@ -10643,12 +11197,12 @@ function createImageDoctorService(options) {
|
|
|
10643
11197
|
authStrategy: strategy,
|
|
10644
11198
|
generationTimeoutMs: config.queue.generationTimeoutMs
|
|
10645
11199
|
}));
|
|
10646
|
-
const readAccount = async () => {
|
|
10647
|
-
const
|
|
11200
|
+
const readAccount = async (providerId) => {
|
|
11201
|
+
const entry = (await options.subscriptionAccounts.listAll()).find((candidate) => candidate.providerId === providerId);
|
|
10648
11202
|
return Object.freeze({
|
|
10649
|
-
present:
|
|
10650
|
-
usable:
|
|
10651
|
-
reason:
|
|
11203
|
+
present: entry !== void 0,
|
|
11204
|
+
usable: entry?.credentialStatus.ok === true,
|
|
11205
|
+
reason: entry === void 0 ? "missing" : entry.credentialStatus.ok ? "ready" : "unavailable"
|
|
10652
11206
|
});
|
|
10653
11207
|
};
|
|
10654
11208
|
const activePaths = () => options.storageCatalog.active().resolver;
|
|
@@ -10686,6 +11240,7 @@ function createImageDoctorService(options) {
|
|
|
10686
11240
|
} catch {
|
|
10687
11241
|
storesValid = false;
|
|
10688
11242
|
}
|
|
11243
|
+
const antigravityAccount = await readAccount("antigravity");
|
|
10689
11244
|
const rows = await options.keyDb.outboundApiKeysList();
|
|
10690
11245
|
let legacyRows = 0;
|
|
10691
11246
|
let invalidRows = 0;
|
|
@@ -10702,7 +11257,7 @@ function createImageDoctorService(options) {
|
|
|
10702
11257
|
invalidRows += 1;
|
|
10703
11258
|
}
|
|
10704
11259
|
}
|
|
10705
|
-
const account = await readAccount();
|
|
11260
|
+
const account = await readAccount("codex");
|
|
10706
11261
|
let evidence;
|
|
10707
11262
|
let evidenceStore;
|
|
10708
11263
|
try {
|
|
@@ -10716,10 +11271,11 @@ function createImageDoctorService(options) {
|
|
|
10716
11271
|
return Object.freeze({
|
|
10717
11272
|
config: Object.freeze({
|
|
10718
11273
|
enabled: config.enabled,
|
|
10719
|
-
provider: config.
|
|
11274
|
+
provider: config.models[config.defaultModel] ?? "codex-subscription",
|
|
10720
11275
|
model: config.defaultModel,
|
|
10721
11276
|
valid: configErrors.length === 0,
|
|
10722
|
-
errorCount: configErrors.length
|
|
11277
|
+
errorCount: configErrors.length,
|
|
11278
|
+
routedProviders: Object.freeze([...new Set(Object.values(config.models))])
|
|
10723
11279
|
}),
|
|
10724
11280
|
roots: Object.freeze({
|
|
10725
11281
|
valid: verifiedAreas === ROOT_AREAS.length,
|
|
@@ -10744,12 +11300,13 @@ function createImageDoctorService(options) {
|
|
|
10744
11300
|
imagesAuthorizedRows
|
|
10745
11301
|
}),
|
|
10746
11302
|
account,
|
|
11303
|
+
antigravityAccount,
|
|
10747
11304
|
evidence: Object.freeze(evidence)
|
|
10748
11305
|
});
|
|
10749
11306
|
},
|
|
10750
11307
|
verifyLive: async (config, signal) => {
|
|
10751
11308
|
if (!config.enabled) return Object.freeze({ ok: false, code: "images_disabled" });
|
|
10752
|
-
const account = await readAccount();
|
|
11309
|
+
const account = await readAccount("codex");
|
|
10753
11310
|
if (!account.usable) {
|
|
10754
11311
|
return Object.freeze({ ok: false, code: "codex_account_unavailable" });
|
|
10755
11312
|
}
|
|
@@ -11010,6 +11567,7 @@ import {
|
|
|
11010
11567
|
validateImagesServerConfig as validateImagesServerConfig3
|
|
11011
11568
|
} from "@omnicross/core/outbound-api";
|
|
11012
11569
|
import {
|
|
11570
|
+
createAntigravitySubscriptionImageProvider,
|
|
11013
11571
|
createCodexSubscriptionImageProvider
|
|
11014
11572
|
} from "@omnicross/subscriptions";
|
|
11015
11573
|
|
|
@@ -11041,10 +11599,11 @@ function createTrustedImageApiRuntimeResolver(options) {
|
|
|
11041
11599
|
throw new TypeError("enabled image remote loading requires a proven resolver");
|
|
11042
11600
|
}
|
|
11043
11601
|
const hmacKey = Buffer.from(options.hmacKey);
|
|
11044
|
-
const modelAliases = new Map(Object.entries(options.config.
|
|
11602
|
+
const modelAliases = new Map(Object.entries(options.config.aliases));
|
|
11603
|
+
const modelRoutes = new Map(Object.entries(options.config.models));
|
|
11045
11604
|
const limits = Object.freeze({ ...options.config.limits });
|
|
11046
|
-
const providerId = options.config.provider;
|
|
11047
11605
|
const defaultModel = options.config.defaultModel;
|
|
11606
|
+
const providerId = modelRoutes.get(defaultModel) ?? "codex-subscription";
|
|
11048
11607
|
const referenceStore = options.referenceStore;
|
|
11049
11608
|
const retention = Object.freeze({
|
|
11050
11609
|
enabled: true,
|
|
@@ -11065,6 +11624,7 @@ function createTrustedImageApiRuntimeResolver(options) {
|
|
|
11065
11624
|
providerId,
|
|
11066
11625
|
defaultModel,
|
|
11067
11626
|
modelAliases,
|
|
11627
|
+
modelRoutes,
|
|
11068
11628
|
limits,
|
|
11069
11629
|
...preferredAccountId ? { preferredAccountId } : {},
|
|
11070
11630
|
...preferredAccountGroup ? { preferredAccountGroup } : {},
|
|
@@ -11469,7 +12029,9 @@ var GENERATION_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/u;
|
|
|
11469
12029
|
function snapshotConfig(config) {
|
|
11470
12030
|
return {
|
|
11471
12031
|
...config,
|
|
11472
|
-
|
|
12032
|
+
models: { ...config.models },
|
|
12033
|
+
aliases: { ...config.aliases },
|
|
12034
|
+
codex: { ...config.codex },
|
|
11473
12035
|
account: { ...config.account },
|
|
11474
12036
|
queue: { ...config.queue },
|
|
11475
12037
|
temporary: { ...config.temporary },
|
|
@@ -11503,10 +12065,15 @@ function createImageRuntimeGeneration(options) {
|
|
|
11503
12065
|
}
|
|
11504
12066
|
});
|
|
11505
12067
|
}
|
|
11506
|
-
const
|
|
11507
|
-
|
|
12068
|
+
const routedProviders = [...new Set(Object.values(config.models))];
|
|
12069
|
+
const codexStrategy = routedProviders.includes("codex-subscription") ? options.subscriptionAccounts.getStrategy("codex") : void 0;
|
|
12070
|
+
if (routedProviders.includes("codex-subscription") && (!codexStrategy || codexStrategy.providerId !== "codex")) {
|
|
11508
12071
|
throw new TypeError("enabled image runtime requires the Codex subscription strategy");
|
|
11509
12072
|
}
|
|
12073
|
+
const antigravityStrategy = routedProviders.includes("antigravity-subscription") ? options.subscriptionAccounts.getStrategy("antigravity") : void 0;
|
|
12074
|
+
if (routedProviders.includes("antigravity-subscription") && (!antigravityStrategy || antigravityStrategy.providerId !== "antigravity")) {
|
|
12075
|
+
throw new TypeError("enabled image runtime requires the Antigravity subscription strategy");
|
|
12076
|
+
}
|
|
11510
12077
|
const privateHmacKey = options.privateHmacKey ? Buffer.from(options.privateHmacKey) : loadOrCreateImageTenantHmacSalt(options.storage.paths, randomBytes6);
|
|
11511
12078
|
if (privateHmacKey.byteLength !== 32) {
|
|
11512
12079
|
privateHmacKey.fill(0);
|
|
@@ -11541,23 +12108,32 @@ function createImageRuntimeGeneration(options) {
|
|
|
11541
12108
|
if (options.testOnlySyntheticVerifiedProvider && options.testOnlySyntheticVerifiedProvider.label !== "synthetic-verified-image-provider-test-only") {
|
|
11542
12109
|
throw new TypeError("synthetic verified image provider test seam label is invalid");
|
|
11543
12110
|
}
|
|
11544
|
-
const
|
|
12111
|
+
const providers = options.testOnlySyntheticVerifiedProvider ? [options.testOnlySyntheticVerifiedProvider.createProvider({
|
|
11545
12112
|
generationId: options.generationId,
|
|
11546
12113
|
scheduler,
|
|
11547
12114
|
now: options.now ?? Date.now,
|
|
11548
12115
|
referenceStore: options.storage.referenceStore,
|
|
11549
12116
|
stateStore: options.storage.stateStore
|
|
11550
|
-
}) : createCodexSubscriptionImageProvider({
|
|
11551
|
-
authStrategy,
|
|
12117
|
+
})] : routedProviders.map((providerId) => providerId === "codex-subscription" ? createCodexSubscriptionImageProvider({
|
|
12118
|
+
authStrategy: codexStrategy,
|
|
11552
12119
|
evidenceSource: generationEvidenceSource,
|
|
11553
12120
|
executionScheduler: scheduler,
|
|
11554
12121
|
generationTimeoutMs: config.queue.generationTimeoutMs,
|
|
12122
|
+
now: options.now,
|
|
12123
|
+
wire: {
|
|
12124
|
+
imageModel: config.codex.imageModel,
|
|
12125
|
+
carrierModel: config.codex.carrierModel
|
|
12126
|
+
}
|
|
12127
|
+
}) : createAntigravitySubscriptionImageProvider({
|
|
12128
|
+
authStrategy: antigravityStrategy,
|
|
12129
|
+
executionScheduler: scheduler,
|
|
12130
|
+
generationTimeoutMs: config.queue.generationTimeoutMs,
|
|
11555
12131
|
now: options.now
|
|
11556
|
-
});
|
|
11557
|
-
if (
|
|
12132
|
+
}));
|
|
12133
|
+
if (providers.length === 1 && providers[0].id !== "codex-subscription") {
|
|
11558
12134
|
throw new TypeError("synthetic verified image provider id must match configured provider");
|
|
11559
12135
|
}
|
|
11560
|
-
const providerRegistry = new ImageProviderRegistry(
|
|
12136
|
+
const providerRegistry = new ImageProviderRegistry(providers);
|
|
11561
12137
|
const orchestrator = new ImageOrchestrator({
|
|
11562
12138
|
registry: providerRegistry,
|
|
11563
12139
|
referenceStore: options.storage.referenceStore,
|
|
@@ -11579,35 +12155,53 @@ function createImageRuntimeGeneration(options) {
|
|
|
11579
12155
|
...options.createCallId ? { createCallId: options.createCallId } : {},
|
|
11580
12156
|
...options.now ? { now: options.now } : {}
|
|
11581
12157
|
});
|
|
12158
|
+
const defaultProviderId = config.models[config.defaultModel] ?? "codex-subscription";
|
|
12159
|
+
const inspectOneProvider = async (providerId, apiKeyId) => {
|
|
12160
|
+
const capabilities = await orchestrator.getCapabilities(providerId, {
|
|
12161
|
+
requestId: `${options.generationId}:capability-inspection`,
|
|
12162
|
+
tenantId: apiKeyId,
|
|
12163
|
+
signal: new AbortController().signal,
|
|
12164
|
+
sessionKey: `outbound:images:${apiKeyId}`,
|
|
12165
|
+
...config.account.id ? { preferredAccountId: config.account.id } : {},
|
|
12166
|
+
...config.account.group ? { preferredAccountGroup: config.account.group } : {},
|
|
12167
|
+
boundAccountFallbackPolicy: config.account.fallback
|
|
12168
|
+
});
|
|
12169
|
+
return capabilities;
|
|
12170
|
+
};
|
|
11582
12171
|
const inspectCapability = async (apiKeyId) => {
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
providerId: config.provider,
|
|
11598
|
-
model: config.defaultModel,
|
|
11599
|
-
...!available ? { reason: capabilities.reason ?? "runtime_unavailable" } : {},
|
|
11600
|
-
capabilities
|
|
11601
|
-
});
|
|
11602
|
-
} catch (error) {
|
|
12172
|
+
const providerCapabilities = /* @__PURE__ */ new Map();
|
|
12173
|
+
let defaultProviderError;
|
|
12174
|
+
for (const providerId of [...new Set(Object.values(config.models))]) {
|
|
12175
|
+
try {
|
|
12176
|
+
providerCapabilities.set(providerId, await inspectOneProvider(providerId, apiKeyId));
|
|
12177
|
+
} catch (error) {
|
|
12178
|
+
if (providerId === defaultProviderId) defaultProviderError = error;
|
|
12179
|
+
}
|
|
12180
|
+
}
|
|
12181
|
+
const routedModels = Object.freeze(
|
|
12182
|
+
[...providerCapabilities.entries()].flatMap(([providerId, capabilities2]) => capabilities2.available === true && capabilities2.generate === true ? Object.entries(config.models).filter(([model, modelProvider]) => modelProvider === providerId && capabilities2.models.includes(model)).map(([model]) => model) : [])
|
|
12183
|
+
);
|
|
12184
|
+
const capabilities = providerCapabilities.get(defaultProviderId);
|
|
12185
|
+
if (!capabilities) {
|
|
11603
12186
|
return Object.freeze({
|
|
11604
12187
|
enabled: true,
|
|
11605
12188
|
available: false,
|
|
11606
|
-
providerId:
|
|
12189
|
+
providerId: defaultProviderId,
|
|
11607
12190
|
model: config.defaultModel,
|
|
11608
|
-
|
|
12191
|
+
routedModels,
|
|
12192
|
+
reason: defaultProviderError instanceof ImageGenerationError4 && (defaultProviderError.code === "upstream_auth_required" || defaultProviderError.code === "invalid_api_key") ? "account_unverified" : "runtime_unavailable"
|
|
11609
12193
|
});
|
|
11610
12194
|
}
|
|
12195
|
+
const available = capabilities.available === true && capabilities.generate === true && capabilities.models.includes(config.defaultModel);
|
|
12196
|
+
return Object.freeze({
|
|
12197
|
+
enabled: true,
|
|
12198
|
+
available,
|
|
12199
|
+
providerId: defaultProviderId,
|
|
12200
|
+
model: config.defaultModel,
|
|
12201
|
+
routedModels,
|
|
12202
|
+
...!available ? { reason: capabilities.reason ?? "runtime_unavailable" } : {},
|
|
12203
|
+
capabilities
|
|
12204
|
+
});
|
|
11611
12205
|
};
|
|
11612
12206
|
const resolverToDispose = runtimeResolver;
|
|
11613
12207
|
const schedulerToDispose = scheduler;
|
|
@@ -11645,7 +12239,7 @@ function createImageRuntimeGeneration(options) {
|
|
|
11645
12239
|
imageApi,
|
|
11646
12240
|
hosted,
|
|
11647
12241
|
hostedRuntime: Object.freeze({
|
|
11648
|
-
providerId:
|
|
12242
|
+
providerId: defaultProviderId,
|
|
11649
12243
|
imageModel: config.defaultModel,
|
|
11650
12244
|
referenceTtlMs: config.references.ttlMs,
|
|
11651
12245
|
maxOutputBytes: config.limits.maxOutputBytes,
|
|
@@ -14642,6 +15236,9 @@ var ImageRuntimeManager = class {
|
|
|
14642
15236
|
}
|
|
14643
15237
|
async listAvailableModels(apiKeyId) {
|
|
14644
15238
|
const inspection = await this.inspectCapability(apiKeyId);
|
|
15239
|
+
if (inspection.routedModels !== void 0) {
|
|
15240
|
+
return Object.freeze([...inspection.routedModels]);
|
|
15241
|
+
}
|
|
14645
15242
|
return inspection.available && inspection.model === "gpt-image-2" ? Object.freeze([inspection.model]) : Object.freeze([]);
|
|
14646
15243
|
}
|
|
14647
15244
|
resourceStatus() {
|
|
@@ -16857,11 +17454,13 @@ var JsonVoucherDb = class {
|
|
|
16857
17454
|
// src/ports/JsonSubscriptionCredentialStore.ts
|
|
16858
17455
|
import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as readFileSync18, renameSync as renameSync12 } from "fs";
|
|
16859
17456
|
import { dirname as dirname15 } from "path";
|
|
17457
|
+
import { getAntigravityProjectResolver as getAntigravityProjectResolver2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
|
|
16860
17458
|
import { getSharedAccountHealth as getSharedAccountHealth2 } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
|
|
16861
17459
|
import { getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling3 } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
|
|
16862
|
-
import { fetchUpstream as
|
|
17460
|
+
import { fetchUpstream as fetchUpstream12 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
16863
17461
|
import { getSharedIdentityStore as getSharedIdentityStore2 } from "@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore";
|
|
16864
17462
|
import {
|
|
17463
|
+
antigravityOAuth as antigravityOAuth2,
|
|
16865
17464
|
claudeOAuth as claudeOAuth2,
|
|
16866
17465
|
codexOAuth as codexOAuth2,
|
|
16867
17466
|
geminiOAuth as geminiOAuth2,
|
|
@@ -17015,7 +17614,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17015
17614
|
* a plaintext token pair into `upstream-trace.jsonl`.
|
|
17016
17615
|
*/
|
|
17017
17616
|
buildRefreshFetch(providerId, accountId) {
|
|
17018
|
-
return this.fetchImpl ?? ((url, init) =>
|
|
17617
|
+
return this.fetchImpl ?? ((url, init) => fetchUpstream12(url, init, { providerId, accountId, redactBodies: true }));
|
|
17019
17618
|
}
|
|
17020
17619
|
/**
|
|
17021
17620
|
* In-flight refresh coalescing. OAuth refresh tokens are
|
|
@@ -17056,7 +17655,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17056
17655
|
* other hot reads. Never returns token material.
|
|
17057
17656
|
*/
|
|
17058
17657
|
getAccountProxy(providerId, accountId) {
|
|
17059
|
-
if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi" && providerId !== "grok" && providerId !== "copilot") {
|
|
17658
|
+
if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi" && providerId !== "grok" && providerId !== "copilot" && providerId !== "antigravity") {
|
|
17060
17659
|
return void 0;
|
|
17061
17660
|
}
|
|
17062
17661
|
return getAccountProxy(this.readConfig(), providerId, accountId);
|
|
@@ -17075,7 +17674,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17075
17674
|
const fingerprintOn = identityStore.isEnabled();
|
|
17076
17675
|
const now = Date.now();
|
|
17077
17676
|
const out = {};
|
|
17078
|
-
for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi", "grok", "copilot"]) {
|
|
17677
|
+
for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi", "grok", "copilot", "antigravity"]) {
|
|
17079
17678
|
const sanitized = sanitizeAccounts(config, provider);
|
|
17080
17679
|
if (sanitized.length === 0) continue;
|
|
17081
17680
|
for (const account of sanitized) {
|
|
@@ -17334,6 +17933,76 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17334
17933
|
return false;
|
|
17335
17934
|
});
|
|
17336
17935
|
}
|
|
17936
|
+
/**
|
|
17937
|
+
* Refresh the Antigravity (Google) OAuth access token. Like gemini, the
|
|
17938
|
+
* Google token endpoint does NOT return a refresh_token on refresh, so this
|
|
17939
|
+
* writes ONLY access+expiresAt (+status/lastRefreshedAt) and DELIBERATELY
|
|
17940
|
+
* preserves the stored `refreshToken` — plus the account's `projectId`
|
|
17941
|
+
* (a handshake product; the post-refresh re-validation is the refresh
|
|
17942
|
+
* scheduler's hook, not this write) and `email`. HONEST `false` when no
|
|
17943
|
+
* refresh_token.
|
|
17944
|
+
*/
|
|
17945
|
+
async refreshAntigravityToken() {
|
|
17946
|
+
return this.coalesce("antigravity:active", async () => {
|
|
17947
|
+
const config = this.readConfig();
|
|
17948
|
+
const active = getActiveAccount(config, "antigravity");
|
|
17949
|
+
const antigravity = active?.tokens;
|
|
17950
|
+
if (!active || !antigravity?.refreshToken) return false;
|
|
17951
|
+
const capturedId = active.id;
|
|
17952
|
+
this.materializeMigration(config);
|
|
17953
|
+
const refreshFetch = this.buildRefreshFetch("antigravity", capturedId);
|
|
17954
|
+
try {
|
|
17955
|
+
const result = await antigravityOAuth2.refreshAccessToken(antigravity.refreshToken, refreshFetch);
|
|
17956
|
+
const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
|
|
17957
|
+
const next = {
|
|
17958
|
+
...antigravity,
|
|
17959
|
+
// KEEP the existing refreshToken/projectId/email.
|
|
17960
|
+
accessToken: result.accessToken,
|
|
17961
|
+
expiresAt,
|
|
17962
|
+
status: "authorized",
|
|
17963
|
+
lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17964
|
+
errorMessage: void 0
|
|
17965
|
+
};
|
|
17966
|
+
this.writeBackById("antigravity", capturedId, next);
|
|
17967
|
+
await this.revalidateAntigravityProject(capturedId);
|
|
17968
|
+
return true;
|
|
17969
|
+
} catch (error) {
|
|
17970
|
+
this.markExpiredById("antigravity", capturedId, antigravity, error);
|
|
17971
|
+
return false;
|
|
17972
|
+
}
|
|
17973
|
+
});
|
|
17974
|
+
}
|
|
17975
|
+
/**
|
|
17976
|
+
* Post-refresh project re-validation hook (antigravity design D8): after a
|
|
17977
|
+
* successful antigravity token refresh, re-run the Code Assist project
|
|
17978
|
+
* handshake and write the (possibly rotated) `projectId` back to the account.
|
|
17979
|
+
* A handshake FAILURE keeps the stored projectId untouched (logged) so the
|
|
17980
|
+
* account keeps serving with the last-known-good project until a later
|
|
17981
|
+
* refresh succeeds. Returns whether the handshake produced a project.
|
|
17982
|
+
*/
|
|
17983
|
+
async revalidateAntigravityProject(accountId) {
|
|
17984
|
+
const before = getAccountById(this.readConfig(), "antigravity", accountId);
|
|
17985
|
+
const accessToken = before?.tokens?.accessToken;
|
|
17986
|
+
if (!accessToken) return false;
|
|
17987
|
+
try {
|
|
17988
|
+
const projectId = await getAntigravityProjectResolver2().resolveProject(accessToken);
|
|
17989
|
+
if (projectId !== void 0) {
|
|
17990
|
+
const config = this.readConfig();
|
|
17991
|
+
const account = getAccountById(config, "antigravity", accountId);
|
|
17992
|
+
const tokens = account?.tokens;
|
|
17993
|
+
if (account && tokens?.accessToken === accessToken && tokens.projectId !== projectId) {
|
|
17994
|
+
this.writeBackById("antigravity", accountId, { ...tokens, projectId });
|
|
17995
|
+
}
|
|
17996
|
+
return true;
|
|
17997
|
+
}
|
|
17998
|
+
return false;
|
|
17999
|
+
} catch (error) {
|
|
18000
|
+
console.warn(
|
|
18001
|
+
`[JsonSubscriptionCredentialStore] antigravity project re-validation failed for account ${accountId}: ` + (error instanceof Error ? error.message : String(error))
|
|
18002
|
+
);
|
|
18003
|
+
return false;
|
|
18004
|
+
}
|
|
18005
|
+
}
|
|
17337
18006
|
/**
|
|
17338
18007
|
* Refresh a SPECIFIC managed account by id (background scheduler sweep and
|
|
17339
18008
|
* account-pool resolution). It uses only that account's stored refresh
|
|
@@ -17362,6 +18031,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17362
18031
|
};
|
|
17363
18032
|
if (refreshed.idToken) next.idToken = refreshed.idToken;
|
|
17364
18033
|
this.writeBackById(provider, id, next);
|
|
18034
|
+
if (provider === "antigravity") await this.revalidateAntigravityProject(id);
|
|
17365
18035
|
return true;
|
|
17366
18036
|
} catch (error) {
|
|
17367
18037
|
this.markExpiredById(provider, id, captured, error);
|
|
@@ -17386,7 +18056,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17386
18056
|
}
|
|
17387
18057
|
const oauth = account.tokens;
|
|
17388
18058
|
if (!oauth.accessToken) return null;
|
|
17389
|
-
if (providerId === "codex" || providerId === "gemini" || providerId === "kimi" || providerId === "grok" || providerId === "copilot") {
|
|
18059
|
+
if (providerId === "codex" || providerId === "gemini" || providerId === "kimi" || providerId === "grok" || providerId === "copilot" || providerId === "antigravity") {
|
|
17390
18060
|
const expiresAtMs = oauth.expiresAt ? Date.parse(oauth.expiresAt) : 0;
|
|
17391
18061
|
const expiringSoon = expiresAtMs > 0 && Date.now() >= expiresAtMs - ACCOUNT_REFRESH_LEAD_MS;
|
|
17392
18062
|
if (expiringSoon && oauth.refreshToken) {
|
|
@@ -17502,6 +18172,13 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17502
18172
|
if (provider === "copilot") {
|
|
17503
18173
|
throw new Error("GitHub Copilot tokens cannot be refreshed \u2014 re-authenticate the account");
|
|
17504
18174
|
}
|
|
18175
|
+
if (provider === "antigravity") {
|
|
18176
|
+
const r2 = await antigravityOAuth2.refreshAccessToken(refreshToken, refreshFetch);
|
|
18177
|
+
return {
|
|
18178
|
+
accessToken: r2.accessToken,
|
|
18179
|
+
expiresAt: new Date(Date.now() + r2.expiresIn * 1e3).toISOString()
|
|
18180
|
+
};
|
|
18181
|
+
}
|
|
17505
18182
|
const flow = provider === "claude" ? claudeOAuth2 : provider === "codex" ? codexOAuth2 : geminiOAuth2;
|
|
17506
18183
|
const r = await flow.refreshAccessToken(refreshToken, refreshFetch);
|
|
17507
18184
|
return {
|
|
@@ -17745,7 +18422,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17745
18422
|
};
|
|
17746
18423
|
|
|
17747
18424
|
// src/AccountHealthProbeScheduler.ts
|
|
17748
|
-
import { fetchUpstream as
|
|
18425
|
+
import { fetchUpstream as fetchUpstream13 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
17749
18426
|
|
|
17750
18427
|
// src/probe/CodexGenerationProbe.ts
|
|
17751
18428
|
import {
|
|
@@ -17900,7 +18577,11 @@ var PROVIDER_PROBE_PLANS = {
|
|
|
17900
18577
|
// The Copilot quota endpoint (copilot_internal/user) is a verified FREE
|
|
17901
18578
|
// authed GET but lives on api.github.com with its own auth dialect and a
|
|
17902
18579
|
// monthly-only window — the allowance collector owns the health surface.
|
|
17903
|
-
copilot: { kind: "local" }
|
|
18580
|
+
copilot: { kind: "local" },
|
|
18581
|
+
// Antigravity's quota endpoints are POST RPCs on daily-cloudcode-pa (not a
|
|
18582
|
+
// cheap GET) and need the antigravity/hub UA — the allowance collector owns
|
|
18583
|
+
// the health surface; the probe stays local.
|
|
18584
|
+
antigravity: { kind: "local" }
|
|
17904
18585
|
};
|
|
17905
18586
|
function probePlanFor(providerId) {
|
|
17906
18587
|
return PROVIDER_PROBE_PLANS[providerId] ?? { kind: "local" };
|
|
@@ -17922,7 +18603,7 @@ var AccountHealthProbeScheduler = class {
|
|
|
17922
18603
|
this.logger = logger;
|
|
17923
18604
|
this.config = config;
|
|
17924
18605
|
this.now = opts.now ?? Date.now;
|
|
17925
|
-
this.fetchImpl = opts.fetchImpl ??
|
|
18606
|
+
this.fetchImpl = opts.fetchImpl ?? fetchUpstream13;
|
|
17926
18607
|
this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
17927
18608
|
this.planFor = opts.planFor ?? probePlanFor;
|
|
17928
18609
|
}
|
|
@@ -19627,7 +20308,7 @@ var AuditWriter = class {
|
|
|
19627
20308
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync8 } from "fs";
|
|
19628
20309
|
import { createHmac as createHmac5 } from "crypto";
|
|
19629
20310
|
import { join as join26 } from "path";
|
|
19630
|
-
import { fetchUpstream as
|
|
20311
|
+
import { fetchUpstream as fetchUpstream14 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
19631
20312
|
|
|
19632
20313
|
// src/billing/billingFiles.ts
|
|
19633
20314
|
var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
|
|
@@ -19650,7 +20331,7 @@ var BillingPublisher = class {
|
|
|
19650
20331
|
constructor(billingDir, logger, opts = {}) {
|
|
19651
20332
|
this.billingDir = billingDir;
|
|
19652
20333
|
this.logger = logger;
|
|
19653
|
-
this.fetchImpl = opts.fetchImpl ?? ((url, init) =>
|
|
20334
|
+
this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream14(url, init));
|
|
19654
20335
|
this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
|
|
19655
20336
|
this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
|
|
19656
20337
|
this.now = opts.now ?? Date.now;
|
|
@@ -19900,7 +20581,7 @@ var BillingRetrySweeper = class {
|
|
|
19900
20581
|
// src/TokenRefreshScheduler.ts
|
|
19901
20582
|
var REFRESH_LEAD_MS2 = 5 * 6e4;
|
|
19902
20583
|
var SWEEP_INTERVAL_MS5 = 6e4;
|
|
19903
|
-
var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot"];
|
|
20584
|
+
var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot", "antigravity"];
|
|
19904
20585
|
var TokenRefreshScheduler = class {
|
|
19905
20586
|
constructor(store, logger, intervalMs = SWEEP_INTERVAL_MS5, leadMs = REFRESH_LEAD_MS2) {
|
|
19906
20587
|
this.store = store;
|
|
@@ -19991,6 +20672,8 @@ var TokenRefreshScheduler = class {
|
|
|
19991
20672
|
// never reaches this — the branch exists for union totality.
|
|
19992
20673
|
case "copilot":
|
|
19993
20674
|
return this.store.refreshCopilotToken();
|
|
20675
|
+
case "antigravity":
|
|
20676
|
+
return this.store.refreshAntigravityToken();
|
|
19994
20677
|
}
|
|
19995
20678
|
}
|
|
19996
20679
|
};
|
|
@@ -20069,7 +20752,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
|
|
|
20069
20752
|
|
|
20070
20753
|
// src/webhook/WebhookDispatcher.ts
|
|
20071
20754
|
import { createHmac as createHmac6 } from "crypto";
|
|
20072
|
-
import { fetchUpstream as
|
|
20755
|
+
import { fetchUpstream as fetchUpstream15 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
20073
20756
|
var WEBHOOK_MAX_ATTEMPTS = 3;
|
|
20074
20757
|
var WEBHOOK_QUEUE_MAX = 1e3;
|
|
20075
20758
|
var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
|
|
@@ -20089,7 +20772,7 @@ var WebhookDispatcher = class {
|
|
|
20089
20772
|
sleep;
|
|
20090
20773
|
now;
|
|
20091
20774
|
constructor(opts = {}) {
|
|
20092
|
-
this.fetchImpl = opts.fetchImpl ?? ((url, init) =>
|
|
20775
|
+
this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream15(url, init));
|
|
20093
20776
|
this.logger = opts.logger;
|
|
20094
20777
|
this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
|
|
20095
20778
|
this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
|
|
@@ -20175,8 +20858,8 @@ var WebhookDispatcher = class {
|
|
|
20175
20858
|
signal: AbortSignal.timeout(this.timeoutMs)
|
|
20176
20859
|
});
|
|
20177
20860
|
return res.ok ? { ok: true, status: res.status } : { ok: false, status: res.status };
|
|
20178
|
-
} catch (
|
|
20179
|
-
return { ok: false, error:
|
|
20861
|
+
} catch (err9) {
|
|
20862
|
+
return { ok: false, error: err9 instanceof Error ? err9.message : String(err9) };
|
|
20180
20863
|
}
|
|
20181
20864
|
}
|
|
20182
20865
|
/**
|
|
@@ -20318,7 +21001,7 @@ function buildDaemon(config, paths) {
|
|
|
20318
21001
|
setSecretBox(secretBox3);
|
|
20319
21002
|
setSecretBox2(secretBox3);
|
|
20320
21003
|
const decryptedConfig = decryptConfigSecrets(config, secretBox3);
|
|
20321
|
-
const accountAllowanceStore = new
|
|
21004
|
+
const accountAllowanceStore = new AccountAllowanceStore10(
|
|
20322
21005
|
Date.now,
|
|
20323
21006
|
void 0,
|
|
20324
21007
|
new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
|
|
@@ -20362,6 +21045,8 @@ function buildDaemon(config, paths) {
|
|
|
20362
21045
|
})
|
|
20363
21046
|
);
|
|
20364
21047
|
setGeminiCodeAssistResolver(getGeminiCodeAssistProjectResolver2());
|
|
21048
|
+
setAntigravitySandboxFailover(decryptedConfig.antigravity?.sandboxFailover === true);
|
|
21049
|
+
setOpenCodeGoUserAgent(decryptedConfig.opencodego?.userAgent ?? null);
|
|
20365
21050
|
const autoDisableStore = new AutoDisableStore();
|
|
20366
21051
|
const providerKeyQuotaService = new ProviderKeyQuotaService(secretBox3);
|
|
20367
21052
|
const apiKeyPool = new ApiKeyPoolService(
|
|
@@ -20380,7 +21065,7 @@ function buildDaemon(config, paths) {
|
|
|
20380
21065
|
const pricingEngine = new PricingEngine(pricingStore, logger, {
|
|
20381
21066
|
// Catalog egress follows the same global/env proxy policy as every other
|
|
20382
21067
|
// daemon upstream call; no provider/account override applies here.
|
|
20383
|
-
fetchImpl: ((input, init) =>
|
|
21068
|
+
fetchImpl: ((input, init) => fetchUpstream16(String(input), init ?? {}))
|
|
20384
21069
|
});
|
|
20385
21070
|
const pricingRefreshScheduler = new PricingRefreshScheduler(
|
|
20386
21071
|
pricingEngine,
|
|
@@ -20665,7 +21350,7 @@ function buildDaemon(config, paths) {
|
|
|
20665
21350
|
// — `server.proxy.byProvider[...]` was silently skipped — and the call was
|
|
20666
21351
|
// excluded from the upstream trace, so a failing login left no evidence.
|
|
20667
21352
|
// `redactBodies` keeps the code/verifier + minted token out of that trace.
|
|
20668
|
-
oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) =>
|
|
21353
|
+
oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => fetchUpstream16(url, init, { providerId, redactBodies: true }),
|
|
20669
21354
|
subscriptionAccountAppender: credentialStore,
|
|
20670
21355
|
// Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
|
|
20671
21356
|
// + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
|
|
@@ -20680,6 +21365,21 @@ function buildDaemon(config, paths) {
|
|
|
20680
21365
|
// Grok interactive OAuth — the same async DEVICE-CODE shape as kimi.
|
|
20681
21366
|
grokSessions: new CodexOAuthSessionStore(),
|
|
20682
21367
|
copilotSessions: new CodexOAuthSessionStore(),
|
|
21368
|
+
// Antigravity interactive OAuth — the async LOOPBACK flow store + the
|
|
21369
|
+
// one-shot 127.0.0.1:51121 listener (same shape as codex; test seam below).
|
|
21370
|
+
antigravitySessions: new CodexOAuthSessionStore(),
|
|
21371
|
+
antigravityAwaitLoopback: paths.antigravityAwaitLoopback ?? ((state, timeoutMs, signal) => awaitLoopbackCode(state, timeoutMs, signal, {
|
|
21372
|
+
port: 51121,
|
|
21373
|
+
path: "/oauth-callback",
|
|
21374
|
+
label: "antigravity"
|
|
21375
|
+
})),
|
|
21376
|
+
// The dynamic model-catalog probe's token source (the ACTIVE antigravity
|
|
21377
|
+
// account; refreshed by the by-id near-expiry seam inside the lookup).
|
|
21378
|
+
resolveAntigravityAccessToken: async () => {
|
|
21379
|
+
const config2 = await credentialStore.getFullConfig();
|
|
21380
|
+
const activeId = config2.activeAntigravityAccountId ?? config2.antigravityAccounts?.[0]?.id;
|
|
21381
|
+
return activeId ? credentialStore.getAccessTokenForAccount("antigravity", activeId) : null;
|
|
21382
|
+
},
|
|
20683
21383
|
// Migration pack (app-parity child 6, design D2/D3) — the concrete credential
|
|
20684
21384
|
// store provides BOTH the full DECRYPTED read (`getFullConfig`, export) and
|
|
20685
21385
|
// the multi-account append (`appendProviderAccount`, import re-encrypts at-
|
|
@@ -20738,7 +21438,7 @@ function buildDaemon(config, paths) {
|
|
|
20738
21438
|
});
|
|
20739
21439
|
const webhookDispatcher = new WebhookDispatcher({
|
|
20740
21440
|
logger,
|
|
20741
|
-
fetchImpl: (url, init) =>
|
|
21441
|
+
fetchImpl: (url, init) => fetchUpstream16(url, init)
|
|
20742
21442
|
});
|
|
20743
21443
|
setWebhookRuntime(webhookDispatcher, getSharedAccountHealth4());
|
|
20744
21444
|
const auditWriter = new AuditWriter(auditDir, logger);
|