@omnicross/daemon 0.4.2 → 0.4.4
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 +1193 -281
- package/dist/cli.js +1141 -221
- package/dist/index.cjs +986 -238
- package/dist/index.d.cts +1588 -1386
- package/dist/index.d.ts +1588 -1386
- package/dist/index.js +954 -199
- 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");
|
|
@@ -7466,7 +8007,7 @@ async function handleAdminApi(req, res, path2, deps) {
|
|
|
7466
8007
|
case "server":
|
|
7467
8008
|
return await handleServer(req, res, method, deps);
|
|
7468
8009
|
case "images":
|
|
7469
|
-
return await handleImages(res, method, rest, deps);
|
|
8010
|
+
return await handleImages(req, res, method, rest, deps);
|
|
7470
8011
|
case "search":
|
|
7471
8012
|
return await handleSearchAdmin(req, res, method, rest, deps);
|
|
7472
8013
|
case "accounts":
|
|
@@ -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
|
}
|
|
@@ -9003,7 +9554,41 @@ function imageEndpointUrls(base) {
|
|
|
9003
9554
|
edits: `${base}/v1/images/edits`
|
|
9004
9555
|
}) : null;
|
|
9005
9556
|
}
|
|
9006
|
-
|
|
9557
|
+
function imageProviderEvidence(images, capabilities) {
|
|
9558
|
+
const evidenceAt = safeStatusTimestamp(capabilities?.oldestEvidenceAt);
|
|
9559
|
+
const resolvedAt = safeStatusTimestamp(capabilities?.resolvedAt);
|
|
9560
|
+
if (evidenceAt === void 0 || resolvedAt === void 0) return null;
|
|
9561
|
+
const expiresAt = evidenceAt <= Number.MAX_SAFE_INTEGER - images.evidenceTtlMs ? evidenceAt + images.evidenceTtlMs : void 0;
|
|
9562
|
+
return Object.freeze({
|
|
9563
|
+
verifiedAt: evidenceAt,
|
|
9564
|
+
ageMs: Math.max(0, resolvedAt - evidenceAt),
|
|
9565
|
+
...expiresAt !== void 0 ? { expiresAt } : {}
|
|
9566
|
+
});
|
|
9567
|
+
}
|
|
9568
|
+
async function handleImagesVerifyLive(req, res, deps) {
|
|
9569
|
+
const verifier = deps.imageLiveVerifier;
|
|
9570
|
+
if (!verifier) {
|
|
9571
|
+
return writeJsonError(res, 501, "Images live verification is not available");
|
|
9572
|
+
}
|
|
9573
|
+
const serverConfig = await loadServerConfig3(deps.settingsStore);
|
|
9574
|
+
const images = serverConfig.images ?? DEFAULT_IMAGES_SERVER_CONFIG;
|
|
9575
|
+
req.resume();
|
|
9576
|
+
const controller = new AbortController();
|
|
9577
|
+
req.on("close", () => controller.abort());
|
|
9578
|
+
const result = await verifier.verifyLive(images, controller.signal);
|
|
9579
|
+
const antigravityRouted = Object.values(images.models).includes("antigravity-subscription");
|
|
9580
|
+
return writeJson4(res, 200, {
|
|
9581
|
+
...result,
|
|
9582
|
+
...antigravityRouted ? { antigravityDeferred: true } : {}
|
|
9583
|
+
});
|
|
9584
|
+
}
|
|
9585
|
+
async function handleImages(req, res, method, rest, deps) {
|
|
9586
|
+
if (rest.length === 1 && rest[0] === "verify-live") {
|
|
9587
|
+
if (method !== "POST") {
|
|
9588
|
+
return writeJsonError(res, 405, `method ${method} not allowed on Images verify-live`);
|
|
9589
|
+
}
|
|
9590
|
+
return handleImagesVerifyLive(req, res, deps);
|
|
9591
|
+
}
|
|
9007
9592
|
if (rest.length !== 1 || rest[0] !== "capabilities") {
|
|
9008
9593
|
return writeJsonError(res, 404, "unknown Images admin resource");
|
|
9009
9594
|
}
|
|
@@ -9018,14 +9603,14 @@ async function handleImages(res, method, rest, deps) {
|
|
|
9018
9603
|
const capability = await reader.inspectCapability(IMAGE_ADMIN_STATUS_TENANT);
|
|
9019
9604
|
const resources = safeRuntimeResources(reader.resourceStatus());
|
|
9020
9605
|
const outbound = deps.outboundApiServer.getStatus();
|
|
9021
|
-
const
|
|
9022
|
-
const
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
})
|
|
9606
|
+
const evidence = imageProviderEvidence(images, capability.capabilities);
|
|
9607
|
+
const providers = (capability.providers ?? []).map((provider) => Object.freeze({
|
|
9608
|
+
providerId: provider.providerId,
|
|
9609
|
+
available: provider.available === true,
|
|
9610
|
+
reason: provider.available ? null : safeImageCapabilityReason(provider.reason),
|
|
9611
|
+
models: Object.freeze([...provider.models]),
|
|
9612
|
+
evidence: imageProviderEvidence(images, provider.capabilities)
|
|
9613
|
+
}));
|
|
9029
9614
|
const draining = lifecycle.draining.map((generation) => Object.freeze({
|
|
9030
9615
|
generationId: safeImageGenerationId(generation.generationId),
|
|
9031
9616
|
enabled: generation.enabled,
|
|
@@ -9035,7 +9620,7 @@ async function handleImages(res, method, rest, deps) {
|
|
|
9035
9620
|
return writeJson4(res, 200, {
|
|
9036
9621
|
configured: {
|
|
9037
9622
|
enabled: images.enabled,
|
|
9038
|
-
provider: images.
|
|
9623
|
+
provider: images.models[images.defaultModel] ?? "codex-subscription",
|
|
9039
9624
|
model: images.defaultModel,
|
|
9040
9625
|
remoteUrlsEnabled: images.remote.enabled,
|
|
9041
9626
|
referenceTtlMs: images.references.ttlMs
|
|
@@ -9046,6 +9631,7 @@ async function handleImages(res, method, rest, deps) {
|
|
|
9046
9631
|
evidence,
|
|
9047
9632
|
features: safeCapabilityValues(capability.capabilities, images.defaultModel)
|
|
9048
9633
|
},
|
|
9634
|
+
providers,
|
|
9049
9635
|
runtime: {
|
|
9050
9636
|
disposed: lifecycle.disposed,
|
|
9051
9637
|
generationId: safeImageGenerationId(lifecycle.current.generationId),
|
|
@@ -9135,12 +9721,12 @@ async function handlePlayground(req, res, method, deps) {
|
|
|
9135
9721
|
const payload = body["body"];
|
|
9136
9722
|
const status = deps.outboundApiServer.getStatus();
|
|
9137
9723
|
if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
|
|
9138
|
-
const path2 = resolvePlaygroundPath(endpoint,
|
|
9724
|
+
const path2 = resolvePlaygroundPath(endpoint, isRecord9(payload) ? payload : {});
|
|
9139
9725
|
if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
|
|
9140
9726
|
const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
|
|
9141
9727
|
await proxyToOutbound(res, status.port, path2, key, upstreamBody);
|
|
9142
9728
|
}
|
|
9143
|
-
function
|
|
9729
|
+
function isRecord9(v) {
|
|
9144
9730
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
9145
9731
|
}
|
|
9146
9732
|
function proxyToOutbound(res, outboundPort, path2, key, body) {
|
|
@@ -9169,8 +9755,8 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
|
|
|
9169
9755
|
});
|
|
9170
9756
|
}
|
|
9171
9757
|
);
|
|
9172
|
-
upstream.on("error", (
|
|
9173
|
-
if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${
|
|
9758
|
+
upstream.on("error", (err9) => {
|
|
9759
|
+
if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${err9.message}`);
|
|
9174
9760
|
else res.end();
|
|
9175
9761
|
resolve10();
|
|
9176
9762
|
});
|
|
@@ -9275,7 +9861,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
|
|
|
9275
9861
|
}
|
|
9276
9862
|
|
|
9277
9863
|
// src/admin/version.ts
|
|
9278
|
-
var DAEMON_VERSION = true ? "0.4.
|
|
9864
|
+
var DAEMON_VERSION = true ? "0.4.4" : "0.0.0-dev";
|
|
9279
9865
|
|
|
9280
9866
|
// src/admin/AdminServer.ts
|
|
9281
9867
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
@@ -9318,13 +9904,13 @@ var AdminServer = class {
|
|
|
9318
9904
|
const server = http2.createServer((req, res) => {
|
|
9319
9905
|
this.onRequest(req, res);
|
|
9320
9906
|
});
|
|
9321
|
-
const onError = (
|
|
9322
|
-
if (
|
|
9907
|
+
const onError = (err9) => {
|
|
9908
|
+
if (err9.code === "EADDRINUSE" && port !== 0) {
|
|
9323
9909
|
server.removeListener("error", onError);
|
|
9324
9910
|
this.listen(bindAddr, 0).then(resolve10, reject);
|
|
9325
9911
|
return;
|
|
9326
9912
|
}
|
|
9327
|
-
reject(
|
|
9913
|
+
reject(err9);
|
|
9328
9914
|
};
|
|
9329
9915
|
server.on("error", onError);
|
|
9330
9916
|
server.listen(port, bindAddr, () => {
|
|
@@ -9342,8 +9928,8 @@ var AdminServer = class {
|
|
|
9342
9928
|
}
|
|
9343
9929
|
/** Per-request handler: auth gate (when a token is set) → routing. */
|
|
9344
9930
|
onRequest(req, res) {
|
|
9345
|
-
void this.dispatch(req, res).catch((
|
|
9346
|
-
const message =
|
|
9931
|
+
void this.dispatch(req, res).catch((err9) => {
|
|
9932
|
+
const message = err9 instanceof Error ? err9.message : String(err9);
|
|
9347
9933
|
this.deps.logger.error("[AdminServer] unhandled error:", message);
|
|
9348
9934
|
if (!res.headersSent) {
|
|
9349
9935
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
@@ -9566,7 +10152,10 @@ var HTML_HEADERS = {
|
|
|
9566
10152
|
function pageHtml(message) {
|
|
9567
10153
|
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
10154
|
}
|
|
9569
|
-
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
|
|
10155
|
+
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal, binding = {}) {
|
|
10156
|
+
const port = binding.port ?? LOOPBACK_PORT;
|
|
10157
|
+
const callbackPath = binding.path ?? CALLBACK_PATH;
|
|
10158
|
+
const label = binding.label ?? "codex";
|
|
9570
10159
|
return new Promise((resolve10, reject) => {
|
|
9571
10160
|
let settled = false;
|
|
9572
10161
|
const finish = (server2, fn) => {
|
|
@@ -9577,8 +10166,8 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
|
|
|
9577
10166
|
server2.close();
|
|
9578
10167
|
};
|
|
9579
10168
|
const server = createServer2((req, res) => {
|
|
9580
|
-
const url = new URL(req.url ?? "", `http://${LOOPBACK_HOST}:${
|
|
9581
|
-
if (url.pathname !==
|
|
10169
|
+
const url = new URL(req.url ?? "", `http://${LOOPBACK_HOST}:${port}`);
|
|
10170
|
+
if (url.pathname !== callbackPath) {
|
|
9582
10171
|
res.writeHead(404, HTML_HEADERS);
|
|
9583
10172
|
res.end(pageHtml("Not found"));
|
|
9584
10173
|
return;
|
|
@@ -9607,25 +10196,25 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
|
|
|
9607
10196
|
return;
|
|
9608
10197
|
}
|
|
9609
10198
|
signal?.addEventListener("abort", abort, { once: true });
|
|
9610
|
-
server.on("error", (
|
|
10199
|
+
server.on("error", (err9) => {
|
|
9611
10200
|
if (settled) return;
|
|
9612
10201
|
settled = true;
|
|
9613
10202
|
clearTimeout(timer);
|
|
9614
|
-
if (
|
|
10203
|
+
if (err9.code === "EADDRINUSE") {
|
|
9615
10204
|
reject(
|
|
9616
10205
|
new Error(
|
|
9617
|
-
`login: cannot bind ${LOOPBACK_HOST}:${
|
|
10206
|
+
`login: cannot bind ${LOOPBACK_HOST}:${port} (address in use) \u2014 another ${label} login or process is holding the port`
|
|
9618
10207
|
)
|
|
9619
10208
|
);
|
|
9620
10209
|
} else {
|
|
9621
|
-
reject(
|
|
10210
|
+
reject(err9);
|
|
9622
10211
|
}
|
|
9623
10212
|
});
|
|
9624
10213
|
const timer = setTimeout(() => {
|
|
9625
10214
|
finish(server, () => reject(new Error(`login: timed out after ${Math.round(timeoutMs / 1e3)}s waiting for the callback`)));
|
|
9626
10215
|
}, timeoutMs);
|
|
9627
10216
|
if (typeof timer.unref === "function") timer.unref();
|
|
9628
|
-
server.listen(
|
|
10217
|
+
server.listen(port, LOOPBACK_HOST);
|
|
9629
10218
|
});
|
|
9630
10219
|
}
|
|
9631
10220
|
|
|
@@ -9695,7 +10284,7 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
|
|
|
9695
10284
|
|
|
9696
10285
|
// src/allowance/ProviderKeyQuotaService.ts
|
|
9697
10286
|
import { mergeExtraHeaders as mergeExtraHeaders2 } from "@omnicross/core";
|
|
9698
|
-
import { fetchUpstream as
|
|
10287
|
+
import { fetchUpstream as fetchUpstream11 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
9699
10288
|
|
|
9700
10289
|
// src/allowance/ProviderKeyQuota.ts
|
|
9701
10290
|
var MINUTE_MS3 = 6e4;
|
|
@@ -9724,11 +10313,11 @@ function isoInstant3(value) {
|
|
|
9724
10313
|
}
|
|
9725
10314
|
return void 0;
|
|
9726
10315
|
}
|
|
9727
|
-
function
|
|
10316
|
+
function secondsUntil9(instant, now) {
|
|
9728
10317
|
if (!instant) return void 0;
|
|
9729
10318
|
return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
|
|
9730
10319
|
}
|
|
9731
|
-
function
|
|
10320
|
+
function isRecord10(value) {
|
|
9732
10321
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9733
10322
|
}
|
|
9734
10323
|
function detectProviderKeyQuotaAdapter(baseUrl) {
|
|
@@ -9795,17 +10384,17 @@ function zaiWindowIdLabel(durationMs) {
|
|
|
9795
10384
|
return { id: "quota", label: "Quota" };
|
|
9796
10385
|
}
|
|
9797
10386
|
function parseZaiQuotaPayload(payload, now) {
|
|
9798
|
-
if (!
|
|
9799
|
-
const data =
|
|
10387
|
+
if (!isRecord10(payload)) return null;
|
|
10388
|
+
const data = isRecord10(payload["data"]) ? payload["data"] : payload;
|
|
9800
10389
|
if (payload["success"] === false) return null;
|
|
9801
10390
|
const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
|
|
9802
10391
|
const byWindow = /* @__PURE__ */ new Map();
|
|
9803
10392
|
for (const raw of limits) {
|
|
9804
|
-
if (!
|
|
10393
|
+
if (!isRecord10(raw)) continue;
|
|
9805
10394
|
const item = raw;
|
|
9806
10395
|
if (item.type === void 0) continue;
|
|
9807
10396
|
const details = raw["usageDetails"];
|
|
9808
|
-
if (Array.isArray(details) && details.some((d) =>
|
|
10397
|
+
if (Array.isArray(details) && details.some((d) => isRecord10(d) && d["modelCode"] === "zread")) {
|
|
9809
10398
|
continue;
|
|
9810
10399
|
}
|
|
9811
10400
|
const durationMs = zaiWindowDurationMs(item);
|
|
@@ -9824,7 +10413,7 @@ function parseZaiQuotaPayload(payload, now) {
|
|
|
9824
10413
|
usedPercent,
|
|
9825
10414
|
...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS3) } : {},
|
|
9826
10415
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9827
|
-
remainingSeconds:
|
|
10416
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9828
10417
|
state: "fresh"
|
|
9829
10418
|
};
|
|
9830
10419
|
const existing = byWindow.get(id);
|
|
@@ -9838,7 +10427,7 @@ function parseZaiQuotaPayload(payload, now) {
|
|
|
9838
10427
|
var MINIMAX_STATUS_EXHAUSTED = 2;
|
|
9839
10428
|
var MINIMAX_SHARED_BUCKET = "general";
|
|
9840
10429
|
function parseMiniMaxBucket(value) {
|
|
9841
|
-
if (!
|
|
10430
|
+
if (!isRecord10(value)) return null;
|
|
9842
10431
|
const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
|
|
9843
10432
|
if (!modelName) return null;
|
|
9844
10433
|
const instant = (v) => {
|
|
@@ -9865,14 +10454,14 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
|
|
|
9865
10454
|
usedPercent,
|
|
9866
10455
|
...windowMinutes !== void 0 ? { windowMinutes } : {},
|
|
9867
10456
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9868
|
-
remainingSeconds:
|
|
10457
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9869
10458
|
state: usedPercent !== null ? "fresh" : "unavailable"
|
|
9870
10459
|
};
|
|
9871
10460
|
}
|
|
9872
10461
|
function parseMiniMaxTokenPlanPayload(payload, now) {
|
|
9873
|
-
if (!
|
|
10462
|
+
if (!isRecord10(payload)) return null;
|
|
9874
10463
|
const baseResp = payload["base_resp"];
|
|
9875
|
-
if (!
|
|
10464
|
+
if (!isRecord10(baseResp) || baseResp["status_code"] !== 0) return null;
|
|
9876
10465
|
const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
|
|
9877
10466
|
let general = null;
|
|
9878
10467
|
for (const raw of buckets) {
|
|
@@ -9905,11 +10494,11 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
|
|
|
9905
10494
|
];
|
|
9906
10495
|
}
|
|
9907
10496
|
function parseUmansUsagePayload(payload, now) {
|
|
9908
|
-
if (!
|
|
9909
|
-
const limits =
|
|
9910
|
-
const requests = limits &&
|
|
9911
|
-
const usage =
|
|
9912
|
-
const window =
|
|
10497
|
+
if (!isRecord10(payload)) return null;
|
|
10498
|
+
const limits = isRecord10(payload["limits"]) ? payload["limits"] : void 0;
|
|
10499
|
+
const requests = limits && isRecord10(limits["requests"]) ? limits["requests"] : void 0;
|
|
10500
|
+
const usage = isRecord10(payload["usage"]) ? payload["usage"] : void 0;
|
|
10501
|
+
const window = isRecord10(payload["window"]) ? payload["window"] : void 0;
|
|
9913
10502
|
const hardCap = finiteNumber5(requests?.["hard_cap"]);
|
|
9914
10503
|
const softLimit = finiteNumber5(requests?.["limit"]);
|
|
9915
10504
|
const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
|
|
@@ -9930,15 +10519,15 @@ function parseUmansUsagePayload(payload, now) {
|
|
|
9930
10519
|
usedPercent,
|
|
9931
10520
|
windowMinutes: 5 * 60,
|
|
9932
10521
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9933
|
-
remainingSeconds:
|
|
10522
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9934
10523
|
state: "fresh"
|
|
9935
10524
|
}
|
|
9936
10525
|
];
|
|
9937
10526
|
}
|
|
9938
10527
|
function parseSyntheticQuotasPayload(payload, now) {
|
|
9939
|
-
if (!
|
|
9940
|
-
const fiveHour =
|
|
9941
|
-
const weekly =
|
|
10528
|
+
if (!isRecord10(payload)) return null;
|
|
10529
|
+
const fiveHour = isRecord10(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
|
|
10530
|
+
const weekly = isRecord10(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
|
|
9942
10531
|
const windows = [];
|
|
9943
10532
|
if (fiveHour) {
|
|
9944
10533
|
const max = finiteNumber5(fiveHour["max"]);
|
|
@@ -9952,7 +10541,7 @@ function parseSyntheticQuotasPayload(payload, now) {
|
|
|
9952
10541
|
usedPercent,
|
|
9953
10542
|
windowMinutes: 5 * 60,
|
|
9954
10543
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9955
|
-
remainingSeconds:
|
|
10544
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9956
10545
|
state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
|
|
9957
10546
|
});
|
|
9958
10547
|
}
|
|
@@ -9967,7 +10556,7 @@ function parseSyntheticQuotasPayload(payload, now) {
|
|
|
9967
10556
|
usedPercent,
|
|
9968
10557
|
windowMinutes: 7 * 24 * 60,
|
|
9969
10558
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
9970
|
-
remainingSeconds:
|
|
10559
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
9971
10560
|
state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
|
|
9972
10561
|
});
|
|
9973
10562
|
}
|
|
@@ -9979,12 +10568,12 @@ var CLINE_WINDOW_CONFIG = {
|
|
|
9979
10568
|
monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
|
|
9980
10569
|
};
|
|
9981
10570
|
function parseClinePassUsageLimitsPayload(payload, now) {
|
|
9982
|
-
if (!
|
|
9983
|
-
const data =
|
|
10571
|
+
if (!isRecord10(payload)) return null;
|
|
10572
|
+
const data = isRecord10(payload["data"]) ? payload["data"] : payload;
|
|
9984
10573
|
const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
|
|
9985
10574
|
const windows = [];
|
|
9986
10575
|
for (const raw of limits) {
|
|
9987
|
-
if (!
|
|
10576
|
+
if (!isRecord10(raw)) continue;
|
|
9988
10577
|
const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
|
|
9989
10578
|
if (!config) continue;
|
|
9990
10579
|
const usedPercent = finitePercent4(raw["percentUsed"]);
|
|
@@ -9997,7 +10586,7 @@ function parseClinePassUsageLimitsPayload(payload, now) {
|
|
|
9997
10586
|
usedPercent,
|
|
9998
10587
|
windowMinutes: config.minutes,
|
|
9999
10588
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
10000
|
-
remainingSeconds:
|
|
10589
|
+
remainingSeconds: secondsUntil9(resetsAt, now),
|
|
10001
10590
|
state: "fresh"
|
|
10002
10591
|
});
|
|
10003
10592
|
}
|
|
@@ -10036,7 +10625,7 @@ function rowKeyEntries(row) {
|
|
|
10036
10625
|
return [];
|
|
10037
10626
|
}
|
|
10038
10627
|
var ProviderKeyQuotaService = class {
|
|
10039
|
-
constructor(box, fetchImpl = (url, init) =>
|
|
10628
|
+
constructor(box, fetchImpl = (url, init) => fetchUpstream11(url, init, { redactBodies: true }), now = Date.now) {
|
|
10040
10629
|
this.box = box;
|
|
10041
10630
|
this.fetchImpl = fetchImpl;
|
|
10042
10631
|
this.now = now;
|
|
@@ -10643,12 +11232,12 @@ function createImageDoctorService(options) {
|
|
|
10643
11232
|
authStrategy: strategy,
|
|
10644
11233
|
generationTimeoutMs: config.queue.generationTimeoutMs
|
|
10645
11234
|
}));
|
|
10646
|
-
const readAccount = async () => {
|
|
10647
|
-
const
|
|
11235
|
+
const readAccount = async (providerId) => {
|
|
11236
|
+
const entry = (await options.subscriptionAccounts.listAll()).find((candidate) => candidate.providerId === providerId);
|
|
10648
11237
|
return Object.freeze({
|
|
10649
|
-
present:
|
|
10650
|
-
usable:
|
|
10651
|
-
reason:
|
|
11238
|
+
present: entry !== void 0,
|
|
11239
|
+
usable: entry?.credentialStatus.ok === true,
|
|
11240
|
+
reason: entry === void 0 ? "missing" : entry.credentialStatus.ok ? "ready" : "unavailable"
|
|
10652
11241
|
});
|
|
10653
11242
|
};
|
|
10654
11243
|
const activePaths = () => options.storageCatalog.active().resolver;
|
|
@@ -10686,6 +11275,7 @@ function createImageDoctorService(options) {
|
|
|
10686
11275
|
} catch {
|
|
10687
11276
|
storesValid = false;
|
|
10688
11277
|
}
|
|
11278
|
+
const antigravityAccount = await readAccount("antigravity");
|
|
10689
11279
|
const rows = await options.keyDb.outboundApiKeysList();
|
|
10690
11280
|
let legacyRows = 0;
|
|
10691
11281
|
let invalidRows = 0;
|
|
@@ -10702,7 +11292,7 @@ function createImageDoctorService(options) {
|
|
|
10702
11292
|
invalidRows += 1;
|
|
10703
11293
|
}
|
|
10704
11294
|
}
|
|
10705
|
-
const account = await readAccount();
|
|
11295
|
+
const account = await readAccount("codex");
|
|
10706
11296
|
let evidence;
|
|
10707
11297
|
let evidenceStore;
|
|
10708
11298
|
try {
|
|
@@ -10716,10 +11306,11 @@ function createImageDoctorService(options) {
|
|
|
10716
11306
|
return Object.freeze({
|
|
10717
11307
|
config: Object.freeze({
|
|
10718
11308
|
enabled: config.enabled,
|
|
10719
|
-
provider: config.
|
|
11309
|
+
provider: config.models[config.defaultModel] ?? "codex-subscription",
|
|
10720
11310
|
model: config.defaultModel,
|
|
10721
11311
|
valid: configErrors.length === 0,
|
|
10722
|
-
errorCount: configErrors.length
|
|
11312
|
+
errorCount: configErrors.length,
|
|
11313
|
+
routedProviders: Object.freeze([...new Set(Object.values(config.models))])
|
|
10723
11314
|
}),
|
|
10724
11315
|
roots: Object.freeze({
|
|
10725
11316
|
valid: verifiedAreas === ROOT_AREAS.length,
|
|
@@ -10744,12 +11335,13 @@ function createImageDoctorService(options) {
|
|
|
10744
11335
|
imagesAuthorizedRows
|
|
10745
11336
|
}),
|
|
10746
11337
|
account,
|
|
11338
|
+
antigravityAccount,
|
|
10747
11339
|
evidence: Object.freeze(evidence)
|
|
10748
11340
|
});
|
|
10749
11341
|
},
|
|
10750
11342
|
verifyLive: async (config, signal) => {
|
|
10751
11343
|
if (!config.enabled) return Object.freeze({ ok: false, code: "images_disabled" });
|
|
10752
|
-
const account = await readAccount();
|
|
11344
|
+
const account = await readAccount("codex");
|
|
10753
11345
|
if (!account.usable) {
|
|
10754
11346
|
return Object.freeze({ ok: false, code: "codex_account_unavailable" });
|
|
10755
11347
|
}
|
|
@@ -11010,6 +11602,7 @@ import {
|
|
|
11010
11602
|
validateImagesServerConfig as validateImagesServerConfig3
|
|
11011
11603
|
} from "@omnicross/core/outbound-api";
|
|
11012
11604
|
import {
|
|
11605
|
+
createAntigravitySubscriptionImageProvider,
|
|
11013
11606
|
createCodexSubscriptionImageProvider
|
|
11014
11607
|
} from "@omnicross/subscriptions";
|
|
11015
11608
|
|
|
@@ -11041,10 +11634,11 @@ function createTrustedImageApiRuntimeResolver(options) {
|
|
|
11041
11634
|
throw new TypeError("enabled image remote loading requires a proven resolver");
|
|
11042
11635
|
}
|
|
11043
11636
|
const hmacKey = Buffer.from(options.hmacKey);
|
|
11044
|
-
const modelAliases = new Map(Object.entries(options.config.
|
|
11637
|
+
const modelAliases = new Map(Object.entries(options.config.aliases));
|
|
11638
|
+
const modelRoutes = new Map(Object.entries(options.config.models));
|
|
11045
11639
|
const limits = Object.freeze({ ...options.config.limits });
|
|
11046
|
-
const providerId = options.config.provider;
|
|
11047
11640
|
const defaultModel = options.config.defaultModel;
|
|
11641
|
+
const providerId = modelRoutes.get(defaultModel) ?? "codex-subscription";
|
|
11048
11642
|
const referenceStore = options.referenceStore;
|
|
11049
11643
|
const retention = Object.freeze({
|
|
11050
11644
|
enabled: true,
|
|
@@ -11065,6 +11659,7 @@ function createTrustedImageApiRuntimeResolver(options) {
|
|
|
11065
11659
|
providerId,
|
|
11066
11660
|
defaultModel,
|
|
11067
11661
|
modelAliases,
|
|
11662
|
+
modelRoutes,
|
|
11068
11663
|
limits,
|
|
11069
11664
|
...preferredAccountId ? { preferredAccountId } : {},
|
|
11070
11665
|
...preferredAccountGroup ? { preferredAccountGroup } : {},
|
|
@@ -11469,7 +12064,9 @@ var GENERATION_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/u;
|
|
|
11469
12064
|
function snapshotConfig(config) {
|
|
11470
12065
|
return {
|
|
11471
12066
|
...config,
|
|
11472
|
-
|
|
12067
|
+
models: { ...config.models },
|
|
12068
|
+
aliases: { ...config.aliases },
|
|
12069
|
+
codex: { ...config.codex },
|
|
11473
12070
|
account: { ...config.account },
|
|
11474
12071
|
queue: { ...config.queue },
|
|
11475
12072
|
temporary: { ...config.temporary },
|
|
@@ -11503,10 +12100,15 @@ function createImageRuntimeGeneration(options) {
|
|
|
11503
12100
|
}
|
|
11504
12101
|
});
|
|
11505
12102
|
}
|
|
11506
|
-
const
|
|
11507
|
-
|
|
12103
|
+
const routedProviders = [...new Set(Object.values(config.models))];
|
|
12104
|
+
const codexStrategy = routedProviders.includes("codex-subscription") ? options.subscriptionAccounts.getStrategy("codex") : void 0;
|
|
12105
|
+
if (routedProviders.includes("codex-subscription") && (!codexStrategy || codexStrategy.providerId !== "codex")) {
|
|
11508
12106
|
throw new TypeError("enabled image runtime requires the Codex subscription strategy");
|
|
11509
12107
|
}
|
|
12108
|
+
const antigravityStrategy = routedProviders.includes("antigravity-subscription") ? options.subscriptionAccounts.getStrategy("antigravity") : void 0;
|
|
12109
|
+
if (routedProviders.includes("antigravity-subscription") && (!antigravityStrategy || antigravityStrategy.providerId !== "antigravity")) {
|
|
12110
|
+
throw new TypeError("enabled image runtime requires the Antigravity subscription strategy");
|
|
12111
|
+
}
|
|
11510
12112
|
const privateHmacKey = options.privateHmacKey ? Buffer.from(options.privateHmacKey) : loadOrCreateImageTenantHmacSalt(options.storage.paths, randomBytes6);
|
|
11511
12113
|
if (privateHmacKey.byteLength !== 32) {
|
|
11512
12114
|
privateHmacKey.fill(0);
|
|
@@ -11541,23 +12143,32 @@ function createImageRuntimeGeneration(options) {
|
|
|
11541
12143
|
if (options.testOnlySyntheticVerifiedProvider && options.testOnlySyntheticVerifiedProvider.label !== "synthetic-verified-image-provider-test-only") {
|
|
11542
12144
|
throw new TypeError("synthetic verified image provider test seam label is invalid");
|
|
11543
12145
|
}
|
|
11544
|
-
const
|
|
12146
|
+
const providers = options.testOnlySyntheticVerifiedProvider ? [options.testOnlySyntheticVerifiedProvider.createProvider({
|
|
11545
12147
|
generationId: options.generationId,
|
|
11546
12148
|
scheduler,
|
|
11547
12149
|
now: options.now ?? Date.now,
|
|
11548
12150
|
referenceStore: options.storage.referenceStore,
|
|
11549
12151
|
stateStore: options.storage.stateStore
|
|
11550
|
-
}) : createCodexSubscriptionImageProvider({
|
|
11551
|
-
authStrategy,
|
|
12152
|
+
})] : routedProviders.map((providerId) => providerId === "codex-subscription" ? createCodexSubscriptionImageProvider({
|
|
12153
|
+
authStrategy: codexStrategy,
|
|
11552
12154
|
evidenceSource: generationEvidenceSource,
|
|
11553
12155
|
executionScheduler: scheduler,
|
|
11554
12156
|
generationTimeoutMs: config.queue.generationTimeoutMs,
|
|
12157
|
+
now: options.now,
|
|
12158
|
+
wire: {
|
|
12159
|
+
imageModel: config.codex.imageModel,
|
|
12160
|
+
carrierModel: config.codex.carrierModel
|
|
12161
|
+
}
|
|
12162
|
+
}) : createAntigravitySubscriptionImageProvider({
|
|
12163
|
+
authStrategy: antigravityStrategy,
|
|
12164
|
+
executionScheduler: scheduler,
|
|
12165
|
+
generationTimeoutMs: config.queue.generationTimeoutMs,
|
|
11555
12166
|
now: options.now
|
|
11556
|
-
});
|
|
11557
|
-
if (
|
|
12167
|
+
}));
|
|
12168
|
+
if (providers.length === 1 && providers[0].id !== "codex-subscription") {
|
|
11558
12169
|
throw new TypeError("synthetic verified image provider id must match configured provider");
|
|
11559
12170
|
}
|
|
11560
|
-
const providerRegistry = new ImageProviderRegistry(
|
|
12171
|
+
const providerRegistry = new ImageProviderRegistry(providers);
|
|
11561
12172
|
const orchestrator = new ImageOrchestrator({
|
|
11562
12173
|
registry: providerRegistry,
|
|
11563
12174
|
referenceStore: options.storage.referenceStore,
|
|
@@ -11579,35 +12190,72 @@ function createImageRuntimeGeneration(options) {
|
|
|
11579
12190
|
...options.createCallId ? { createCallId: options.createCallId } : {},
|
|
11580
12191
|
...options.now ? { now: options.now } : {}
|
|
11581
12192
|
});
|
|
12193
|
+
const defaultProviderId = config.models[config.defaultModel] ?? "codex-subscription";
|
|
12194
|
+
const inspectOneProvider = async (providerId, apiKeyId) => {
|
|
12195
|
+
const capabilities = await orchestrator.getCapabilities(providerId, {
|
|
12196
|
+
requestId: `${options.generationId}:capability-inspection`,
|
|
12197
|
+
tenantId: apiKeyId,
|
|
12198
|
+
signal: new AbortController().signal,
|
|
12199
|
+
sessionKey: `outbound:images:${apiKeyId}`,
|
|
12200
|
+
...config.account.id ? { preferredAccountId: config.account.id } : {},
|
|
12201
|
+
...config.account.group ? { preferredAccountGroup: config.account.group } : {},
|
|
12202
|
+
boundAccountFallbackPolicy: config.account.fallback
|
|
12203
|
+
});
|
|
12204
|
+
return capabilities;
|
|
12205
|
+
};
|
|
11582
12206
|
const inspectCapability = async (apiKeyId) => {
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
12207
|
+
const providerCapabilities = /* @__PURE__ */ new Map();
|
|
12208
|
+
let defaultProviderError;
|
|
12209
|
+
const providerRows = [];
|
|
12210
|
+
for (const providerId of [...new Set(Object.values(config.models))]) {
|
|
12211
|
+
try {
|
|
12212
|
+
const capabilities2 = await inspectOneProvider(providerId, apiKeyId);
|
|
12213
|
+
providerCapabilities.set(providerId, capabilities2);
|
|
12214
|
+
const affirmed = capabilities2.available === true && capabilities2.generate === true;
|
|
12215
|
+
providerRows.push({
|
|
12216
|
+
providerId,
|
|
12217
|
+
available: affirmed,
|
|
12218
|
+
...!affirmed ? { reason: capabilities2.reason ?? "runtime_unavailable" } : {},
|
|
12219
|
+
models: affirmed ? Object.entries(config.models).filter(([model, modelProvider]) => modelProvider === providerId && capabilities2.models.includes(model)).map(([model]) => model) : [],
|
|
12220
|
+
capabilities: capabilities2
|
|
12221
|
+
});
|
|
12222
|
+
} catch (error) {
|
|
12223
|
+
if (providerId === defaultProviderId) defaultProviderError = error;
|
|
12224
|
+
providerRows.push({
|
|
12225
|
+
providerId,
|
|
12226
|
+
available: false,
|
|
12227
|
+
reason: error instanceof ImageGenerationError4 && (error.code === "upstream_auth_required" || error.code === "invalid_api_key") ? "account_unverified" : "runtime_unavailable",
|
|
12228
|
+
models: []
|
|
12229
|
+
});
|
|
12230
|
+
}
|
|
12231
|
+
}
|
|
12232
|
+
const providers2 = Object.freeze(providerRows);
|
|
12233
|
+
const routedModels = Object.freeze(
|
|
12234
|
+
providerRows.flatMap((row) => row.available ? row.models : [])
|
|
12235
|
+
);
|
|
12236
|
+
const capabilities = providerCapabilities.get(defaultProviderId);
|
|
12237
|
+
if (!capabilities) {
|
|
11603
12238
|
return Object.freeze({
|
|
11604
12239
|
enabled: true,
|
|
11605
12240
|
available: false,
|
|
11606
|
-
providerId:
|
|
12241
|
+
providerId: defaultProviderId,
|
|
11607
12242
|
model: config.defaultModel,
|
|
11608
|
-
|
|
12243
|
+
routedModels,
|
|
12244
|
+
providers: providers2,
|
|
12245
|
+
reason: defaultProviderError instanceof ImageGenerationError4 && (defaultProviderError.code === "upstream_auth_required" || defaultProviderError.code === "invalid_api_key") ? "account_unverified" : "runtime_unavailable"
|
|
11609
12246
|
});
|
|
11610
12247
|
}
|
|
12248
|
+
const available = capabilities.available === true && capabilities.generate === true && capabilities.models.includes(config.defaultModel);
|
|
12249
|
+
return Object.freeze({
|
|
12250
|
+
enabled: true,
|
|
12251
|
+
available,
|
|
12252
|
+
providerId: defaultProviderId,
|
|
12253
|
+
model: config.defaultModel,
|
|
12254
|
+
routedModels,
|
|
12255
|
+
providers: providers2,
|
|
12256
|
+
...!available ? { reason: capabilities.reason ?? "runtime_unavailable" } : {},
|
|
12257
|
+
capabilities
|
|
12258
|
+
});
|
|
11611
12259
|
};
|
|
11612
12260
|
const resolverToDispose = runtimeResolver;
|
|
11613
12261
|
const schedulerToDispose = scheduler;
|
|
@@ -11645,7 +12293,7 @@ function createImageRuntimeGeneration(options) {
|
|
|
11645
12293
|
imageApi,
|
|
11646
12294
|
hosted,
|
|
11647
12295
|
hostedRuntime: Object.freeze({
|
|
11648
|
-
providerId:
|
|
12296
|
+
providerId: defaultProviderId,
|
|
11649
12297
|
imageModel: config.defaultModel,
|
|
11650
12298
|
referenceTtlMs: config.references.ttlMs,
|
|
11651
12299
|
maxOutputBytes: config.limits.maxOutputBytes,
|
|
@@ -14642,6 +15290,9 @@ var ImageRuntimeManager = class {
|
|
|
14642
15290
|
}
|
|
14643
15291
|
async listAvailableModels(apiKeyId) {
|
|
14644
15292
|
const inspection = await this.inspectCapability(apiKeyId);
|
|
15293
|
+
if (inspection.routedModels !== void 0) {
|
|
15294
|
+
return Object.freeze([...inspection.routedModels]);
|
|
15295
|
+
}
|
|
14645
15296
|
return inspection.available && inspection.model === "gpt-image-2" ? Object.freeze([inspection.model]) : Object.freeze([]);
|
|
14646
15297
|
}
|
|
14647
15298
|
resourceStatus() {
|
|
@@ -16857,11 +17508,13 @@ var JsonVoucherDb = class {
|
|
|
16857
17508
|
// src/ports/JsonSubscriptionCredentialStore.ts
|
|
16858
17509
|
import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as readFileSync18, renameSync as renameSync12 } from "fs";
|
|
16859
17510
|
import { dirname as dirname15 } from "path";
|
|
17511
|
+
import { getAntigravityProjectResolver as getAntigravityProjectResolver2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
|
|
16860
17512
|
import { getSharedAccountHealth as getSharedAccountHealth2 } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
|
|
16861
17513
|
import { getSharedAccountAllowanceScheduling as getSharedAccountAllowanceScheduling3 } from "@omnicross/core/pipeline/AccountAllowanceScheduling";
|
|
16862
|
-
import { fetchUpstream as
|
|
17514
|
+
import { fetchUpstream as fetchUpstream12 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
16863
17515
|
import { getSharedIdentityStore as getSharedIdentityStore2 } from "@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore";
|
|
16864
17516
|
import {
|
|
17517
|
+
antigravityOAuth as antigravityOAuth2,
|
|
16865
17518
|
claudeOAuth as claudeOAuth2,
|
|
16866
17519
|
codexOAuth as codexOAuth2,
|
|
16867
17520
|
geminiOAuth as geminiOAuth2,
|
|
@@ -17015,7 +17668,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17015
17668
|
* a plaintext token pair into `upstream-trace.jsonl`.
|
|
17016
17669
|
*/
|
|
17017
17670
|
buildRefreshFetch(providerId, accountId) {
|
|
17018
|
-
return this.fetchImpl ?? ((url, init) =>
|
|
17671
|
+
return this.fetchImpl ?? ((url, init) => fetchUpstream12(url, init, { providerId, accountId, redactBodies: true }));
|
|
17019
17672
|
}
|
|
17020
17673
|
/**
|
|
17021
17674
|
* In-flight refresh coalescing. OAuth refresh tokens are
|
|
@@ -17056,7 +17709,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17056
17709
|
* other hot reads. Never returns token material.
|
|
17057
17710
|
*/
|
|
17058
17711
|
getAccountProxy(providerId, accountId) {
|
|
17059
|
-
if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi" && providerId !== "grok" && providerId !== "copilot") {
|
|
17712
|
+
if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi" && providerId !== "grok" && providerId !== "copilot" && providerId !== "antigravity") {
|
|
17060
17713
|
return void 0;
|
|
17061
17714
|
}
|
|
17062
17715
|
return getAccountProxy(this.readConfig(), providerId, accountId);
|
|
@@ -17075,7 +17728,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17075
17728
|
const fingerprintOn = identityStore.isEnabled();
|
|
17076
17729
|
const now = Date.now();
|
|
17077
17730
|
const out = {};
|
|
17078
|
-
for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi", "grok", "copilot"]) {
|
|
17731
|
+
for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi", "grok", "copilot", "antigravity"]) {
|
|
17079
17732
|
const sanitized = sanitizeAccounts(config, provider);
|
|
17080
17733
|
if (sanitized.length === 0) continue;
|
|
17081
17734
|
for (const account of sanitized) {
|
|
@@ -17334,6 +17987,76 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17334
17987
|
return false;
|
|
17335
17988
|
});
|
|
17336
17989
|
}
|
|
17990
|
+
/**
|
|
17991
|
+
* Refresh the Antigravity (Google) OAuth access token. Like gemini, the
|
|
17992
|
+
* Google token endpoint does NOT return a refresh_token on refresh, so this
|
|
17993
|
+
* writes ONLY access+expiresAt (+status/lastRefreshedAt) and DELIBERATELY
|
|
17994
|
+
* preserves the stored `refreshToken` — plus the account's `projectId`
|
|
17995
|
+
* (a handshake product; the post-refresh re-validation is the refresh
|
|
17996
|
+
* scheduler's hook, not this write) and `email`. HONEST `false` when no
|
|
17997
|
+
* refresh_token.
|
|
17998
|
+
*/
|
|
17999
|
+
async refreshAntigravityToken() {
|
|
18000
|
+
return this.coalesce("antigravity:active", async () => {
|
|
18001
|
+
const config = this.readConfig();
|
|
18002
|
+
const active = getActiveAccount(config, "antigravity");
|
|
18003
|
+
const antigravity = active?.tokens;
|
|
18004
|
+
if (!active || !antigravity?.refreshToken) return false;
|
|
18005
|
+
const capturedId = active.id;
|
|
18006
|
+
this.materializeMigration(config);
|
|
18007
|
+
const refreshFetch = this.buildRefreshFetch("antigravity", capturedId);
|
|
18008
|
+
try {
|
|
18009
|
+
const result = await antigravityOAuth2.refreshAccessToken(antigravity.refreshToken, refreshFetch);
|
|
18010
|
+
const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
|
|
18011
|
+
const next = {
|
|
18012
|
+
...antigravity,
|
|
18013
|
+
// KEEP the existing refreshToken/projectId/email.
|
|
18014
|
+
accessToken: result.accessToken,
|
|
18015
|
+
expiresAt,
|
|
18016
|
+
status: "authorized",
|
|
18017
|
+
lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18018
|
+
errorMessage: void 0
|
|
18019
|
+
};
|
|
18020
|
+
this.writeBackById("antigravity", capturedId, next);
|
|
18021
|
+
await this.revalidateAntigravityProject(capturedId);
|
|
18022
|
+
return true;
|
|
18023
|
+
} catch (error) {
|
|
18024
|
+
this.markExpiredById("antigravity", capturedId, antigravity, error);
|
|
18025
|
+
return false;
|
|
18026
|
+
}
|
|
18027
|
+
});
|
|
18028
|
+
}
|
|
18029
|
+
/**
|
|
18030
|
+
* Post-refresh project re-validation hook (antigravity design D8): after a
|
|
18031
|
+
* successful antigravity token refresh, re-run the Code Assist project
|
|
18032
|
+
* handshake and write the (possibly rotated) `projectId` back to the account.
|
|
18033
|
+
* A handshake FAILURE keeps the stored projectId untouched (logged) so the
|
|
18034
|
+
* account keeps serving with the last-known-good project until a later
|
|
18035
|
+
* refresh succeeds. Returns whether the handshake produced a project.
|
|
18036
|
+
*/
|
|
18037
|
+
async revalidateAntigravityProject(accountId) {
|
|
18038
|
+
const before = getAccountById(this.readConfig(), "antigravity", accountId);
|
|
18039
|
+
const accessToken = before?.tokens?.accessToken;
|
|
18040
|
+
if (!accessToken) return false;
|
|
18041
|
+
try {
|
|
18042
|
+
const projectId = await getAntigravityProjectResolver2().resolveProject(accessToken);
|
|
18043
|
+
if (projectId !== void 0) {
|
|
18044
|
+
const config = this.readConfig();
|
|
18045
|
+
const account = getAccountById(config, "antigravity", accountId);
|
|
18046
|
+
const tokens = account?.tokens;
|
|
18047
|
+
if (account && tokens?.accessToken === accessToken && tokens.projectId !== projectId) {
|
|
18048
|
+
this.writeBackById("antigravity", accountId, { ...tokens, projectId });
|
|
18049
|
+
}
|
|
18050
|
+
return true;
|
|
18051
|
+
}
|
|
18052
|
+
return false;
|
|
18053
|
+
} catch (error) {
|
|
18054
|
+
console.warn(
|
|
18055
|
+
`[JsonSubscriptionCredentialStore] antigravity project re-validation failed for account ${accountId}: ` + (error instanceof Error ? error.message : String(error))
|
|
18056
|
+
);
|
|
18057
|
+
return false;
|
|
18058
|
+
}
|
|
18059
|
+
}
|
|
17337
18060
|
/**
|
|
17338
18061
|
* Refresh a SPECIFIC managed account by id (background scheduler sweep and
|
|
17339
18062
|
* account-pool resolution). It uses only that account's stored refresh
|
|
@@ -17362,6 +18085,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17362
18085
|
};
|
|
17363
18086
|
if (refreshed.idToken) next.idToken = refreshed.idToken;
|
|
17364
18087
|
this.writeBackById(provider, id, next);
|
|
18088
|
+
if (provider === "antigravity") await this.revalidateAntigravityProject(id);
|
|
17365
18089
|
return true;
|
|
17366
18090
|
} catch (error) {
|
|
17367
18091
|
this.markExpiredById(provider, id, captured, error);
|
|
@@ -17386,7 +18110,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17386
18110
|
}
|
|
17387
18111
|
const oauth = account.tokens;
|
|
17388
18112
|
if (!oauth.accessToken) return null;
|
|
17389
|
-
if (providerId === "codex" || providerId === "gemini" || providerId === "kimi" || providerId === "grok" || providerId === "copilot") {
|
|
18113
|
+
if (providerId === "codex" || providerId === "gemini" || providerId === "kimi" || providerId === "grok" || providerId === "copilot" || providerId === "antigravity") {
|
|
17390
18114
|
const expiresAtMs = oauth.expiresAt ? Date.parse(oauth.expiresAt) : 0;
|
|
17391
18115
|
const expiringSoon = expiresAtMs > 0 && Date.now() >= expiresAtMs - ACCOUNT_REFRESH_LEAD_MS;
|
|
17392
18116
|
if (expiringSoon && oauth.refreshToken) {
|
|
@@ -17502,6 +18226,13 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17502
18226
|
if (provider === "copilot") {
|
|
17503
18227
|
throw new Error("GitHub Copilot tokens cannot be refreshed \u2014 re-authenticate the account");
|
|
17504
18228
|
}
|
|
18229
|
+
if (provider === "antigravity") {
|
|
18230
|
+
const r2 = await antigravityOAuth2.refreshAccessToken(refreshToken, refreshFetch);
|
|
18231
|
+
return {
|
|
18232
|
+
accessToken: r2.accessToken,
|
|
18233
|
+
expiresAt: new Date(Date.now() + r2.expiresIn * 1e3).toISOString()
|
|
18234
|
+
};
|
|
18235
|
+
}
|
|
17505
18236
|
const flow = provider === "claude" ? claudeOAuth2 : provider === "codex" ? codexOAuth2 : geminiOAuth2;
|
|
17506
18237
|
const r = await flow.refreshAccessToken(refreshToken, refreshFetch);
|
|
17507
18238
|
return {
|
|
@@ -17745,7 +18476,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
17745
18476
|
};
|
|
17746
18477
|
|
|
17747
18478
|
// src/AccountHealthProbeScheduler.ts
|
|
17748
|
-
import { fetchUpstream as
|
|
18479
|
+
import { fetchUpstream as fetchUpstream13 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
17749
18480
|
|
|
17750
18481
|
// src/probe/CodexGenerationProbe.ts
|
|
17751
18482
|
import {
|
|
@@ -17900,7 +18631,11 @@ var PROVIDER_PROBE_PLANS = {
|
|
|
17900
18631
|
// The Copilot quota endpoint (copilot_internal/user) is a verified FREE
|
|
17901
18632
|
// authed GET but lives on api.github.com with its own auth dialect and a
|
|
17902
18633
|
// monthly-only window — the allowance collector owns the health surface.
|
|
17903
|
-
copilot: { kind: "local" }
|
|
18634
|
+
copilot: { kind: "local" },
|
|
18635
|
+
// Antigravity's quota endpoints are POST RPCs on daily-cloudcode-pa (not a
|
|
18636
|
+
// cheap GET) and need the antigravity/hub UA — the allowance collector owns
|
|
18637
|
+
// the health surface; the probe stays local.
|
|
18638
|
+
antigravity: { kind: "local" }
|
|
17904
18639
|
};
|
|
17905
18640
|
function probePlanFor(providerId) {
|
|
17906
18641
|
return PROVIDER_PROBE_PLANS[providerId] ?? { kind: "local" };
|
|
@@ -17922,7 +18657,7 @@ var AccountHealthProbeScheduler = class {
|
|
|
17922
18657
|
this.logger = logger;
|
|
17923
18658
|
this.config = config;
|
|
17924
18659
|
this.now = opts.now ?? Date.now;
|
|
17925
|
-
this.fetchImpl = opts.fetchImpl ??
|
|
18660
|
+
this.fetchImpl = opts.fetchImpl ?? fetchUpstream13;
|
|
17926
18661
|
this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
17927
18662
|
this.planFor = opts.planFor ?? probePlanFor;
|
|
17928
18663
|
}
|
|
@@ -19627,7 +20362,7 @@ var AuditWriter = class {
|
|
|
19627
20362
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync8 } from "fs";
|
|
19628
20363
|
import { createHmac as createHmac5 } from "crypto";
|
|
19629
20364
|
import { join as join26 } from "path";
|
|
19630
|
-
import { fetchUpstream as
|
|
20365
|
+
import { fetchUpstream as fetchUpstream14 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
19631
20366
|
|
|
19632
20367
|
// src/billing/billingFiles.ts
|
|
19633
20368
|
var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
|
|
@@ -19650,7 +20385,7 @@ var BillingPublisher = class {
|
|
|
19650
20385
|
constructor(billingDir, logger, opts = {}) {
|
|
19651
20386
|
this.billingDir = billingDir;
|
|
19652
20387
|
this.logger = logger;
|
|
19653
|
-
this.fetchImpl = opts.fetchImpl ?? ((url, init) =>
|
|
20388
|
+
this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream14(url, init));
|
|
19654
20389
|
this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
|
|
19655
20390
|
this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
|
|
19656
20391
|
this.now = opts.now ?? Date.now;
|
|
@@ -19900,7 +20635,7 @@ var BillingRetrySweeper = class {
|
|
|
19900
20635
|
// src/TokenRefreshScheduler.ts
|
|
19901
20636
|
var REFRESH_LEAD_MS2 = 5 * 6e4;
|
|
19902
20637
|
var SWEEP_INTERVAL_MS5 = 6e4;
|
|
19903
|
-
var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot"];
|
|
20638
|
+
var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot", "antigravity"];
|
|
19904
20639
|
var TokenRefreshScheduler = class {
|
|
19905
20640
|
constructor(store, logger, intervalMs = SWEEP_INTERVAL_MS5, leadMs = REFRESH_LEAD_MS2) {
|
|
19906
20641
|
this.store = store;
|
|
@@ -19991,6 +20726,8 @@ var TokenRefreshScheduler = class {
|
|
|
19991
20726
|
// never reaches this — the branch exists for union totality.
|
|
19992
20727
|
case "copilot":
|
|
19993
20728
|
return this.store.refreshCopilotToken();
|
|
20729
|
+
case "antigravity":
|
|
20730
|
+
return this.store.refreshAntigravityToken();
|
|
19994
20731
|
}
|
|
19995
20732
|
}
|
|
19996
20733
|
};
|
|
@@ -20069,7 +20806,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
|
|
|
20069
20806
|
|
|
20070
20807
|
// src/webhook/WebhookDispatcher.ts
|
|
20071
20808
|
import { createHmac as createHmac6 } from "crypto";
|
|
20072
|
-
import { fetchUpstream as
|
|
20809
|
+
import { fetchUpstream as fetchUpstream15 } from "@omnicross/core/pipeline/upstreamFetch";
|
|
20073
20810
|
var WEBHOOK_MAX_ATTEMPTS = 3;
|
|
20074
20811
|
var WEBHOOK_QUEUE_MAX = 1e3;
|
|
20075
20812
|
var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
|
|
@@ -20089,7 +20826,7 @@ var WebhookDispatcher = class {
|
|
|
20089
20826
|
sleep;
|
|
20090
20827
|
now;
|
|
20091
20828
|
constructor(opts = {}) {
|
|
20092
|
-
this.fetchImpl = opts.fetchImpl ?? ((url, init) =>
|
|
20829
|
+
this.fetchImpl = opts.fetchImpl ?? ((url, init) => fetchUpstream15(url, init));
|
|
20093
20830
|
this.logger = opts.logger;
|
|
20094
20831
|
this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
|
|
20095
20832
|
this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
|
|
@@ -20175,8 +20912,8 @@ var WebhookDispatcher = class {
|
|
|
20175
20912
|
signal: AbortSignal.timeout(this.timeoutMs)
|
|
20176
20913
|
});
|
|
20177
20914
|
return res.ok ? { ok: true, status: res.status } : { ok: false, status: res.status };
|
|
20178
|
-
} catch (
|
|
20179
|
-
return { ok: false, error:
|
|
20915
|
+
} catch (err9) {
|
|
20916
|
+
return { ok: false, error: err9 instanceof Error ? err9.message : String(err9) };
|
|
20180
20917
|
}
|
|
20181
20918
|
}
|
|
20182
20919
|
/**
|
|
@@ -20318,7 +21055,7 @@ function buildDaemon(config, paths) {
|
|
|
20318
21055
|
setSecretBox(secretBox3);
|
|
20319
21056
|
setSecretBox2(secretBox3);
|
|
20320
21057
|
const decryptedConfig = decryptConfigSecrets(config, secretBox3);
|
|
20321
|
-
const accountAllowanceStore = new
|
|
21058
|
+
const accountAllowanceStore = new AccountAllowanceStore10(
|
|
20322
21059
|
Date.now,
|
|
20323
21060
|
void 0,
|
|
20324
21061
|
new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
|
|
@@ -20362,6 +21099,8 @@ function buildDaemon(config, paths) {
|
|
|
20362
21099
|
})
|
|
20363
21100
|
);
|
|
20364
21101
|
setGeminiCodeAssistResolver(getGeminiCodeAssistProjectResolver2());
|
|
21102
|
+
setAntigravitySandboxFailover(decryptedConfig.antigravity?.sandboxFailover === true);
|
|
21103
|
+
setOpenCodeGoUserAgent(decryptedConfig.opencodego?.userAgent ?? null);
|
|
20365
21104
|
const autoDisableStore = new AutoDisableStore();
|
|
20366
21105
|
const providerKeyQuotaService = new ProviderKeyQuotaService(secretBox3);
|
|
20367
21106
|
const apiKeyPool = new ApiKeyPoolService(
|
|
@@ -20380,7 +21119,7 @@ function buildDaemon(config, paths) {
|
|
|
20380
21119
|
const pricingEngine = new PricingEngine(pricingStore, logger, {
|
|
20381
21120
|
// Catalog egress follows the same global/env proxy policy as every other
|
|
20382
21121
|
// daemon upstream call; no provider/account override applies here.
|
|
20383
|
-
fetchImpl: ((input, init) =>
|
|
21122
|
+
fetchImpl: ((input, init) => fetchUpstream16(String(input), init ?? {}))
|
|
20384
21123
|
});
|
|
20385
21124
|
const pricingRefreshScheduler = new PricingRefreshScheduler(
|
|
20386
21125
|
pricingEngine,
|
|
@@ -20622,6 +21361,7 @@ function buildDaemon(config, paths) {
|
|
|
20622
21361
|
outboundApiServer,
|
|
20623
21362
|
imageRuntimeConfig,
|
|
20624
21363
|
imageRuntimeStatus: paths.imageRuntimeStatus ?? imageRuntimeManager,
|
|
21364
|
+
imageLiveVerifier: paths.imageLiveVerifier ?? imageDoctor,
|
|
20625
21365
|
imageConfigAudit: paths.imageConfigAudit ?? ((record) => {
|
|
20626
21366
|
imageObservability.recordConfigurationAudit(record);
|
|
20627
21367
|
}),
|
|
@@ -20665,7 +21405,7 @@ function buildDaemon(config, paths) {
|
|
|
20665
21405
|
// — `server.proxy.byProvider[...]` was silently skipped — and the call was
|
|
20666
21406
|
// excluded from the upstream trace, so a failing login left no evidence.
|
|
20667
21407
|
// `redactBodies` keeps the code/verifier + minted token out of that trace.
|
|
20668
|
-
oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) =>
|
|
21408
|
+
oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => fetchUpstream16(url, init, { providerId, redactBodies: true }),
|
|
20669
21409
|
subscriptionAccountAppender: credentialStore,
|
|
20670
21410
|
// Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
|
|
20671
21411
|
// + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
|
|
@@ -20680,6 +21420,21 @@ function buildDaemon(config, paths) {
|
|
|
20680
21420
|
// Grok interactive OAuth — the same async DEVICE-CODE shape as kimi.
|
|
20681
21421
|
grokSessions: new CodexOAuthSessionStore(),
|
|
20682
21422
|
copilotSessions: new CodexOAuthSessionStore(),
|
|
21423
|
+
// Antigravity interactive OAuth — the async LOOPBACK flow store + the
|
|
21424
|
+
// one-shot 127.0.0.1:51121 listener (same shape as codex; test seam below).
|
|
21425
|
+
antigravitySessions: new CodexOAuthSessionStore(),
|
|
21426
|
+
antigravityAwaitLoopback: paths.antigravityAwaitLoopback ?? ((state, timeoutMs, signal) => awaitLoopbackCode(state, timeoutMs, signal, {
|
|
21427
|
+
port: 51121,
|
|
21428
|
+
path: "/oauth-callback",
|
|
21429
|
+
label: "antigravity"
|
|
21430
|
+
})),
|
|
21431
|
+
// The dynamic model-catalog probe's token source (the ACTIVE antigravity
|
|
21432
|
+
// account; refreshed by the by-id near-expiry seam inside the lookup).
|
|
21433
|
+
resolveAntigravityAccessToken: async () => {
|
|
21434
|
+
const config2 = await credentialStore.getFullConfig();
|
|
21435
|
+
const activeId = config2.activeAntigravityAccountId ?? config2.antigravityAccounts?.[0]?.id;
|
|
21436
|
+
return activeId ? credentialStore.getAccessTokenForAccount("antigravity", activeId) : null;
|
|
21437
|
+
},
|
|
20683
21438
|
// Migration pack (app-parity child 6, design D2/D3) — the concrete credential
|
|
20684
21439
|
// store provides BOTH the full DECRYPTED read (`getFullConfig`, export) and
|
|
20685
21440
|
// the multi-account append (`appendProviderAccount`, import re-encrypts at-
|
|
@@ -20738,7 +21493,7 @@ function buildDaemon(config, paths) {
|
|
|
20738
21493
|
});
|
|
20739
21494
|
const webhookDispatcher = new WebhookDispatcher({
|
|
20740
21495
|
logger,
|
|
20741
|
-
fetchImpl: (url, init) =>
|
|
21496
|
+
fetchImpl: (url, init) => fetchUpstream16(url, init)
|
|
20742
21497
|
});
|
|
20743
21498
|
setWebhookRuntime(webhookDispatcher, getSharedAccountHealth4());
|
|
20744
21499
|
const auditWriter = new AuditWriter(auditDir, logger);
|