dsh-antigravity-auth 0.1.0

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +168 -0
  4. package/README.zh.md +159 -0
  5. package/cordis.patch.yml +12 -0
  6. package/lib/capability-lifecycle--tgGKajs.js +1896 -0
  7. package/lib/client.cjs +2123 -0
  8. package/lib/client.cjs.map +1 -0
  9. package/lib/image.js +564 -0
  10. package/lib/index.js +176 -0
  11. package/lib/invariant.js +2 -0
  12. package/lib/live-gate-runner.js +542 -0
  13. package/lib/live-gates.js +97 -0
  14. package/lib/llm-adapter.js +916 -0
  15. package/lib/media-admission.js +206 -0
  16. package/lib/private-failure-B9vzUkQ7.js +23 -0
  17. package/lib/private-transport-urF138qW.js +641 -0
  18. package/lib/private-transport.js +2 -0
  19. package/lib/project-context.js +133 -0
  20. package/lib/quota.js +283 -0
  21. package/lib/replay.js +156 -0
  22. package/lib/rpc-contract-BFWfdKKs.js +491 -0
  23. package/lib/rpc-contract.js +2 -0
  24. package/lib/safe-text-AlEyN8q_.js +12 -0
  25. package/lib/search.js +259 -0
  26. package/lib/status-D0-em3Ru.js +125 -0
  27. package/lib/types/auth-service.d.ts +64 -0
  28. package/lib/types/auth-service.d.ts.map +1 -0
  29. package/lib/types/auth-store.d.ts +45 -0
  30. package/lib/types/auth-store.d.ts.map +1 -0
  31. package/lib/types/bootstrap-service.d.ts +6 -0
  32. package/lib/types/bootstrap-service.d.ts.map +1 -0
  33. package/lib/types/capability-gates.d.ts +19 -0
  34. package/lib/types/capability-gates.d.ts.map +1 -0
  35. package/lib/types/capability-lifecycle.d.ts +26 -0
  36. package/lib/types/capability-lifecycle.d.ts.map +1 -0
  37. package/lib/types/client/AntigravityAuthSettings.d.ts +19 -0
  38. package/lib/types/client/AntigravityAuthSettings.d.ts.map +1 -0
  39. package/lib/types/client/index.d.ts +18 -0
  40. package/lib/types/client/index.d.ts.map +1 -0
  41. package/lib/types/client/locales.d.ts +121 -0
  42. package/lib/types/client/locales.d.ts.map +1 -0
  43. package/lib/types/client/styles.d.ts +4 -0
  44. package/lib/types/client/styles.d.ts.map +1 -0
  45. package/lib/types/credential-coordinator.d.ts +84 -0
  46. package/lib/types/credential-coordinator.d.ts.map +1 -0
  47. package/lib/types/image.d.ts +39 -0
  48. package/lib/types/image.d.ts.map +1 -0
  49. package/lib/types/index.d.ts +21 -0
  50. package/lib/types/index.d.ts.map +1 -0
  51. package/lib/types/invariant.d.ts +3 -0
  52. package/lib/types/invariant.d.ts.map +1 -0
  53. package/lib/types/live-gate-attachments.d.ts +6 -0
  54. package/lib/types/live-gate-attachments.d.ts.map +1 -0
  55. package/lib/types/live-gate-auth.d.ts +5 -0
  56. package/lib/types/live-gate-auth.d.ts.map +1 -0
  57. package/lib/types/live-gate-image.d.ts +5 -0
  58. package/lib/types/live-gate-image.d.ts.map +1 -0
  59. package/lib/types/live-gate-llm.d.ts +10 -0
  60. package/lib/types/live-gate-llm.d.ts.map +1 -0
  61. package/lib/types/live-gate-outcome.d.ts +8 -0
  62. package/lib/types/live-gate-outcome.d.ts.map +1 -0
  63. package/lib/types/live-gate-runner.d.ts +15 -0
  64. package/lib/types/live-gate-runner.d.ts.map +1 -0
  65. package/lib/types/live-gate-search.d.ts +5 -0
  66. package/lib/types/live-gate-search.d.ts.map +1 -0
  67. package/lib/types/live-gate-video.d.ts +8 -0
  68. package/lib/types/live-gate-video.d.ts.map +1 -0
  69. package/lib/types/live-gates.d.ts +25 -0
  70. package/lib/types/live-gates.d.ts.map +1 -0
  71. package/lib/types/llm-adapter.d.ts +65 -0
  72. package/lib/types/llm-adapter.d.ts.map +1 -0
  73. package/lib/types/login-types.d.ts +36 -0
  74. package/lib/types/login-types.d.ts.map +1 -0
  75. package/lib/types/media-admission.d.ts +54 -0
  76. package/lib/types/media-admission.d.ts.map +1 -0
  77. package/lib/types/model-catalog.d.ts +19 -0
  78. package/lib/types/model-catalog.d.ts.map +1 -0
  79. package/lib/types/oauth-flow.d.ts +87 -0
  80. package/lib/types/oauth-flow.d.ts.map +1 -0
  81. package/lib/types/private-failure.d.ts +6 -0
  82. package/lib/types/private-failure.d.ts.map +1 -0
  83. package/lib/types/private-transport-error.d.ts +13 -0
  84. package/lib/types/private-transport-error.d.ts.map +1 -0
  85. package/lib/types/private-transport.d.ts +48 -0
  86. package/lib/types/private-transport.d.ts.map +1 -0
  87. package/lib/types/project-context.d.ts +30 -0
  88. package/lib/types/project-context.d.ts.map +1 -0
  89. package/lib/types/quota.d.ts +43 -0
  90. package/lib/types/quota.d.ts.map +1 -0
  91. package/lib/types/raw-http.d.ts +11 -0
  92. package/lib/types/raw-http.d.ts.map +1 -0
  93. package/lib/types/replay.d.ts +30 -0
  94. package/lib/types/replay.d.ts.map +1 -0
  95. package/lib/types/rpc-contract.d.ts +33 -0
  96. package/lib/types/rpc-contract.d.ts.map +1 -0
  97. package/lib/types/rpc-vocabulary.d.ts +7 -0
  98. package/lib/types/rpc-vocabulary.d.ts.map +1 -0
  99. package/lib/types/rpc.d.ts +11 -0
  100. package/lib/types/rpc.d.ts.map +1 -0
  101. package/lib/types/safe-text.d.ts +3 -0
  102. package/lib/types/safe-text.d.ts.map +1 -0
  103. package/lib/types/search.d.ts +42 -0
  104. package/lib/types/search.d.ts.map +1 -0
  105. package/lib/types/status.d.ts +62 -0
  106. package/lib/types/status.d.ts.map +1 -0
  107. package/lib/types/video.d.ts +42 -0
  108. package/lib/types/video.d.ts.map +1 -0
  109. package/lib/types/wire-identity.d.ts +49 -0
  110. package/lib/types/wire-identity.d.ts.map +1 -0
  111. package/lib/video.js +320 -0
  112. package/lib/wire-identity.js +162 -0
  113. package/package.json +189 -0
  114. package/scripts/live-gates.mjs +4 -0
