@benjamolina/pi-antigravity-guard 0.2.0 → 0.3.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.
- package/README.md +22 -5
- package/dist/catalog.d.ts +390 -0
- package/dist/catalog.js +166 -0
- package/dist/context.d.ts +8 -9
- package/dist/context.js +32 -18
- package/dist/provider.js +2 -11
- package/dist/stream.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pi Antigravity Guard
|
|
2
2
|
|
|
3
|
-
`@benjamolina/pi-antigravity-guard` is a Pi extension that registers the text-only `antigravity-guard` provider. It
|
|
3
|
+
`@benjamolina/pi-antigravity-guard` is a static Pi extension that registers the text-only `antigravity-guard` provider. It uses Pi-managed OAuth credentials and the existing Antigravity OAuth endpoint and quota path; it does not provide alternate credential routes, quota pools, fallback, or model substitution.
|
|
4
4
|
|
|
5
5
|
## Use
|
|
6
6
|
|
|
@@ -14,13 +14,30 @@ Choose browser login, or choose manual login and paste the complete callback URL
|
|
|
14
14
|
|
|
15
15
|
Start a fresh text-only session with `--no-builtin-tools` and disable any active extension-provided tools. That flag does not disable extension tools by itself. Tools, tool history, and images are unsupported and rejected rather than silently changed.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Supported static catalog
|
|
18
|
+
|
|
19
|
+
The provider registers only these evidence-admitted public IDs, in this order. `off` is available for every row even though it is omitted from Pi's level map; omitted reasoning also selects that row's `off` route. Unsupported levels are not advertised and are rejected before transport.
|
|
20
|
+
|
|
21
|
+
| Public ID | Exposed Pi levels | Context / output |
|
|
22
|
+
|---|---|---:|
|
|
23
|
+
| `antigravity-gemini-3.8-flash` | off, low, medium, high | 1,048,576 / 65,536 |
|
|
24
|
+
| `antigravity-gemini-3.7-flash` | off, low, medium, high | 1,048,576 / 65,536 |
|
|
25
|
+
| `antigravity-gemini-3.6-flash` | off, low, medium, high | 1,048,576 / 65,536 |
|
|
26
|
+
| `antigravity-gemini-3.1-pro` | off, low, high | 1,048,576 / 65,535 |
|
|
27
|
+
| `antigravity-claude-sonnet-4.6` | off, high | 250,000 / 64,000 |
|
|
28
|
+
| `antigravity-claude-opus-4.6-thinking` | off, high | 250,000 / 64,000 |
|
|
29
|
+
| `antigravity-gpt-oss-120b` | off, medium | 131,072 / 32,768 |
|
|
30
|
+
|
|
31
|
+
Gemini 3.8 remains compatible with the released mapping: `antigravity-gemini-3.8-flash` sends `gemini-3.8-flash-tiered`; `off` sends native `thinkingLevel: "low"` with hidden thoughts, and `low`, `medium`, and `high` send their matching native level with visible thoughts.
|
|
32
|
+
|
|
33
|
+
`antigravity-gemini-3.5-flash` is not registered or advertised as supported because its recorded HTTP-200 response lacks the strict terminal metadata required for admission.
|
|
18
34
|
|
|
19
35
|
## Limits and safety
|
|
20
36
|
|
|
21
|
-
|
|
37
|
+
An explicit `maxTokens` must be a positive integer no greater than the row's output limit. For a route with a positive finite thinking budget, it must also be greater than that budget. When `maxTokens` is omitted, the provider uses 4,096 unless a larger finite thinking budget needs a 1,024-token answer reserve, always bounded by the row's output limit. Custom `thinkingBudgets` are unsupported and rejected.
|
|
38
|
+
|
|
22
39
|
- Costs are reported as zero because subscription usage is unpriced, not because access is free.
|
|
23
|
-
- The
|
|
24
|
-
- It has no account rotation, quota fallback, model substitution, or
|
|
40
|
+
- The catalog is static: it performs no startup or runtime model discovery, catalog synchronization, or dynamic registration.
|
|
41
|
+
- It has no account rotation, quota fallback, model substitution, tool support, or image support.
|
|
25
42
|
|
|
26
43
|
To remove it, disable or uninstall `@benjamolina/pi-antigravity-guard` and reload Pi. Removal does not delete Pi-managed credentials or revoke tokens.
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
export type StandardReasoningLevel = "off" | "minimal" | "low" | "medium" | "high";
|
|
2
|
+
type NativeThinkingLevel = "low" | "medium" | "high";
|
|
3
|
+
type NativeRoute = {
|
|
4
|
+
readonly wireModel: string;
|
|
5
|
+
readonly thinking: {
|
|
6
|
+
readonly kind: "native-level";
|
|
7
|
+
readonly thinkingLevel: NativeThinkingLevel;
|
|
8
|
+
readonly includeThoughts: boolean;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
type IntegerBudgetRoute = {
|
|
12
|
+
readonly wireModel: string;
|
|
13
|
+
readonly thinking: {
|
|
14
|
+
readonly kind: "budget";
|
|
15
|
+
readonly budget: number;
|
|
16
|
+
readonly includeThoughts: boolean;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: "omit";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export type GenerationRoute = NativeRoute | IntegerBudgetRoute;
|
|
22
|
+
export interface CatalogEntry {
|
|
23
|
+
readonly publicId: string;
|
|
24
|
+
readonly descriptor: {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly thinkingLevelMap: Readonly<Record<"minimal" | "low" | "medium" | "high", string | null>>;
|
|
27
|
+
readonly contextWindow: number;
|
|
28
|
+
readonly maxTokens: number;
|
|
29
|
+
};
|
|
30
|
+
readonly routes: Readonly<Partial<Record<StandardReasoningLevel, GenerationRoute>>>;
|
|
31
|
+
readonly replay: {
|
|
32
|
+
readonly kind: "same-public-model" | "strip";
|
|
33
|
+
};
|
|
34
|
+
readonly response: {
|
|
35
|
+
readonly kind: "gemini-envelope";
|
|
36
|
+
readonly family: "gemini" | "claude" | "gpt-oss";
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
declare const CATALOG: readonly [{
|
|
40
|
+
readonly publicId: "antigravity-gemini-3.8-flash";
|
|
41
|
+
readonly descriptor: {
|
|
42
|
+
readonly name: "Gemini 3.8 Flash (Antigravity, text only)";
|
|
43
|
+
readonly thinkingLevelMap: {
|
|
44
|
+
readonly minimal: null;
|
|
45
|
+
readonly low: "low";
|
|
46
|
+
readonly medium: "medium";
|
|
47
|
+
readonly high: "high";
|
|
48
|
+
};
|
|
49
|
+
readonly contextWindow: 1048576;
|
|
50
|
+
readonly maxTokens: 65536;
|
|
51
|
+
};
|
|
52
|
+
readonly routes: {
|
|
53
|
+
readonly off: {
|
|
54
|
+
readonly wireModel: "gemini-3.8-flash-tiered";
|
|
55
|
+
readonly thinking: {
|
|
56
|
+
readonly kind: "native-level";
|
|
57
|
+
readonly thinkingLevel: "low";
|
|
58
|
+
readonly includeThoughts: false;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
readonly low: {
|
|
62
|
+
readonly wireModel: "gemini-3.8-flash-tiered";
|
|
63
|
+
readonly thinking: {
|
|
64
|
+
readonly kind: "native-level";
|
|
65
|
+
readonly thinkingLevel: "low";
|
|
66
|
+
readonly includeThoughts: true;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
readonly medium: {
|
|
70
|
+
readonly wireModel: "gemini-3.8-flash-tiered";
|
|
71
|
+
readonly thinking: {
|
|
72
|
+
readonly kind: "native-level";
|
|
73
|
+
readonly thinkingLevel: "medium";
|
|
74
|
+
readonly includeThoughts: true;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
readonly high: {
|
|
78
|
+
readonly wireModel: "gemini-3.8-flash-tiered";
|
|
79
|
+
readonly thinking: {
|
|
80
|
+
readonly kind: "native-level";
|
|
81
|
+
readonly thinkingLevel: "high";
|
|
82
|
+
readonly includeThoughts: true;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
readonly replay: {
|
|
87
|
+
readonly kind: "same-public-model";
|
|
88
|
+
};
|
|
89
|
+
readonly response: {
|
|
90
|
+
readonly kind: "gemini-envelope";
|
|
91
|
+
readonly family: "gemini";
|
|
92
|
+
};
|
|
93
|
+
}, {
|
|
94
|
+
readonly publicId: "antigravity-gemini-3.7-flash";
|
|
95
|
+
readonly descriptor: {
|
|
96
|
+
readonly name: "Gemini 3.7 Flash (Antigravity, text only)";
|
|
97
|
+
readonly thinkingLevelMap: {
|
|
98
|
+
readonly minimal: null;
|
|
99
|
+
readonly low: "low";
|
|
100
|
+
readonly medium: "medium";
|
|
101
|
+
readonly high: "high";
|
|
102
|
+
};
|
|
103
|
+
readonly contextWindow: 1048576;
|
|
104
|
+
readonly maxTokens: 65536;
|
|
105
|
+
};
|
|
106
|
+
readonly routes: {
|
|
107
|
+
readonly off: {
|
|
108
|
+
readonly wireModel: "gemini-3.7-flash-low";
|
|
109
|
+
readonly thinking: {
|
|
110
|
+
readonly kind: "budget";
|
|
111
|
+
readonly budget: 0;
|
|
112
|
+
readonly includeThoughts: false;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
readonly low: {
|
|
116
|
+
readonly wireModel: "gemini-3.7-flash-low";
|
|
117
|
+
readonly thinking: {
|
|
118
|
+
readonly kind: "budget";
|
|
119
|
+
readonly budget: 1000;
|
|
120
|
+
readonly includeThoughts: true;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
readonly medium: {
|
|
124
|
+
readonly wireModel: "gemini-3.7-flash-medium";
|
|
125
|
+
readonly thinking: {
|
|
126
|
+
readonly kind: "budget";
|
|
127
|
+
readonly budget: 4000;
|
|
128
|
+
readonly includeThoughts: true;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
readonly high: {
|
|
132
|
+
readonly wireModel: "gemini-3.7-flash-high";
|
|
133
|
+
readonly thinking: {
|
|
134
|
+
readonly kind: "budget";
|
|
135
|
+
readonly budget: -1;
|
|
136
|
+
readonly includeThoughts: true;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
readonly replay: {
|
|
141
|
+
readonly kind: "strip";
|
|
142
|
+
};
|
|
143
|
+
readonly response: {
|
|
144
|
+
readonly kind: "gemini-envelope";
|
|
145
|
+
readonly family: "gemini";
|
|
146
|
+
};
|
|
147
|
+
}, {
|
|
148
|
+
readonly publicId: "antigravity-gemini-3.6-flash";
|
|
149
|
+
readonly descriptor: {
|
|
150
|
+
readonly name: "Gemini 3.6 Flash (Antigravity, text only)";
|
|
151
|
+
readonly thinkingLevelMap: {
|
|
152
|
+
readonly minimal: null;
|
|
153
|
+
readonly low: "low";
|
|
154
|
+
readonly medium: "medium";
|
|
155
|
+
readonly high: "high";
|
|
156
|
+
};
|
|
157
|
+
readonly contextWindow: 1048576;
|
|
158
|
+
readonly maxTokens: 65536;
|
|
159
|
+
};
|
|
160
|
+
readonly routes: {
|
|
161
|
+
readonly off: {
|
|
162
|
+
readonly wireModel: "gemini-3.6-flash-low";
|
|
163
|
+
readonly thinking: {
|
|
164
|
+
readonly kind: "omit";
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
readonly low: {
|
|
168
|
+
readonly wireModel: "gemini-3.6-flash-low";
|
|
169
|
+
readonly thinking: {
|
|
170
|
+
readonly kind: "budget";
|
|
171
|
+
readonly budget: 1000;
|
|
172
|
+
readonly includeThoughts: true;
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
readonly medium: {
|
|
176
|
+
readonly wireModel: "gemini-3.6-flash-medium";
|
|
177
|
+
readonly thinking: {
|
|
178
|
+
readonly kind: "budget";
|
|
179
|
+
readonly budget: 4000;
|
|
180
|
+
readonly includeThoughts: true;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
readonly high: {
|
|
184
|
+
readonly wireModel: "gemini-3.6-flash-high";
|
|
185
|
+
readonly thinking: {
|
|
186
|
+
readonly kind: "budget";
|
|
187
|
+
readonly budget: -1;
|
|
188
|
+
readonly includeThoughts: true;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
readonly replay: {
|
|
193
|
+
readonly kind: "strip";
|
|
194
|
+
};
|
|
195
|
+
readonly response: {
|
|
196
|
+
readonly kind: "gemini-envelope";
|
|
197
|
+
readonly family: "gemini";
|
|
198
|
+
};
|
|
199
|
+
}, {
|
|
200
|
+
readonly publicId: "antigravity-gemini-3.1-pro";
|
|
201
|
+
readonly descriptor: {
|
|
202
|
+
readonly name: "Gemini 3.1 Pro (Antigravity, text only)";
|
|
203
|
+
readonly thinkingLevelMap: {
|
|
204
|
+
readonly minimal: null;
|
|
205
|
+
readonly low: "low";
|
|
206
|
+
readonly medium: null;
|
|
207
|
+
readonly high: "high";
|
|
208
|
+
};
|
|
209
|
+
readonly contextWindow: 1048576;
|
|
210
|
+
readonly maxTokens: 65535;
|
|
211
|
+
};
|
|
212
|
+
readonly routes: {
|
|
213
|
+
readonly off: {
|
|
214
|
+
readonly wireModel: "gemini-3.1-pro-low";
|
|
215
|
+
readonly thinking: {
|
|
216
|
+
readonly kind: "omit";
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
readonly low: {
|
|
220
|
+
readonly wireModel: "gemini-3.1-pro-low";
|
|
221
|
+
readonly thinking: {
|
|
222
|
+
readonly kind: "budget";
|
|
223
|
+
readonly budget: 1001;
|
|
224
|
+
readonly includeThoughts: true;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
readonly high: {
|
|
228
|
+
readonly wireModel: "gemini-pro-agent";
|
|
229
|
+
readonly thinking: {
|
|
230
|
+
readonly kind: "budget";
|
|
231
|
+
readonly budget: 10001;
|
|
232
|
+
readonly includeThoughts: true;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
readonly replay: {
|
|
237
|
+
readonly kind: "strip";
|
|
238
|
+
};
|
|
239
|
+
readonly response: {
|
|
240
|
+
readonly kind: "gemini-envelope";
|
|
241
|
+
readonly family: "gemini";
|
|
242
|
+
};
|
|
243
|
+
}, {
|
|
244
|
+
readonly publicId: "antigravity-claude-sonnet-4.6";
|
|
245
|
+
readonly descriptor: {
|
|
246
|
+
readonly name: "Claude Sonnet 4.6 (Antigravity, text only)";
|
|
247
|
+
readonly thinkingLevelMap: {
|
|
248
|
+
readonly minimal: null;
|
|
249
|
+
readonly low: null;
|
|
250
|
+
readonly medium: null;
|
|
251
|
+
readonly high: "high";
|
|
252
|
+
};
|
|
253
|
+
readonly contextWindow: 250000;
|
|
254
|
+
readonly maxTokens: 64000;
|
|
255
|
+
};
|
|
256
|
+
readonly routes: {
|
|
257
|
+
readonly off: {
|
|
258
|
+
readonly wireModel: "claude-sonnet-4-6";
|
|
259
|
+
readonly thinking: {
|
|
260
|
+
readonly kind: "budget";
|
|
261
|
+
readonly budget: 0;
|
|
262
|
+
readonly includeThoughts: false;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
readonly high: {
|
|
266
|
+
readonly wireModel: "claude-sonnet-4-6";
|
|
267
|
+
readonly thinking: {
|
|
268
|
+
readonly kind: "budget";
|
|
269
|
+
readonly budget: 1024;
|
|
270
|
+
readonly includeThoughts: true;
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
readonly replay: {
|
|
275
|
+
readonly kind: "strip";
|
|
276
|
+
};
|
|
277
|
+
readonly response: {
|
|
278
|
+
readonly kind: "gemini-envelope";
|
|
279
|
+
readonly family: "claude";
|
|
280
|
+
};
|
|
281
|
+
}, {
|
|
282
|
+
readonly publicId: "antigravity-claude-opus-4.6-thinking";
|
|
283
|
+
readonly descriptor: {
|
|
284
|
+
readonly name: "Claude Opus 4.6 Thinking (Antigravity, text only)";
|
|
285
|
+
readonly thinkingLevelMap: {
|
|
286
|
+
readonly minimal: null;
|
|
287
|
+
readonly low: null;
|
|
288
|
+
readonly medium: null;
|
|
289
|
+
readonly high: "high";
|
|
290
|
+
};
|
|
291
|
+
readonly contextWindow: 250000;
|
|
292
|
+
readonly maxTokens: 64000;
|
|
293
|
+
};
|
|
294
|
+
readonly routes: {
|
|
295
|
+
readonly off: {
|
|
296
|
+
readonly wireModel: "claude-opus-4-6-thinking";
|
|
297
|
+
readonly thinking: {
|
|
298
|
+
readonly kind: "budget";
|
|
299
|
+
readonly budget: 0;
|
|
300
|
+
readonly includeThoughts: false;
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
readonly high: {
|
|
304
|
+
readonly wireModel: "claude-opus-4-6-thinking";
|
|
305
|
+
readonly thinking: {
|
|
306
|
+
readonly kind: "budget";
|
|
307
|
+
readonly budget: 1024;
|
|
308
|
+
readonly includeThoughts: true;
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
};
|
|
312
|
+
readonly replay: {
|
|
313
|
+
readonly kind: "strip";
|
|
314
|
+
};
|
|
315
|
+
readonly response: {
|
|
316
|
+
readonly kind: "gemini-envelope";
|
|
317
|
+
readonly family: "claude";
|
|
318
|
+
};
|
|
319
|
+
}, {
|
|
320
|
+
readonly publicId: "antigravity-gpt-oss-120b";
|
|
321
|
+
readonly descriptor: {
|
|
322
|
+
readonly name: "GPT-OSS 120B (Antigravity, text only)";
|
|
323
|
+
readonly thinkingLevelMap: {
|
|
324
|
+
readonly minimal: null;
|
|
325
|
+
readonly low: null;
|
|
326
|
+
readonly medium: "medium";
|
|
327
|
+
readonly high: null;
|
|
328
|
+
};
|
|
329
|
+
readonly contextWindow: 131072;
|
|
330
|
+
readonly maxTokens: 32768;
|
|
331
|
+
};
|
|
332
|
+
readonly routes: {
|
|
333
|
+
readonly off: {
|
|
334
|
+
readonly wireModel: "gpt-oss-120b-medium";
|
|
335
|
+
readonly thinking: {
|
|
336
|
+
readonly kind: "omit";
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
readonly medium: {
|
|
340
|
+
readonly wireModel: "gpt-oss-120b-medium";
|
|
341
|
+
readonly thinking: {
|
|
342
|
+
readonly kind: "budget";
|
|
343
|
+
readonly budget: 8192;
|
|
344
|
+
readonly includeThoughts: true;
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
readonly replay: {
|
|
349
|
+
readonly kind: "strip";
|
|
350
|
+
};
|
|
351
|
+
readonly response: {
|
|
352
|
+
readonly kind: "gemini-envelope";
|
|
353
|
+
readonly family: "gpt-oss";
|
|
354
|
+
};
|
|
355
|
+
}];
|
|
356
|
+
type Catalog = typeof CATALOG;
|
|
357
|
+
export type AntigravityPublicModelId = Catalog[number]["publicId"];
|
|
358
|
+
export type AntigravityWireModelId = Catalog[number]["routes"][keyof Catalog[number]["routes"]]["wireModel"];
|
|
359
|
+
export declare function defineCatalog<T extends readonly {
|
|
360
|
+
readonly publicId: string;
|
|
361
|
+
readonly descriptor?: CatalogEntry["descriptor"];
|
|
362
|
+
readonly routes: Readonly<Record<string, {
|
|
363
|
+
readonly wireModel: string;
|
|
364
|
+
readonly thinking?: GenerationRoute["thinking"];
|
|
365
|
+
}>>;
|
|
366
|
+
}[]>(entries: T): T;
|
|
367
|
+
export declare function listCatalogEntries(): readonly CatalogEntry[];
|
|
368
|
+
export declare function getCatalogEntry(publicId: unknown): CatalogEntry | undefined;
|
|
369
|
+
export declare function resolveGenerationRoute(entry: CatalogEntry, reasoning: unknown): GenerationRoute;
|
|
370
|
+
export declare function toPiModelDescriptor(entry: CatalogEntry): {
|
|
371
|
+
id: string;
|
|
372
|
+
name: string;
|
|
373
|
+
reasoning: boolean;
|
|
374
|
+
thinkingLevelMap: {
|
|
375
|
+
high: string | null;
|
|
376
|
+
low: string | null;
|
|
377
|
+
medium: string | null;
|
|
378
|
+
minimal: string | null;
|
|
379
|
+
};
|
|
380
|
+
input: "text"[];
|
|
381
|
+
cost: {
|
|
382
|
+
input: number;
|
|
383
|
+
output: number;
|
|
384
|
+
cacheRead: number;
|
|
385
|
+
cacheWrite: number;
|
|
386
|
+
};
|
|
387
|
+
contextWindow: number;
|
|
388
|
+
maxTokens: number;
|
|
389
|
+
};
|
|
390
|
+
export {};
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const ANSWER_RESERVE = 1024;
|
|
2
|
+
const CATALOG = freeze(defineCatalog([{
|
|
3
|
+
publicId: "antigravity-gemini-3.8-flash",
|
|
4
|
+
descriptor: {
|
|
5
|
+
name: "Gemini 3.8 Flash (Antigravity, text only)",
|
|
6
|
+
thinkingLevelMap: { minimal: null, low: "low", medium: "medium", high: "high" },
|
|
7
|
+
contextWindow: 1_048_576,
|
|
8
|
+
maxTokens: 65_536,
|
|
9
|
+
},
|
|
10
|
+
routes: {
|
|
11
|
+
off: { wireModel: "gemini-3.8-flash-tiered", thinking: { kind: "native-level", thinkingLevel: "low", includeThoughts: false } },
|
|
12
|
+
low: { wireModel: "gemini-3.8-flash-tiered", thinking: { kind: "native-level", thinkingLevel: "low", includeThoughts: true } },
|
|
13
|
+
medium: { wireModel: "gemini-3.8-flash-tiered", thinking: { kind: "native-level", thinkingLevel: "medium", includeThoughts: true } },
|
|
14
|
+
high: { wireModel: "gemini-3.8-flash-tiered", thinking: { kind: "native-level", thinkingLevel: "high", includeThoughts: true } },
|
|
15
|
+
},
|
|
16
|
+
replay: { kind: "same-public-model" },
|
|
17
|
+
response: { kind: "gemini-envelope", family: "gemini" },
|
|
18
|
+
}, {
|
|
19
|
+
publicId: "antigravity-gemini-3.7-flash",
|
|
20
|
+
descriptor: {
|
|
21
|
+
name: "Gemini 3.7 Flash (Antigravity, text only)",
|
|
22
|
+
thinkingLevelMap: { minimal: null, low: "low", medium: "medium", high: "high" },
|
|
23
|
+
contextWindow: 1_048_576,
|
|
24
|
+
maxTokens: 65_536,
|
|
25
|
+
},
|
|
26
|
+
routes: {
|
|
27
|
+
off: { wireModel: "gemini-3.7-flash-low", thinking: { kind: "budget", budget: 0, includeThoughts: false } },
|
|
28
|
+
low: { wireModel: "gemini-3.7-flash-low", thinking: { kind: "budget", budget: 1000, includeThoughts: true } },
|
|
29
|
+
medium: { wireModel: "gemini-3.7-flash-medium", thinking: { kind: "budget", budget: 4000, includeThoughts: true } },
|
|
30
|
+
high: { wireModel: "gemini-3.7-flash-high", thinking: { kind: "budget", budget: -1, includeThoughts: true } },
|
|
31
|
+
},
|
|
32
|
+
replay: { kind: "strip" },
|
|
33
|
+
response: { kind: "gemini-envelope", family: "gemini" },
|
|
34
|
+
}, {
|
|
35
|
+
publicId: "antigravity-gemini-3.6-flash",
|
|
36
|
+
descriptor: {
|
|
37
|
+
name: "Gemini 3.6 Flash (Antigravity, text only)",
|
|
38
|
+
thinkingLevelMap: { minimal: null, low: "low", medium: "medium", high: "high" },
|
|
39
|
+
contextWindow: 1_048_576,
|
|
40
|
+
maxTokens: 65_536,
|
|
41
|
+
},
|
|
42
|
+
routes: {
|
|
43
|
+
off: { wireModel: "gemini-3.6-flash-low", thinking: { kind: "omit" } },
|
|
44
|
+
low: { wireModel: "gemini-3.6-flash-low", thinking: { kind: "budget", budget: 1000, includeThoughts: true } },
|
|
45
|
+
medium: { wireModel: "gemini-3.6-flash-medium", thinking: { kind: "budget", budget: 4000, includeThoughts: true } },
|
|
46
|
+
high: { wireModel: "gemini-3.6-flash-high", thinking: { kind: "budget", budget: -1, includeThoughts: true } },
|
|
47
|
+
},
|
|
48
|
+
replay: { kind: "strip" },
|
|
49
|
+
response: { kind: "gemini-envelope", family: "gemini" },
|
|
50
|
+
}, {
|
|
51
|
+
publicId: "antigravity-gemini-3.1-pro",
|
|
52
|
+
descriptor: {
|
|
53
|
+
name: "Gemini 3.1 Pro (Antigravity, text only)",
|
|
54
|
+
thinkingLevelMap: { minimal: null, low: "low", medium: null, high: "high" },
|
|
55
|
+
contextWindow: 1_048_576,
|
|
56
|
+
maxTokens: 65_535,
|
|
57
|
+
},
|
|
58
|
+
routes: {
|
|
59
|
+
off: { wireModel: "gemini-3.1-pro-low", thinking: { kind: "omit" } },
|
|
60
|
+
low: { wireModel: "gemini-3.1-pro-low", thinking: { kind: "budget", budget: 1001, includeThoughts: true } },
|
|
61
|
+
high: { wireModel: "gemini-pro-agent", thinking: { kind: "budget", budget: 10001, includeThoughts: true } },
|
|
62
|
+
},
|
|
63
|
+
replay: { kind: "strip" },
|
|
64
|
+
response: { kind: "gemini-envelope", family: "gemini" },
|
|
65
|
+
}, {
|
|
66
|
+
publicId: "antigravity-claude-sonnet-4.6",
|
|
67
|
+
descriptor: {
|
|
68
|
+
name: "Claude Sonnet 4.6 (Antigravity, text only)",
|
|
69
|
+
thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high" },
|
|
70
|
+
contextWindow: 250_000,
|
|
71
|
+
maxTokens: 64_000,
|
|
72
|
+
},
|
|
73
|
+
routes: {
|
|
74
|
+
off: { wireModel: "claude-sonnet-4-6", thinking: { kind: "budget", budget: 0, includeThoughts: false } },
|
|
75
|
+
high: { wireModel: "claude-sonnet-4-6", thinking: { kind: "budget", budget: 1024, includeThoughts: true } },
|
|
76
|
+
},
|
|
77
|
+
replay: { kind: "strip" },
|
|
78
|
+
response: { kind: "gemini-envelope", family: "claude" },
|
|
79
|
+
}, {
|
|
80
|
+
publicId: "antigravity-claude-opus-4.6-thinking",
|
|
81
|
+
descriptor: {
|
|
82
|
+
name: "Claude Opus 4.6 Thinking (Antigravity, text only)",
|
|
83
|
+
thinkingLevelMap: { minimal: null, low: null, medium: null, high: "high" },
|
|
84
|
+
contextWindow: 250_000,
|
|
85
|
+
maxTokens: 64_000,
|
|
86
|
+
},
|
|
87
|
+
routes: {
|
|
88
|
+
off: { wireModel: "claude-opus-4-6-thinking", thinking: { kind: "budget", budget: 0, includeThoughts: false } },
|
|
89
|
+
high: { wireModel: "claude-opus-4-6-thinking", thinking: { kind: "budget", budget: 1024, includeThoughts: true } },
|
|
90
|
+
},
|
|
91
|
+
replay: { kind: "strip" },
|
|
92
|
+
response: { kind: "gemini-envelope", family: "claude" },
|
|
93
|
+
}, {
|
|
94
|
+
publicId: "antigravity-gpt-oss-120b",
|
|
95
|
+
descriptor: {
|
|
96
|
+
name: "GPT-OSS 120B (Antigravity, text only)",
|
|
97
|
+
thinkingLevelMap: { minimal: null, low: null, medium: "medium", high: null },
|
|
98
|
+
contextWindow: 131_072,
|
|
99
|
+
maxTokens: 32_768,
|
|
100
|
+
},
|
|
101
|
+
routes: {
|
|
102
|
+
off: { wireModel: "gpt-oss-120b-medium", thinking: { kind: "omit" } },
|
|
103
|
+
medium: { wireModel: "gpt-oss-120b-medium", thinking: { kind: "budget", budget: 8192, includeThoughts: true } },
|
|
104
|
+
},
|
|
105
|
+
replay: { kind: "strip" },
|
|
106
|
+
response: { kind: "gemini-envelope", family: "gpt-oss" },
|
|
107
|
+
}]));
|
|
108
|
+
const lookup = new Map(CATALOG.map((entry) => [entry.publicId, entry]));
|
|
109
|
+
function freeze(value) {
|
|
110
|
+
if (typeof value === "object" && value !== null) {
|
|
111
|
+
Object.freeze(value);
|
|
112
|
+
for (const child of Object.values(value))
|
|
113
|
+
freeze(child);
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
export function defineCatalog(entries) {
|
|
118
|
+
const identities = new Set();
|
|
119
|
+
for (const entry of entries) {
|
|
120
|
+
if (identities.has(entry.publicId))
|
|
121
|
+
throw new Error(`Duplicate public model ID: ${entry.publicId}`);
|
|
122
|
+
identities.add(entry.publicId);
|
|
123
|
+
if (!Object.keys(entry.routes).length)
|
|
124
|
+
throw new Error(`Model has no routes: ${entry.publicId}`);
|
|
125
|
+
if (!entry.descriptor)
|
|
126
|
+
continue;
|
|
127
|
+
for (const [level, route] of Object.entries(entry.routes)) {
|
|
128
|
+
if (!route.thinking)
|
|
129
|
+
throw new Error(`Route has no thinking policy: ${entry.publicId}/${level}`);
|
|
130
|
+
if (level !== "off" && !Object.hasOwn(entry.descriptor.thinkingLevelMap, level)) {
|
|
131
|
+
throw new Error(`Route is outside descriptor map: ${entry.publicId}/${level}`);
|
|
132
|
+
}
|
|
133
|
+
if (level !== "off" && entry.descriptor.thinkingLevelMap[level] === null) {
|
|
134
|
+
throw new Error(`Route is hidden by descriptor: ${entry.publicId}/${level}`);
|
|
135
|
+
}
|
|
136
|
+
if (route.thinking.kind === "budget" && route.thinking.budget > 0 && Number.isFinite(route.thinking.budget) && route.thinking.budget + ANSWER_RESERVE > entry.descriptor.maxTokens) {
|
|
137
|
+
throw new Error(`Finite thinking budget does not leave answer reserve: ${entry.publicId}/${level}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return entries;
|
|
142
|
+
}
|
|
143
|
+
export function listCatalogEntries() {
|
|
144
|
+
return CATALOG;
|
|
145
|
+
}
|
|
146
|
+
export function getCatalogEntry(publicId) {
|
|
147
|
+
return typeof publicId === "string" ? lookup.get(publicId) : undefined;
|
|
148
|
+
}
|
|
149
|
+
export function resolveGenerationRoute(entry, reasoning) {
|
|
150
|
+
const level = reasoning === undefined || reasoning === "off" ? "off" : reasoning;
|
|
151
|
+
if (typeof level !== "string" || !entry.routes[level])
|
|
152
|
+
throw new Error("Unsupported reasoning level");
|
|
153
|
+
return entry.routes[level];
|
|
154
|
+
}
|
|
155
|
+
export function toPiModelDescriptor(entry) {
|
|
156
|
+
return {
|
|
157
|
+
id: entry.publicId,
|
|
158
|
+
name: entry.descriptor.name,
|
|
159
|
+
reasoning: true,
|
|
160
|
+
thinkingLevelMap: { ...entry.descriptor.thinkingLevelMap },
|
|
161
|
+
input: ["text"],
|
|
162
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
163
|
+
contextWindow: entry.descriptor.contextWindow,
|
|
164
|
+
maxTokens: entry.descriptor.maxTokens,
|
|
165
|
+
};
|
|
166
|
+
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { Context, Model, SimpleStreamOptions } from "@earendil-works/pi-ai";
|
|
2
|
-
declare const WIRE_MODEL = "gemini-3.8-flash-tiered";
|
|
3
|
-
declare const THINKING_LEVELS: readonly ["low", "medium", "high"];
|
|
4
|
-
type ThinkingLevel = typeof THINKING_LEVELS[number];
|
|
5
2
|
interface Part {
|
|
6
3
|
text: string;
|
|
7
4
|
thought?: true;
|
|
@@ -11,13 +8,9 @@ interface Content {
|
|
|
11
8
|
role: "user" | "model";
|
|
12
9
|
parts: Part[];
|
|
13
10
|
}
|
|
14
|
-
interface ThinkingConfig {
|
|
15
|
-
thinkingLevel: ThinkingLevel;
|
|
16
|
-
includeThoughts: boolean;
|
|
17
|
-
}
|
|
18
11
|
export interface GenerationRequest {
|
|
19
12
|
project: string;
|
|
20
|
-
model:
|
|
13
|
+
model: string;
|
|
21
14
|
request: {
|
|
22
15
|
contents: Content[];
|
|
23
16
|
systemInstruction?: {
|
|
@@ -26,7 +19,13 @@ export interface GenerationRequest {
|
|
|
26
19
|
generationConfig: {
|
|
27
20
|
temperature: number;
|
|
28
21
|
maxOutputTokens: number;
|
|
29
|
-
thinkingConfig
|
|
22
|
+
thinkingConfig?: {
|
|
23
|
+
thinkingLevel: "low" | "medium" | "high";
|
|
24
|
+
includeThoughts: boolean;
|
|
25
|
+
} | {
|
|
26
|
+
thinkingBudget: number;
|
|
27
|
+
includeThoughts: boolean;
|
|
28
|
+
};
|
|
30
29
|
};
|
|
31
30
|
};
|
|
32
31
|
requestType: "agent";
|
package/dist/context.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
+
import { getCatalogEntry, resolveGenerationRoute } from "./catalog.js";
|
|
1
2
|
const MAX_TEXT_BYTES = 8 * 1024 * 1024;
|
|
2
|
-
const MAX_OUTPUT_TOKENS = 65_536;
|
|
3
3
|
const PROVIDER = "antigravity-guard";
|
|
4
|
-
const PUBLIC_MODEL = "antigravity-gemini-3.8-flash";
|
|
5
|
-
const WIRE_MODEL = "gemini-3.8-flash-tiered";
|
|
6
4
|
const RESERVED_HEADERS = new Set(["authorization", "host", "content-type", "content-length"]);
|
|
7
5
|
const THINKING_LEVELS = ["low", "medium", "high"];
|
|
8
6
|
export class ContextSerializationError extends Error {
|
|
@@ -16,8 +14,10 @@ export function serializeTextContext(input) {
|
|
|
16
14
|
const options = field(input, "options");
|
|
17
15
|
const project = field(input, "project", true);
|
|
18
16
|
const requestId = field(input, "requestId", true);
|
|
19
|
-
|
|
17
|
+
const entry = isRecord(model) ? getCatalogEntry(field(model, "id", true)) : undefined;
|
|
18
|
+
if (!isRecord(context) || !entry || typeof project !== "string" || typeof requestId !== "string")
|
|
20
19
|
fail("Invalid text context.");
|
|
20
|
+
const route = resolveGenerationRoute(entry, option(options, "reasoning"));
|
|
21
21
|
const systemPrompt = field(context, "systemPrompt");
|
|
22
22
|
const tools = field(context, "tools");
|
|
23
23
|
if (systemPrompt !== undefined && typeof systemPrompt !== "string")
|
|
@@ -36,7 +36,7 @@ export function serializeTextContext(input) {
|
|
|
36
36
|
if (role !== "user" && role !== "assistant")
|
|
37
37
|
fail("Unsupported context role for this text-only provider.");
|
|
38
38
|
const assistant = role === "assistant";
|
|
39
|
-
const parts = messageParts(field(message, "content", true), assistant, assistant && isSameProviderAndModel(message));
|
|
39
|
+
const parts = messageParts(field(message, "content", true), assistant, assistant && entry.replay.kind === "same-public-model" && isSameProviderAndModel(message, entry.publicId));
|
|
40
40
|
textBytes += parts.reduce((total, part) => total + byteLength(part.text), 0);
|
|
41
41
|
if (textBytes > MAX_TEXT_BYTES)
|
|
42
42
|
fail("Text context is too large.");
|
|
@@ -47,10 +47,13 @@ export function serializeTextContext(input) {
|
|
|
47
47
|
const systemInstruction = systemPrompt === undefined ? undefined : { parts: [{ text: systemPrompt }] };
|
|
48
48
|
const temperature = option(options, "temperature");
|
|
49
49
|
const maxTokens = option(options, "maxTokens");
|
|
50
|
-
return { project, model:
|
|
50
|
+
return { project, model: route.wireModel, request: { contents, ...(systemInstruction ? { systemInstruction } : {}), generationConfig: {
|
|
51
51
|
temperature: typeof temperature === "number" ? temperature : 1,
|
|
52
|
-
maxOutputTokens:
|
|
53
|
-
|
|
52
|
+
maxOutputTokens: resolveOutputTokens(maxTokens, entry.descriptor.maxTokens, route.thinking),
|
|
53
|
+
...(() => {
|
|
54
|
+
const thinkingConfig = serializeThinkingConfig(route.thinking);
|
|
55
|
+
return thinkingConfig ? { thinkingConfig } : {};
|
|
56
|
+
})(),
|
|
54
57
|
} }, requestType: "agent", userAgent: "antigravity", requestId };
|
|
55
58
|
}
|
|
56
59
|
catch (error) {
|
|
@@ -96,27 +99,38 @@ function messageParts(content, assistant, sameProviderAndModel) {
|
|
|
96
99
|
fail("Only text context is supported by this provider.");
|
|
97
100
|
});
|
|
98
101
|
}
|
|
99
|
-
function isSameProviderAndModel(message) {
|
|
100
|
-
return field(message, "provider") === PROVIDER && field(message, "model") ===
|
|
102
|
+
function isSameProviderAndModel(message, publicId) {
|
|
103
|
+
return field(message, "provider") === PROVIDER && field(message, "model") === publicId;
|
|
104
|
+
}
|
|
105
|
+
function serializeThinkingConfig(thinking) {
|
|
106
|
+
if (thinking.kind === "native-level")
|
|
107
|
+
return { thinkingLevel: thinking.thinkingLevel, includeThoughts: thinking.includeThoughts };
|
|
108
|
+
if (thinking.kind === "budget")
|
|
109
|
+
return { thinkingBudget: thinking.budget, includeThoughts: thinking.includeThoughts };
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
function resolveOutputTokens(maxTokens, maxAllowed, thinking) {
|
|
113
|
+
if (typeof maxTokens === "number") {
|
|
114
|
+
if (maxTokens > maxAllowed)
|
|
115
|
+
fail(`maxTokens must be a positive integer no greater than ${maxAllowed}.`);
|
|
116
|
+
if (thinking.kind === "budget" && thinking.budget > 0 && maxTokens <= thinking.budget)
|
|
117
|
+
fail("maxTokens must exceed the selected thinking budget.");
|
|
118
|
+
return maxTokens;
|
|
119
|
+
}
|
|
120
|
+
return thinking.kind === "budget" && thinking.budget > 0 ? Math.max(4096, thinking.budget + 1024) : 4096;
|
|
101
121
|
}
|
|
102
122
|
function validThoughtSignature(value) {
|
|
103
123
|
if (typeof value !== "string" || !value || value.length % 4 !== 0)
|
|
104
124
|
return undefined;
|
|
105
125
|
return /^[A-Za-z0-9+/]+={0,2}$/.test(value) ? value : undefined;
|
|
106
126
|
}
|
|
107
|
-
function resolveThinkingConfig(options) {
|
|
108
|
-
const reasoning = option(options, "reasoning");
|
|
109
|
-
if (isThinkingLevel(reasoning))
|
|
110
|
-
return { thinkingLevel: reasoning, includeThoughts: true };
|
|
111
|
-
return { thinkingLevel: "low", includeThoughts: false };
|
|
112
|
-
}
|
|
113
127
|
function validateOptions(options) {
|
|
114
128
|
if (options === undefined)
|
|
115
129
|
return;
|
|
116
130
|
if (!isRecord(options))
|
|
117
131
|
fail("Invalid generation options.");
|
|
118
132
|
const reasoning = option(options, "reasoning"), budgets = option(options, "thinkingBudgets"), deferred = option(options, "deferred"), toolChoice = option(options, "toolChoice"), sampling = option(options, "samplingParams"), temperature = option(options, "temperature"), maxTokens = option(options, "maxTokens"), headers = option(options, "headers");
|
|
119
|
-
if (reasoning !== undefined && reasoning !== "off" && !isThinkingLevel(reasoning))
|
|
133
|
+
if (reasoning !== undefined && reasoning !== "off" && !isThinkingLevel(reasoning) && reasoning !== "minimal")
|
|
120
134
|
fail("Unsupported reasoning level.");
|
|
121
135
|
if (budgets !== undefined)
|
|
122
136
|
fail("Thinking budgets are not supported.");
|
|
@@ -128,7 +142,7 @@ function validateOptions(options) {
|
|
|
128
142
|
fail("Custom generation options are not supported.");
|
|
129
143
|
if (temperature !== undefined && (typeof temperature !== "number" || !Number.isFinite(temperature) || temperature < 0 || temperature > 2))
|
|
130
144
|
fail("Temperature must be finite and between 0 and 2.");
|
|
131
|
-
if (maxTokens !== undefined && (typeof maxTokens !== "number" || !Number.isInteger(maxTokens) || maxTokens <= 0 || maxTokens >
|
|
145
|
+
if (maxTokens !== undefined && (typeof maxTokens !== "number" || !Number.isInteger(maxTokens) || maxTokens <= 0 || maxTokens > 65_536))
|
|
132
146
|
fail("maxTokens must be a positive integer no greater than 65536.");
|
|
133
147
|
if (headers !== undefined && !isRecord(headers))
|
|
134
148
|
fail("Invalid generation options.");
|
package/dist/provider.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ANTIGRAVITY_ENDPOINTS } from "@benjamolina/antigravity-guard-core";
|
|
2
|
+
import { listCatalogEntries, toPiModelDescriptor } from "./catalog.js";
|
|
2
3
|
import { createPiOAuthLifecycle } from "./oauth.js";
|
|
3
4
|
import { createPiLifecycleStream, executeStreamTransport } from "./stream.js";
|
|
4
5
|
const PROVIDER = "antigravity-guard";
|
|
5
6
|
const API = "antigravity-guard-sse";
|
|
6
|
-
const MODEL = "antigravity-gemini-3.8-flash";
|
|
7
7
|
const INVALID_CREDENTIALS = "Antigravity credentials are invalid. Run /login antigravity-guard.";
|
|
8
8
|
export function registerAntigravityProvider(pi) {
|
|
9
9
|
const oauth = createPiOAuthLifecycle({ fetch: globalThis.fetch, now: Date.now });
|
|
@@ -11,16 +11,7 @@ export function registerAntigravityProvider(pi) {
|
|
|
11
11
|
name: "Antigravity Guard",
|
|
12
12
|
baseUrl: ANTIGRAVITY_ENDPOINTS.daily,
|
|
13
13
|
api: API,
|
|
14
|
-
models:
|
|
15
|
-
id: MODEL,
|
|
16
|
-
name: "Gemini 3.8 Flash (Antigravity, text only)",
|
|
17
|
-
reasoning: true,
|
|
18
|
-
thinkingLevelMap: { minimal: null, low: "low", medium: "medium", high: "high" },
|
|
19
|
-
input: ["text"],
|
|
20
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
21
|
-
contextWindow: 1_048_576,
|
|
22
|
-
maxTokens: 65_536,
|
|
23
|
-
}],
|
|
14
|
+
models: listCatalogEntries().map(toPiModelDescriptor),
|
|
24
15
|
oauth: {
|
|
25
16
|
name: "Antigravity Guard",
|
|
26
17
|
isSubscription: true,
|
package/dist/stream.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { calculateCost, createAssistantMessageEventStream } from "@earendil-works/pi-ai";
|
|
2
2
|
import { ANTIGRAVITY_ENDPOINTS } from "@benjamolina/antigravity-guard-core";
|
|
3
|
+
import { getCatalogEntry } from "./catalog.js";
|
|
3
4
|
import { serializeTextContext } from "./context.js";
|
|
4
5
|
import { ResponseSemanticError, ResponseSemantics } from "./response.js";
|
|
5
6
|
import { SseFrameError, SseFramer } from "./sse.js";
|
|
@@ -9,7 +10,6 @@ const MAX_ERROR_BYTES = 64 * 1024;
|
|
|
9
10
|
const ANTIGRAVITY_USER_AGENT = "antigravity/cli/1.1.23 (aidev_client; os_type=linux; arch=amd64; cl=974125021; auth_method=consumer)";
|
|
10
11
|
const ENDPOINT = `${ANTIGRAVITY_ENDPOINTS.daily}/v1internal:streamGenerateContent?alt=sse`;
|
|
11
12
|
const API = "antigravity-guard-sse";
|
|
12
|
-
const MODEL = "antigravity-gemini-3.8-flash";
|
|
13
13
|
const PROTECTED_HEADERS = new Set(["authorization", "host", "content-type", "content-length"]);
|
|
14
14
|
const LOCAL_ERRORS = new WeakSet();
|
|
15
15
|
export class StreamTransportError extends Error {
|
|
@@ -169,7 +169,7 @@ export async function executeStreamTransport(input) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
function validateInput(input) {
|
|
172
|
-
if (input.model.id
|
|
172
|
+
if (!getCatalogEntry(input.model.id) || input.model.api !== API)
|
|
173
173
|
throw streamError("response", "The selected Antigravity model or API is unsupported.");
|
|
174
174
|
}
|
|
175
175
|
async function payloadHook(input, payload, signal) {
|