@benjamolina/pi-antigravity-guard 0.2.0 → 0.4.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 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 exposes exactly one selectable model, `antigravity-gemini-3.8-flash`, which is sent to Antigravity as `gemini-3.8-flash-tiered`.
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
 
@@ -12,15 +12,46 @@ Install the package in Pi, then run:
12
12
 
13
13
  Choose browser login, or choose manual login and paste the complete callback URL. The loopback callback uses fixed port `51121`; browser callback failures, remote shells, and port conflicts can use the manual callback-URL flow.
14
14
 
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.
15
+ ## Text registration is not tool enablement
16
16
 
17
- `@benjamolina/pi-antigravity-guard@0.2.0` supports Pi reasoning levels `low`, `medium`, and `high`. An authorized live matrix against `gemini-3.8-flash-tiered` confirmed all three levels; `minimal` was rejected twice with zero usage and is not exposed. Each supported level is sent as the matching native `thinkingLevel` with visible thoughts enabled. When reasoning is off or omitted, the request uses native `low` thinking without returning visible thoughts. Custom `thinkingBudgets` are unsupported and rejected.
17
+ All seven rows below are registered for text. Every production route is currently **not enabled for tools**, so a context with a declaration, assistant tool call, or tool result fails locally before any network request. Text-only requests retain their released behavior.
18
18
 
19
- ## Limits and safety
19
+ | Public ID | Exposed Pi levels | Tool state | Why tools are unavailable |
20
+ |---|---|---|---|
21
+ | `antigravity-gemini-3.8-flash` | off, low, medium, high | Disabled | missing-direct-evidence |
22
+ | `antigravity-gemini-3.7-flash` | off, low, medium, high | Disabled | missing-direct-evidence |
23
+ | `antigravity-gemini-3.6-flash` | off, low, medium, high | Disabled | missing-direct-evidence |
24
+ | `antigravity-gemini-3.1-pro` | off, low, high | Disabled | missing-direct-evidence |
25
+ | `antigravity-claude-sonnet-4.6` | off, high | Disabled | claude-continuity-unproven |
26
+ | `antigravity-claude-opus-4.6-thinking` | off, high | Disabled | claude-continuity-unproven |
27
+ | `antigravity-gpt-oss-120b` | off, medium | Disabled | missing-direct-evidence |
28
+
29
+ `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. `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. A future `fixture-qualified` route remains disabled for ordinary tool use; only separately authorized direct validation for the exact route may make it enabled.
30
+
31
+ Claude Sonnet and Claude Opus remain disabled until declaration, call, result replay, thinking-signature, resume, interruption, and continuation evidence is recorded for each exact route. No route is enabled by this package release.
32
+
33
+ ## Tool preflight boundaries
34
+
35
+ Tool-bearing requests are never silently downgraded to text. When an exact route is eventually enabled, declarations are retained in order and omitted or `auto` choice serializes as `AUTO`; explicit `none` serializes as `NONE`. Forced, required, named, unknown, and constrained-sampling choices are rejected before transport.
36
+
37
+ Schemas must use the documented strict object-rooted subset. Unsupported keywords, references, unions, lossy constraints, empty objects, and oversized input are rejected rather than cleaned. Tool results must match the exact call ID and name, remain text-only, and are replayed in assistant source-call order; image-bearing or ambiguous results are rejected. A missing persisted result uses the documented failed response only during context reconstruction.
38
+
39
+ ## Text catalog limits and safety
40
+
41
+ | Public ID | Exposed Pi levels | Context / output |
42
+ |---|---|---:|
43
+ | `antigravity-gemini-3.8-flash` | off, low, medium, high | 1,048,576 / 65,536 |
44
+ | `antigravity-gemini-3.7-flash` | off, low, medium, high | 1,048,576 / 65,536 |
45
+ | `antigravity-gemini-3.6-flash` | off, low, medium, high | 1,048,576 / 65,536 |
46
+ | `antigravity-gemini-3.1-pro` | off, low, high | 1,048,576 / 65,535 |
47
+ | `antigravity-claude-sonnet-4.6` | off, high | 250,000 / 64,000 |
48
+ | `antigravity-claude-opus-4.6-thinking` | off, high | 250,000 / 64,000 |
49
+ | `antigravity-gpt-oss-120b` | off, medium | 131,072 / 32,768 |
50
+
51
+ 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.
20
52
 