@@ -0,0 +1,133 @@
1
+ import { d as privateStatusError, i as DEFAULT_PRIVATE_RESPONSE_BYTES, l as createPrivateTransport, m as PrivateTransportError, n as DEFAULT_PRIVATE_IDLE_TIMEOUT_MS, o as DEFAULT_PRIVATE_TOTAL_TIMEOUT_MS, p as readPrivateText } from "./private-transport-urF138qW.js";
2
+ import { ANTIGRAVITY_WIRE_ORIGIN } from "./wire-identity.js";
3
+ import { t as classifyPrivateFailure } from "./private-failure-B9vzUkQ7.js";
4
+ import { buildAntigravityLoadCodeAssistMetadata } from "@cortexkit/antigravity-auth-core";
5
+ //#region src/project-context.ts
6
+ /** Host-only, read-only project discovery and safe project normalization. */
7
+ const PROJECT_DISCOVERY_PATH = "/v1internal:loadCodeAssist";
8
+ const PROJECT_DISCOVERY_ENDPOINT = `${ANTIGRAVITY_WIRE_ORIGIN}${PROJECT_DISCOVERY_PATH}`;
9
+ const MAX_RESPONSE_BYTES = Math.min(DEFAULT_PRIVATE_RESPONSE_BYTES, 65536);
10
+ const DEFAULT_OPERATION_TIMEOUT_MS = 1e4;
11
+ const MAX_OPERATION_TIMEOUT_MS = 6e5;
12
+ const MAX_PROJECT_ID_LENGTH = 128;
13
+ const PROJECT_ID_PATTERN = /^[a-z][a-z0-9-]{2,127}$/u;
14
+ var ProjectDiscoveryError = class extends Error {
15
+ code;
16
+ constructor(code, message = projectDiscoveryErrorMessage(code)) {
17
+ super(message);
18
+ this.name = "ProjectDiscoveryError";
19
+ this.code = code;
20
+ }
21
+ };
22
+ /** Create the fixed, read-only loadCodeAssist project probe. */
23
+ function createProjectDiscovery(options = {}) {
24
+ const timeoutMs = boundedTimeout(options.operationTimeoutMs);
25
+ const transport = options.transport ?? createPrivateTransport({
26
+ ...options.transportOptions?.responseHeaderTimeoutMs === void 0 ? {} : { responseHeaderTimeoutMs: options.transportOptions.responseHeaderTimeoutMs },
27
+ ...options.transportOptions?.maxRequestBytes === void 0 ? {} : { maxRequestBytes: options.transportOptions.maxRequestBytes }
28
+ });
29
+ return { discover: async (accessToken, signal) => {
30
+ if (signal?.aborted === true) throw new ProjectDiscoveryError("cancelled");
31
+ const body = JSON.stringify({ metadata: buildAntigravityLoadCodeAssistMetadata() });
32
+ let response;
33
+ try {
34
+ response = await transport.request({
35
+ url: PROJECT_DISCOVERY_ENDPOINT,
36
+ accessToken,
37
+ body,
38
+ ...signal === void 0 ? {} : { signal },
39
+ responseHeaderTimeoutMs: timeoutMs
40
+ });
41
+ } catch (error) {
42
+ throw mapTransportError(error);
43
+ }
44
+ const statusError = privateStatusError(response.status);
45
+ if (statusError !== void 0) {
46
+ await response.body?.cancel().catch(() => {});
47
+ throw mapTransportError(statusError);
48
+ }
49
+ try {
50
+ const text = await readPrivateText(response, {
51
+ ...signal === void 0 ? {} : { signal },
52
+ idleTimeoutMs: Math.min(timeoutMs, DEFAULT_PRIVATE_IDLE_TIMEOUT_MS),
53
+ totalTimeoutMs: Math.min(timeoutMs, DEFAULT_PRIVATE_TOTAL_TIMEOUT_MS),
54
+ maxBytes: MAX_RESPONSE_BYTES
55
+ });
56
+ let value;
57
+ try {
58
+ value = JSON.parse(text);
59
+ } catch {
60
+ throw new ProjectDiscoveryError("malformed");
61
+ }
62
+ return parseProjectResponse(value);
63
+ } catch (error) {
64
+ if (error instanceof ProjectDiscoveryError) throw error;
65
+ throw mapTransportError(error);
66
+ }
67
+ } };
68
+ }
69
+ /** Compatibility name used by the parent capability design. */
70
+ const createProjectContext = createProjectDiscovery;
71
+ /** Normalize the only project field that may cross into the credential store. */
72
+ function normalizeProjectId(value) {
73
+ if (typeof value !== "string") return void 0;
74
+ const normalized = value.trim();
75
+ if (normalized.length === 0 || normalized.length > MAX_PROJECT_ID_LENGTH) return void 0;
76
+ return PROJECT_ID_PATTERN.test(normalized) ? normalized : void 0;
77
+ }
78
+ function parseProjectResponse(value) {
79
+ if (!isRecord(value)) throw new ProjectDiscoveryError("malformed");
80
+ if (!Object.prototype.hasOwnProperty.call(value, "cloudaicompanionProject")) return void 0;
81
+ const candidate = value.cloudaicompanionProject;
82
+ if (candidate === null || candidate === void 0) return void 0;
83
+ if (typeof candidate === "string") {
84
+ if (candidate.trim().length === 0) return void 0;
85
+ return projectFromValue(candidate);
86
+ }
87
+ if (!isRecord(candidate)) throw new ProjectDiscoveryError("protocol-drift");
88
+ if (!Object.prototype.hasOwnProperty.call(candidate, "id")) return void 0;
89
+ if (candidate.id === null || candidate.id === void 0) throw new ProjectDiscoveryError("protocol-drift");
90
+ return projectFromValue(candidate.id);
91
+ }
92
+ function projectFromValue(value) {
93
+ const projectId = normalizeProjectId(value);
94
+ if (projectId === void 0) throw new ProjectDiscoveryError("protocol-drift");
95
+ return { projectId };
96
+ }
97
+ function boundedTimeout(value) {
98
+ if (value === void 0 || !Number.isFinite(value) || value <= 0) return DEFAULT_OPERATION_TIMEOUT_MS;
99
+ return Math.min(Math.floor(value), MAX_OPERATION_TIMEOUT_MS);
100
+ }
101
+ const PROJECT_FAILURE_CODES = {
102
+ authentication: "authentication",
103
+ forbidden: "forbidden",
104
+ "rate-limited": "rate-limited",
105
+ cancelled: "cancelled",
106
+ timeout: "offline",
107
+ "attribution-rejected": "protocol-drift",
108
+ "protocol-drift": "protocol-drift",
109
+ "response-limit": "protocol-drift",
110
+ "request-limit": "protocol-drift",
111
+ upstream: "offline",
112
+ network: "offline",
113
+ failed: "offline"
114
+ };
115
+ function mapTransportError(error) {
116
+ if (error instanceof ProjectDiscoveryError) return error;
117
+ if (error instanceof PrivateTransportError) return new ProjectDiscoveryError(PROJECT_FAILURE_CODES[classifyPrivateFailure(error)]);
118
+ return new ProjectDiscoveryError("offline");
119
+ }
120
+ function projectDiscoveryErrorMessage(code) {
121
+ if (code === "authentication") return "The Antigravity project probe requires authentication";
122
+ if (code === "forbidden") return "The Antigravity project probe was forbidden";
123
+ if (code === "rate-limited") return "The Antigravity project probe is rate-limited";
124
+ if (code === "offline") return "The Antigravity project probe is offline";
125
+ if (code === "malformed") return "The Antigravity project response was malformed";
126
+ if (code === "protocol-drift") return "The Antigravity project protocol changed";
127
+ return "The Antigravity project probe was cancelled";
128
+ }
129
+ function isRecord(value) {
130
+ return typeof value === "object" && value !== null && !Array.isArray(value);
131
+ }
132
+ //#endregion
133
+ export { PROJECT_DISCOVERY_ENDPOINT, PROJECT_DISCOVERY_PATH, ProjectDiscoveryError, createProjectContext, createProjectDiscovery, normalizeProjectId };
package/lib/quota.js ADDED
@@ -0,0 +1,283 @@
1
+ import { d as privateStatusError, i as DEFAULT_PRIVATE_RESPONSE_BYTES, l as createPrivateTransport, m as PrivateTransportError, p as readPrivateText } from "./private-transport-urF138qW.js";
2
+ import { ANTIGRAVITY_WIRE_ORIGIN } from "./wire-identity.js";
3
+ import { t as classifyPrivateFailure } from "./private-failure-B9vzUkQ7.js";
4
+ //#region src/quota.ts
5
+ /** Single-account Antigravity quota normalization and bounded Host service. */
6
+ const ANTIGRAVITY_QUOTA_ENDPOINT = `${ANTIGRAVITY_WIRE_ORIGIN}/v1internal:retrieveUserQuotaSummary`;
7
+ const QUOTA_REFRESH_MIN_INTERVAL_MS = 3e4;
8
+ /** Normalize only validated, display-safe quota facts from a provider response. */
9
+ function normalizeQuotaResponse(value, now = Date.now()) {
10
+ const groups = [];
11
+ const sourceValue = isRecord(value) && isRecord(value.response) ? value.response : value;
12
+ const source = isRecord(sourceValue) ? sourceValue : void 0;
13
+ const candidates = source === void 0 ? [] : [
14
+ ...Array.isArray(source.groups) ? source.groups : [],
15
+ ...Array.isArray(source.buckets) ? source.buckets : [],
16
+ ...Array.isArray(source.quotaBuckets) ? source.quotaBuckets : [],
17
+ ...Array.isArray(source.quota_buckets) ? source.quota_buckets : [],
18
+ ...Array.isArray(source.userQuotaSummary) ? source.userQuotaSummary : [],
19
+ ...Array.isArray(source.quotas) ? source.quotas : []
20
+ ];
21
+ for (const candidate of candidates) {
22
+ if (!isRecord(candidate)) continue;
23
+ const buckets = Array.isArray(candidate.buckets) ? candidate.buckets : Array.isArray(candidate.quotaBuckets) ? candidate.quotaBuckets : Array.isArray(candidate.windows) ? candidate.windows : [candidate];
24
+ for (const rawBucket of buckets) {
25
+ if (!isRecord(rawBucket)) continue;
26
+ const window = identifyWindow(rawBucket);
27
+ const resetTime = normalizeResetTime(rawBucket.resetTime ?? rawBucket.reset_time ?? rawBucket.resetAt ?? rawBucket.reset_at, now);
28
+ const fraction = normalizeFraction(rawBucket.remainingFraction ?? rawBucket.remaining_fraction ?? rawBucket.fraction ?? rawBucket.remaining ?? rawBucket.remaining_percent ?? rawBucket.percentage);
29
+ if (window === void 0 || resetTime === void 0 || fraction === void 0) continue;
30
+ const group = identifyGroup(candidate, rawBucket);
31
+ if (group === void 0) continue;
32
+ const modelCount = boundedCount(candidate.modelCount ?? candidate.model_count ?? candidate.models ?? descriptionModelCount(candidate.description));
33
+ const existing = groups.find((item) => item.group === group);
34
+ if (existing === void 0) groups.push({
35
+ group,
36
+ modelCount,
37
+ windows: [{
38
+ window,
39
+ remainingFraction: fraction,
40
+ resetTime
41
+ }]
42
+ });
43
+ else if (!existing.windows.some((item) => item.window === window)) {
44
+ const updated = {
45
+ group,
46
+ modelCount: Math.max(existing.modelCount, modelCount),
47
+ windows: [...existing.windows, {
48
+ window,
49
+ remainingFraction: fraction,
50
+ resetTime
51
+ }].sort(windowOrder)
52
+ };
53
+ groups.splice(groups.indexOf(existing), 1, updated);
54
+ } else {
55
+ const updatedWindows = existing.windows.map((item) => item.window === window ? {
56
+ window,
57
+ remainingFraction: Math.min(item.remainingFraction, fraction),
58
+ resetTime: item.resetTime
59
+ } : item);
60
+ const updated = {
61
+ group,
62
+ modelCount: Math.max(existing.modelCount, modelCount),
63
+ windows: updatedWindows.sort(windowOrder)
64
+ };
65
+ groups.splice(groups.indexOf(existing), 1, updated);
66
+ }
67
+ }
68
+ }
69
+ if (groups.length === 0) {
70
+ if (isRecord(source)) return {
71
+ state: "available",
72
+ checkedAt: new Date(now).toISOString(),
73
+ groups: []
74
+ };
75
+ throw new QuotaNormalizationError("The quota response did not contain recognized windows");
76
+ }
77
+ return {
78
+ state: "available",
79
+ checkedAt: new Date(now).toISOString(),
80
+ groups: groups.sort((left, right) => left.group.localeCompare(right.group))
81
+ };
82
+ }
83
+ var QuotaNormalizationError = class extends Error {
84
+ constructor(message) {
85
+ super(message);
86
+ this.name = "QuotaNormalizationError";
87
+ }
88
+ };
89
+ function createQuotaService(options) {
90
+ const now = options.now ?? (() => Date.now());
91
+ const minInterval = positive(options.minIntervalMs, QUOTA_REFRESH_MIN_INTERVAL_MS);
92
+ const transport = options.transport ?? createPrivateTransport({
93
+ ...options.transportOptions?.responseHeaderTimeoutMs === void 0 ? {} : { responseHeaderTimeoutMs: options.transportOptions.responseHeaderTimeoutMs },
94
+ ...options.transportOptions?.maxRequestBytes === void 0 ? {} : { maxRequestBytes: options.transportOptions.maxRequestBytes }
95
+ });
96
+ let current = { state: "unauthenticated" };
97
+ let checkedAt = 0;
98
+ let inFlight;
99
+ let inFlightAbort;
100
+ const lifecycleController = new AbortController();
101
+ let disposed = false;
102
+ return {
103
+ refresh: async (signal, force = false) => {
104
+ if (disposed) return current;
105
+ if (!force && checkedAt > 0 && now() - checkedAt < minInterval) return current;
106
+ if (inFlight !== void 0) return await waitForCaller(inFlight, signal);
107
+ const combined = mergeAbortSignals(void 0, lifecycleController.signal);
108
+ inFlightAbort = combined.dispose;
109
+ inFlight = refreshQuota(options.auth, transport, combined.signal, now).then((value) => {
110
+ current = value;
111
+ checkedAt = now();
112
+ return value;
113
+ }).catch((error) => {
114
+ current = mapQuotaError(error, now());
115
+ checkedAt = now();
116
+ return current;
117
+ }).finally(() => {
118
+ combined.dispose();
119
+ inFlightAbort = void 0;
120
+ inFlight = void 0;
121
+ });
122
+ return await waitForCaller(inFlight, signal);
123
+ },
124
+ status: () => current,
125
+ dispose: async () => {
126
+ disposed = true;
127
+ lifecycleController.abort();
128
+ inFlightAbort?.();
129
+ await inFlight?.catch(() => {});
130
+ }
131
+ };
132
+ }
133
+ async function refreshQuota(auth, transport, signal, now) {
134
+ const credential = await auth.credential(signal);
135
+ if (credential === void 0) return { state: "unauthenticated" };
136
+ const body = credential.projectId ? { project: credential.projectId } : {};
137
+ let response = await transport.request({
138
+ url: ANTIGRAVITY_QUOTA_ENDPOINT,
139
+ accessToken: credential.accessToken,
140
+ body: JSON.stringify(body),
141
+ ...signal === void 0 ? {} : { signal }
142
+ });
143
+ if (response.status === 403 && credential.projectId) try {
144
+ const retryResponse = await transport.request({
145
+ url: ANTIGRAVITY_QUOTA_ENDPOINT,
146
+ accessToken: credential.accessToken,
147
+ body: JSON.stringify({}),
148
+ ...signal === void 0 ? {} : { signal }
149
+ });
150
+ if (retryResponse.ok) response = retryResponse;
151
+ } catch {}
152
+ const statusError = privateStatusError(response.status);
153
+ if (statusError !== void 0) {
154
+ await response.body?.cancel().catch(() => {});
155
+ throw statusError;
156
+ }
157
+ let value;
158
+ try {
159
+ value = JSON.parse(await readPrivateText(response, {
160
+ ...signal === void 0 ? {} : { signal },
161
+ maxBytes: DEFAULT_PRIVATE_RESPONSE_BYTES
162
+ }));
163
+ } catch (error) {
164
+ if (error instanceof PrivateTransportError) throw error;
165
+ throw new QuotaNormalizationError("The quota response was not valid JSON");
166
+ }
167
+ return normalizeQuotaResponse(value, now());
168
+ }
169
+ const QUOTA_FAILURE_STATES = {
170
+ authentication: "unauthenticated",
171
+ forbidden: "forbidden",
172
+ "rate-limited": "rate-limited",
173
+ cancelled: "offline",
174
+ timeout: "timeout",
175
+ "attribution-rejected": "protocol-drift",
176
+ "protocol-drift": "protocol-drift",
177
+ "response-limit": "protocol-drift",
178
+ "request-limit": "protocol-drift",
179
+ upstream: "offline",
180
+ network: "offline",
181
+ failed: "offline"
182
+ };
183
+ function mapQuotaError(error, checkedAt) {
184
+ return {
185
+ state: error instanceof PrivateTransportError ? QUOTA_FAILURE_STATES[classifyPrivateFailure(error)] : error instanceof QuotaNormalizationError ? "protocol-drift" : "offline",
186
+ checkedAt: new Date(checkedAt).toISOString()
187
+ };
188
+ }
189
+ function identifyWindow(value) {
190
+ const raw = String(value.window ?? value.windowType ?? value.window_type ?? value.bucketId ?? value.bucket_id ?? "").toLowerCase();
191
+ if (raw.includes("5h") || raw.includes("5-hour") || raw.includes("five")) return "5h";
192
+ if (raw.includes("week") || raw.includes("weekly") || raw.includes("7d")) return "weekly";
193
+ const seconds = numberValue(value.durationSeconds ?? value.duration_seconds);
194
+ if (seconds !== void 0) {
195
+ if (seconds <= 18e3) return "5h";
196
+ if (seconds <= 691200) return "weekly";
197
+ }
198
+ }
199
+ function identifyGroup(candidate, bucket) {
200
+ const raw = [
201
+ candidate.displayName,
202
+ candidate.group,
203
+ candidate.quotaGroup,
204
+ candidate.quota_group,
205
+ candidate.modelFamily,
206
+ candidate.title,
207
+ candidate.name,
208
+ candidate.description,
209
+ bucket?.bucketId,
210
+ bucket?.bucket_id,
211
+ bucket?.displayName
212
+ ].filter(Boolean).map(String).join(" ").toLowerCase();
213
+ if (raw.includes("3p") || raw.includes("non") || raw.includes("claude") || raw.includes("gpt") || raw.includes("openai") || raw.includes("anthropic") || raw.includes("third-party") || raw.includes("external")) return "non-gemini";
214
+ if (raw.includes("gemini") || raw.includes("google") || raw.includes("chat") || raw.includes("code") || raw.includes("default") || raw.length === 0) return "gemini";
215
+ return "gemini";
216
+ }
217
+ function normalizeFraction(value) {
218
+ const number = numberValue(value);
219
+ if (number === void 0) return void 0;
220
+ if (number >= 0 && number <= 1) return number;
221
+ if (number <= 100) return number / 100;
222
+ }
223
+ function normalizeResetTime(value, now) {
224
+ const parsed = typeof value === "number" ? value < 1e10 ? value * 1e3 : value : typeof value === "string" ? Date.parse(value) : NaN;
225
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 0x5af3107a4000) return void 0;
226
+ const iso = new Date(parsed).toISOString();
227
+ return Number.isFinite(Date.parse(iso)) && parsed >= now - 31536e6 ? iso : void 0;
228
+ }
229
+ function boundedCount(value) {
230
+ if (Array.isArray(value)) return Math.min(value.length, 1e4);
231
+ const number = numberValue(value);
232
+ return number === void 0 ? 0 : Math.min(Math.floor(number), 1e4);
233
+ }
234
+ function descriptionModelCount(value) {
235
+ if (typeof value !== "string" || value.length === 0 || value.length > 16384) return 0;
236
+ if (!/^[^:]{1,256}:\s*/u.test(value)) return 0;
237
+ const payload = value.replace(/^[^:]{1,256}:\s*/u, "");
238
+ return Math.min(payload.split(",").map((item) => item.trim()).filter((item) => item.length > 0).length, 1e4);
239
+ }
240
+ function windowOrder(left, right) {
241
+ return left.window === right.window ? 0 : left.window === "5h" ? -1 : 1;
242
+ }
243
+ function positive(value, fallback) {
244
+ return value === void 0 || !Number.isFinite(value) || value <= 0 ? fallback : Math.min(Math.floor(value), 864e5);
245
+ }
246
+ function numberValue(value) {
247
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
248
+ }
249
+ async function waitForCaller(promise, signal) {
250
+ if (signal === void 0) return await promise;
251
+ if (signal.aborted) throw new PrivateTransportError("cancelled", "The quota request was cancelled", { accepted: false });
252
+ let remove;
253
+ const cancellation = new Promise((_, reject) => {
254
+ const abort = () => reject(new PrivateTransportError("cancelled", "The quota request was cancelled", { accepted: false }));
255
+ remove = () => signal.removeEventListener("abort", abort);
256
+ signal.addEventListener("abort", abort, { once: true });
257
+ });
258
+ try {
259
+ return await Promise.race([promise, cancellation]);
260
+ } finally {
261
+ remove?.();
262
+ }
263
+ }
264
+ function mergeAbortSignals(first, second) {
265
+ const controller = new AbortController();
266
+ const abort = (event) => {
267
+ if (!controller.signal.aborted) controller.abort(event.target.reason);
268
+ };
269
+ const signals = first === void 0 ? [second] : [first, second];
270
+ for (const signal of signals) if (signal.aborted) controller.abort(signal.reason);
271
+ else signal.addEventListener("abort", abort, { once: true });
272
+ return {
273
+ signal: controller.signal,
274
+ dispose: () => {
275
+ for (const signal of signals) signal.removeEventListener("abort", abort);
276
+ }
277
+ };
278
+ }
279
+ function isRecord(value) {
280
+ return typeof value === "object" && value !== null && !Array.isArray(value);
281
+ }
282
+ //#endregion
283
+ export { ANTIGRAVITY_QUOTA_ENDPOINT, QUOTA_REFRESH_MIN_INTERVAL_MS, QuotaNormalizationError, createQuotaService, normalizeQuotaResponse };
package/lib/replay.js ADDED
@@ -0,0 +1,156 @@
1
+ //#region src/replay.ts
2
+ const ANTIGRAVITY_REPLAY_VERSION = 1;
3
+ const MAX_SIGNATURE_LENGTH = 16384;
4
+ const MAX_BLOCKS = 128;
5
+ /** Keep only provider-issued signatures and bounded response facts. */
6
+ function createReplayState(model, family, finish, blocks) {
7
+ const boundedBlocks = blocks.slice(0, MAX_BLOCKS).map((block) => {
8
+ const signature = safeSignature(block.signature);
9
+ return {
10
+ kind: block.kind,
11
+ ...signature === void 0 ? {} : { signature }
12
+ };
13
+ });
14
+ const boundedFinish = safeFinish(finish);
15
+ return {
16
+ response: {
17
+ version: 1,
18
+ provider: "google-antigravity",
19
+ model: model.slice(0, 256),
20
+ family,
21
+ ...boundedFinish === void 0 ? {} : { finish: boundedFinish }
22
+ },
23
+ blocks: boundedBlocks
24
+ };
25
+ }
26
+ /** Validate replay metadata before it can affect a later private request. */
27
+ function compatibleReplayState(message, provider, model, _blockKinds) {
28
+ if (provider !== "google-antigravity" || message.role !== "assistant") return void 0;
29
+ const provenance = isRecord(message.source) ? message.source : void 0;
30
+ if (provenance !== void 0 && provenance.kind === "model" && (provenance.provider !== provider || provenance.model !== model)) return void 0;
31
+ const value = isRecord(provenance?.replayState) ? provenance.replayState : isRecord(message.replayState) ? message.replayState : void 0;
32
+ if (!isRecord(value) || !isRecord(value.response) || !Array.isArray(value.blocks)) return void 0;
33
+ const family = value.response.family;
34
+ if (value.response.version !== 1 || value.response.provider !== provider || value.response.model !== model || !isFamily(family) || value.blocks.length > MAX_BLOCKS) return void 0;
35
+ const blocks = [];
36
+ for (const item of value.blocks) {
37
+ if (!isRecord(item) || typeof item.kind !== "string") continue;
38
+ const kind = item.kind;
39
+ const signature = typeof item.signature === "string" && safeSignature(item.signature) !== void 0 ? item.signature : void 0;
40
+ blocks.push({
41
+ kind,
42
+ ...signature === void 0 ? {} : { signature }
43
+ });
44
+ }
45
+ const finish = value.response.finish === void 0 ? void 0 : safeFinish(value.response.finish);
46
+ if (value.response.finish !== void 0 && finish === void 0) return void 0;
47
+ return {
48
+ response: {
49
+ version: 1,
50
+ provider: "google-antigravity",
51
+ model,
52
+ family,
53
+ ...finish === void 0 ? {} : { finish }
54
+ },
55
+ blocks
56
+ };
57
+ }
58
+ /** Return the block family without allowing a model alias to cross families. */
59
+ function antigravityModelFamily(model) {
60
+ const value = model.toLowerCase();
61
+ if (value.includes("gemini")) return "gemini";
62
+ if (value.includes("claude")) return "claude";
63
+ if (value.includes("gpt-oss")) return "gpt-oss";
64
+ return "unknown";
65
+ }
66
+ /** Convert DSH schemas to the small function-declaration subset accepted privately. */
67
+ function sanitizeToolSchemas(tools) {
68
+ if (tools === void 0) return [];
69
+ return tools.slice(0, 64).map((tool) => ({
70
+ name: boundedName(tool.name),
71
+ description: boundedText(tool.description, 4096),
72
+ parameters: sanitizeSchema(tool.parameters)
73
+ }));
74
+ }
75
+ function buildFunctionDeclarations(tools) {
76
+ return sanitizeToolSchemas(tools).map((tool) => ({
77
+ name: tool.name,
78
+ description: tool.description,
79
+ parameters: tool.parameters
80
+ }));
81
+ }
82
+ function sanitizeSchema(value, depth = 0) {
83
+ if (depth > 8 || !isRecord(value)) return {
84
+ type: "object",
85
+ properties: {}
86
+ };
87
+ const type = typeof value.type === "string" && [
88
+ "object",
89
+ "array",
90
+ "string",
91
+ "number",
92
+ "integer",
93
+ "boolean",
94
+ "null"
95
+ ].includes(value.type) ? value.type : "object";
96
+ const output = { type };
97
+ if (typeof value.description === "string") output.description = boundedText(value.description, 1024);
98
+ if (Array.isArray(value.required)) output.required = value.required.filter((item) => typeof item === "string").slice(0, 128);
99
+ if (Array.isArray(value.enum)) output.enum = value.enum.slice(0, 128).filter((item) => [
100
+ "string",
101
+ "number",
102
+ "boolean",
103
+ "null"
104
+ ].includes(typeof item));
105
+ if (type === "object" && isRecord(value.properties)) {
106
+ const properties = {};
107
+ for (const [key, item] of Object.entries(value.properties).slice(0, 128)) if (!hasControl(key) && key.length > 0) properties[key.slice(0, 128)] = sanitizeSchema(item, depth + 1);
108
+ output.properties = properties;
109
+ }
110
+ if (type === "array") output.items = sanitizeSchema(value.items, depth + 1);
111
+ if (Array.isArray(value.oneOf)) output.oneOf = value.oneOf.slice(0, 8).map((item) => sanitizeSchema(item, depth + 1));
112
+ return output;
113
+ }
114
+ function safeFinish(value) {
115
+ if (typeof value !== "string" || value.length === 0 || value.length > 128) return void 0;
116
+ const normalized = value.toUpperCase();
117
+ return [
118
+ "STOP",
119
+ "MAX_TOKENS",
120
+ "LENGTH",
121
+ "TOOL_CALLS",
122
+ "FUNCTION_CALL",
123
+ "SAFETY",
124
+ "BLOCKLIST",
125
+ "ERROR"
126
+ ].includes(normalized) ? normalized : void 0;
127
+ }
128
+ function safeSignature(value) {
129
+ if (typeof value !== "string" || value.length === 0 || value.length > MAX_SIGNATURE_LENGTH) return void 0;
130
+ for (const character of value) {
131
+ const code = character.charCodeAt(0);
132
+ if (code < 32 || code === 127) return void 0;
133
+ }
134
+ return value;
135
+ }
136
+ function boundedName(value) {
137
+ return typeof value === "string" && value.length > 0 && !hasControl(value) ? value.slice(0, 128) : "unnamed_tool";
138
+ }
139
+ function boundedText(value, limit) {
140
+ return typeof value === "string" && !hasControl(value) ? value.slice(0, limit) : "";
141
+ }
142
+ function hasControl(value) {
143
+ for (const character of value) {
144
+ const code = character.charCodeAt(0);
145
+ if (code < 32 || code === 127) return true;
146
+ }
147
+ return false;
148
+ }
149
+ function isFamily(value) {
150
+ return value === "gemini" || value === "claude" || value === "gpt-oss" || value === "unknown";
151
+ }
152
+ function isRecord(value) {
153
+ return typeof value === "object" && value !== null && !Array.isArray(value);
154
+ }
155
+ //#endregion
156
+ export { ANTIGRAVITY_REPLAY_VERSION, antigravityModelFamily, buildFunctionDeclarations, compatibleReplayState, createReplayState, sanitizeToolSchemas };