21
- - This provider stores credentials through Pi's OAuth lifecycle and never reads or changes OpenCode account files; each is independent.
22
53
  - Costs are reported as zero because subscription usage is unpriced, not because access is free.
23
- - The public-to-wire model mapping remains separate from availability and entitlement. The documented reasoning levels are limited to the authorized live matrix results above.
24
- - It has no account rotation, quota fallback, model substitution, or tool support.
54
+ - The catalog is static: it performs no startup or runtime model discovery, catalog synchronization, or dynamic registration.
55
+ - It has no account rotation, quota fallback, model substitution, image support, or enabled tools.
25
56
 
26
57
  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,446 @@
1
+ export type StandardReasoningLevel = "off" | "minimal" | "low" | "medium" | "high";
2
+ type NativeThinkingLevel = "low" | "medium" | "high";
3
+ export interface ToolEvidenceRef {
4
+ readonly record: string;
5
+ readonly revision: string;
6
+ readonly publicModelId: string;
7
+ readonly reasoning: StandardReasoningLevel;
8
+ readonly wireModel: string;
9
+ }
10
+ export type ToolCapability = {
11
+ readonly state: "disabled";
12
+ readonly contractRevision: 1;
13
+ readonly reason: "missing-direct-evidence" | "stale-or-conflicting-evidence" | "claude-continuity-unproven";
14
+ } | {
15
+ readonly state: "fixture-qualified";
16
+ readonly contractRevision: 1;
17
+ readonly fixtureEvidence: ToolEvidenceRef;
18
+ } | {
19
+ readonly state: "enabled";
20
+ readonly contractRevision: 1;
21
+ readonly fixtureEvidence: ToolEvidenceRef;
22
+ readonly directEvidence: ToolEvidenceRef;
23
+ };
24
+ type NativeRoute = {
25
+ readonly wireModel: string;
26
+ readonly thinking: {
27
+ readonly kind: "native-level";
28
+ readonly thinkingLevel: NativeThinkingLevel;
29
+ readonly includeThoughts: boolean;
30
+ };
31
+ };
32
+ type IntegerBudgetRoute = {
33
+ readonly wireModel: string;
34
+ readonly thinking: {
35
+ readonly kind: "budget";
36
+ readonly budget: number;
37
+ readonly includeThoughts: boolean;
38
+ } | {
39
+ readonly kind: "omit";
40
+ };
41
+ };
42
+ export type GenerationRoute = NativeRoute | IntegerBudgetRoute;
43
+ type ConfiguredGenerationRoute = GenerationRoute & {
44
+ readonly tools: ToolCapability;
45
+ };
46
+ export interface CatalogEntry {
47
+ readonly publicId: string;
48
+ readonly descriptor: {
49
+ readonly name: string;
50
+ readonly thinkingLevelMap: Readonly<Record<"minimal" | "low" | "medium" | "high", string | null>>;
51
+ readonly contextWindow: number;
52
+ readonly maxTokens: number;
53
+ };
54
+ readonly routes: Readonly<Partial<Record<StandardReasoningLevel, ConfiguredGenerationRoute>>>;
55
+ readonly replay: {
56
+ readonly kind: "same-public-model" | "strip";
57
+ };
58
+ readonly response: {
59
+ readonly kind: "gemini-envelope";
60
+ readonly family: "gemini" | "claude" | "gpt-oss";
61
+ };
62
+ }
63
+ declare const CATALOG: readonly [{
64
+ readonly publicId: "antigravity-gemini-3.8-flash";
65
+ readonly descriptor: {
66
+ readonly name: "Gemini 3.8 Flash (Antigravity, text only)";
67
+ readonly thinkingLevelMap: {
68
+ readonly minimal: null;
69
+ readonly low: "low";
70
+ readonly medium: "medium";
71
+ readonly high: "high";
72
+ };
73
+ readonly contextWindow: 1048576;
74
+ readonly maxTokens: 65536;
75
+ };
76
+ readonly routes: {
77
+ readonly off: {
78
+ readonly wireModel: "gemini-3.8-flash-tiered";
79
+ readonly thinking: {
80
+ readonly kind: "native-level";
81
+ readonly thinkingLevel: "low";
82
+ readonly includeThoughts: false;
83
+ };
84
+ readonly tools: ToolCapability;
85
+ };
86
+ readonly low: {
87
+ readonly wireModel: "gemini-3.8-flash-tiered";
88
+ readonly thinking: {
89
+ readonly kind: "native-level";
90
+ readonly thinkingLevel: "low";
91
+ readonly includeThoughts: true;
92
+ };
93
+ readonly tools: ToolCapability;
94
+ };
95
+ readonly medium: {
96
+ readonly wireModel: "gemini-3.8-flash-tiered";
97
+ readonly thinking: {
98
+ readonly kind: "native-level";
99
+ readonly thinkingLevel: "medium";
100
+ readonly includeThoughts: true;
101
+ };
102
+ readonly tools: ToolCapability;
103
+ };
104
+ readonly high: {
105
+ readonly wireModel: "gemini-3.8-flash-tiered";
106
+ readonly thinking: {
107
+ readonly kind: "native-level";
108
+ readonly thinkingLevel: "high";
109
+ readonly includeThoughts: true;
110
+ };
111
+ readonly tools: ToolCapability;
112
+ };
113
+ };
114
+ readonly replay: {
115
+ readonly kind: "same-public-model";
116
+ };
117
+ readonly response: {
118
+ readonly kind: "gemini-envelope";
119
+ readonly family: "gemini";
120
+ };
121
+ }, {
122
+ readonly publicId: "antigravity-gemini-3.7-flash";
123
+ readonly descriptor: {
124
+ readonly name: "Gemini 3.7 Flash (Antigravity, text only)";
125
+ readonly thinkingLevelMap: {
126
+ readonly minimal: null;
127
+ readonly low: "low";
128
+ readonly medium: "medium";
129
+ readonly high: "high";
130
+ };
131
+ readonly contextWindow: 1048576;
132
+ readonly maxTokens: 65536;
133
+ };
134
+ readonly routes: {
135
+ readonly off: {
136
+ readonly wireModel: "gemini-3.7-flash-low";
137
+ readonly thinking: {
138
+ readonly kind: "budget";
139
+ readonly budget: 0;
140
+ readonly includeThoughts: false;
141
+ };
142
+ readonly tools: ToolCapability;
143
+ };
144
+ readonly low: {
145
+ readonly wireModel: "gemini-3.7-flash-low";
146
+ readonly thinking: {
147
+ readonly kind: "budget";
148
+ readonly budget: 1000;
149
+ readonly includeThoughts: true;
150
+ };
151
+ readonly tools: ToolCapability;
152
+ };
153
+ readonly medium: {
154
+ readonly wireModel: "gemini-3.7-flash-medium";
155
+ readonly thinking: {
156
+ readonly kind: "budget";
157
+ readonly budget: 4000;
158
+ readonly includeThoughts: true;
159
+ };
160
+ readonly tools: ToolCapability;
161
+ };
162
+ readonly high: {
163
+ readonly wireModel: "gemini-3.7-flash-high";
164
+ readonly thinking: {
165
+ readonly kind: "budget";
166
+ readonly budget: -1;
167
+ readonly includeThoughts: true;
168
+ };
169
+ readonly tools: ToolCapability;
170
+ };
171
+ };
172
+ readonly replay: {
173
+ readonly kind: "strip";
174
+ };
175
+ readonly response: {
176
+ readonly kind: "gemini-envelope";
177
+ readonly family: "gemini";
178
+ };
179
+ }, {
180
+ readonly publicId: "antigravity-gemini-3.6-flash";
181
+ readonly descriptor: {
182
+ readonly name: "Gemini 3.6 Flash (Antigravity, text only)";
183
+ readonly thinkingLevelMap: {
184
+ readonly minimal: null;
185
+ readonly low: "low";
186
+ readonly medium: "medium";
187
+ readonly high: "high";
188
+ };
189
+ readonly contextWindow: 1048576;
190
+ readonly maxTokens: 65536;
191
+ };
192
+ readonly routes: {
193
+ readonly off: {
194
+ readonly wireModel: "gemini-3.6-flash-low";
195
+ readonly thinking: {
196
+ readonly kind: "omit";
197
+ };
198
+ readonly tools: ToolCapability;
199
+ };
200
+ readonly low: {
201
+ readonly wireModel: "gemini-3.6-flash-low";
202
+ readonly thinking: {
203
+ readonly kind: "budget";
204
+ readonly budget: 1000;
205
+ readonly includeThoughts: true;
206
+ };
207
+ readonly tools: ToolCapability;
208
+ };
209
+ readonly medium: {
210
+ readonly wireModel: "gemini-3.6-flash-medium";
211
+ readonly thinking: {
212
+ readonly kind: "budget";
213
+ readonly budget: 4000;
214
+ readonly includeThoughts: true;
215
+ };
216
+ readonly tools: ToolCapability;
217
+ };
218
+ readonly high: {
219
+ readonly wireModel: "gemini-3.6-flash-high";
220
+ readonly thinking: {
221
+ readonly kind: "budget";
222
+ readonly budget: -1;
223
+ readonly includeThoughts: true;
224
+ };
225
+ readonly tools: ToolCapability;
226
+ };
227
+ };
228
+ readonly replay: {
229
+ readonly kind: "strip";
230
+ };
231
+ readonly response: {
232
+ readonly kind: "gemini-envelope";
233
+ readonly family: "gemini";
234
+ };
235
+ }, {
236
+ readonly publicId: "antigravity-gemini-3.1-pro";
237
+ readonly descriptor: {
238
+ readonly name: "Gemini 3.1 Pro (Antigravity, text only)";
239
+ readonly thinkingLevelMap: {
240
+ readonly minimal: null;
241
+ readonly low: "low";
242
+ readonly medium: null;
243
+ readonly high: "high";
244
+ };
245
+ readonly contextWindow: 1048576;
246
+ readonly maxTokens: 65535;
247
+ };
248
+ readonly routes: {
249
+ readonly off: {
250
+ readonly wireModel: "gemini-3.1-pro-low";
251
+ readonly thinking: {
252
+ readonly kind: "omit";
253
+ };
254
+ readonly tools: ToolCapability;
255
+ };
256
+ readonly low: {
257
+ readonly wireModel: "gemini-3.1-pro-low";
258
+ readonly thinking: {
259
+ readonly kind: "budget";
260
+ readonly budget: 1001;
261
+ readonly includeThoughts: true;
262
+ };
263
+ readonly tools: ToolCapability;
264
+ };
265
+ readonly high: {
266
+ readonly wireModel: "gemini-pro-agent";
267
+ readonly thinking: {
268
+ readonly kind: "budget";
269
+ readonly budget: 10001;
270
+ readonly includeThoughts: true;
271
+ };
272
+ readonly tools: ToolCapability;
273
+ };
274
+ };
275
+ readonly replay: {
276
+ readonly kind: "strip";
277
+ };
278
+ readonly response: {
279
+ readonly kind: "gemini-envelope";
280
+ readonly family: "gemini";
281
+ };
282
+ }, {
283
+ readonly publicId: "antigravity-claude-sonnet-4.6";
284
+ readonly descriptor: {
285
+ readonly name: "Claude Sonnet 4.6 (Antigravity, text only)";
286
+ readonly thinkingLevelMap: {
287
+ readonly minimal: null;
288
+ readonly low: null;
289
+ readonly medium: null;
290
+ readonly high: "high";
291
+ };
292
+ readonly contextWindow: 250000;
293
+ readonly maxTokens: 64000;
294
+ };
295
+ readonly routes: {
296
+ readonly off: {
297
+ readonly wireModel: "claude-sonnet-4-6";
298
+ readonly thinking: {
299
+ readonly kind: "budget";
300
+ readonly budget: 0;
301
+ readonly includeThoughts: false;
302
+ };
303
+ readonly tools: ToolCapability;
304
+ };
305
+ readonly high: {
306
+ readonly wireModel: "claude-sonnet-4-6";
307
+ readonly thinking: {
308
+ readonly kind: "budget";
309
+ readonly budget: 1024;
310
+ readonly includeThoughts: true;
311
+ };
312
+ readonly tools: ToolCapability;
313
+ };
314
+ };
315
+ readonly replay: {
316
+ readonly kind: "strip";
317
+ };
318
+ readonly response: {
319
+ readonly kind: "gemini-envelope";
320
+ readonly family: "claude";
321
+ };
322
+ }, {
323
+ readonly publicId: "antigravity-claude-opus-4.6-thinking";
324
+ readonly descriptor: {
325
+ readonly name: "Claude Opus 4.6 Thinking (Antigravity, text only)";
326
+ readonly thinkingLevelMap: {
327
+ readonly minimal: null;
328
+ readonly low: null;
329
+ readonly medium: null;
330
+ readonly high: "high";
331
+ };
332
+ readonly contextWindow: 250000;
333
+ readonly maxTokens: 64000;
334
+ };
335
+ readonly routes: {
336
+ readonly off: {
337
+ readonly wireModel: "claude-opus-4-6-thinking";
338
+ readonly thinking: {
339
+ readonly kind: "budget";
340
+ readonly budget: 0;
341
+ readonly includeThoughts: false;
342
+ };
343
+ readonly tools: ToolCapability;
344
+ };
345
+ readonly high: {
346
+ readonly wireModel: "claude-opus-4-6-thinking";
347
+ readonly thinking: {
348
+ readonly kind: "budget";
349
+ readonly budget: 1024;
350
+ readonly includeThoughts: true;
351
+ };
352
+ readonly tools: ToolCapability;
353
+ };
354
+ };
355
+ readonly replay: {
356
+ readonly kind: "strip";
357
+ };
358
+ readonly response: {
359
+ readonly kind: "gemini-envelope";
360
+ readonly family: "claude";
361
+ };
362
+ }, {
363
+ readonly publicId: "antigravity-gpt-oss-120b";
364
+ readonly descriptor: {
365
+ readonly name: "GPT-OSS 120B (Antigravity, text only)";
366
+ readonly thinkingLevelMap: {
367
+ readonly minimal: null;
368
+ readonly low: null;
369
+ readonly medium: "medium";
370
+ readonly high: null;
371
+ };
372
+ readonly contextWindow: 131072;
373
+ readonly maxTokens: 32768;
374
+ };
375
+ readonly routes: {
376
+ readonly off: {
377
+ readonly wireModel: "gpt-oss-120b-medium";
378
+ readonly thinking: {
379
+ readonly kind: "omit";
380
+ };
381
+ readonly tools: ToolCapability;
382
+ };
383
+ readonly medium: {
384
+ readonly wireModel: "gpt-oss-120b-medium";
385
+ readonly thinking: {
386
+ readonly kind: "budget";
387
+ readonly budget: 8192;
388
+ readonly includeThoughts: true;
389
+ };
390
+ readonly tools: ToolCapability;
391
+ };
392
+ };
393
+ readonly replay: {
394
+ readonly kind: "strip";
395
+ };
396
+ readonly response: {
397
+ readonly kind: "gemini-envelope";
398
+ readonly family: "gpt-oss";
399
+ };
400
+ }];
401
+ type Catalog = typeof CATALOG;
402
+ export type AntigravityPublicModelId = Catalog[number]["publicId"];
403
+ export type AntigravityWireModelId = Catalog[number]["routes"][keyof Catalog[number]["routes"]]["wireModel"];
404
+ /** Constructs deterministic capability data for hermetic serializer tests only. */
405
+ export declare function createEnabledToolCapability(evidence: ToolEvidenceRef): Extract<ToolCapability, {
406
+ readonly state: "enabled";
407
+ }>;
408
+ export declare function defineCatalog<T extends readonly {
409
+ readonly publicId: string;
410
+ readonly descriptor?: CatalogEntry["descriptor"];
411
+ readonly routes: Readonly<Record<string, {
412
+ readonly wireModel: string;
413
+ readonly thinking?: GenerationRoute["thinking"];
414
+ }>>;
415
+ }[]>(entries: T): T;
416
+ export declare function listCatalogEntries(): readonly CatalogEntry[];
417
+ export declare function getCatalogEntry(publicId: unknown): CatalogEntry | undefined;
418
+ export declare function resolveGenerationRoute(entry: CatalogEntry, reasoning: unknown): GenerationRoute;
419
+ export interface GenerationSelection {
420
+ readonly level: StandardReasoningLevel;
421
+ readonly route: GenerationRoute;
422
+ readonly tools: ToolCapability;
423
+ }
424
+ export declare function resolveGenerationSelection(entry: CatalogEntry, reasoning: unknown): GenerationSelection;
425
+ export declare function resolveToolCapability(capability: ToolCapability, publicModelId: string, reasoning: StandardReasoningLevel, wireModel: string): ToolCapability;
426
+ export declare function toPiModelDescriptor(entry: CatalogEntry): {
427
+ id: string;
428
+ name: string;
429
+ reasoning: boolean;
430
+ thinkingLevelMap: {
431
+ high: string | null;
432
+ low: string | null;
433
+ medium: string | null;
434
+ minimal: string | null;
435
+ };
436
+ input: "text"[];
437
+ cost: {
438
+ input: number;
439
+ output: number;
440
+ cacheRead: number;
441
+ cacheWrite: number;
442
+ };
443
+ contextWindow: number;
444
+ maxTokens: number;
445
+ };
446
+ export {};