@oh-my-pi/pi-catalog 17.3.0 → 17.3.2

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.
@@ -265,22 +265,32 @@ function geminiFlashFamily(mode: "budget" | "google-level"): EffortVariantFamily
265
265
  };
266
266
  }
267
267
 
268
- const GEMINI_36_FLASH_FAMILY: EffortVariantFamily = {
269
- id: "gemini-3.6-flash",
270
- name: "Gemini 3.6 Flash",
271
- members: ["gemini-3.6-flash-low", "gemini-3.6-flash-medium", "gemini-3.6-flash-high", "gemini-3.6-flash-tiered"],
272
- routing: {
273
- [Effort.Minimal]: "gemini-3.6-flash-low",
274
- [Effort.Low]: "gemini-3.6-flash-low",
275
- [Effort.Medium]: "gemini-3.6-flash-medium",
276
- [Effort.High]: "gemini-3.6-flash-high",
277
- },
278
- thinking: {
279
- mode: "google-level",
280
- efforts: GEMINI_3_FLASH_FAMILY_EFFORTS,
281
- requiresEffort: true,
282
- },
283
- };
268
+ /**
269
+ * Gemini 3.6+ Flash exposes one mandatory-reasoning wire id per thinking
270
+ * level. Some generations retain additional discovery-only aliases.
271
+ */
272
+ function geminiLevelFlashFamily(version: "3.6" | "3.7", ...additionalMembers: string[]): EffortVariantFamily {
273
+ const id = `gemini-${version}-flash`;
274
+ return {
275
+ id,
276
+ name: `Gemini ${version} Flash`,
277
+ members: [`${id}-low`, `${id}-medium`, `${id}-high`, ...additionalMembers],
278
+ routing: {
279
+ [Effort.Minimal]: `${id}-low`,
280
+ [Effort.Low]: `${id}-low`,
281
+ [Effort.Medium]: `${id}-medium`,
282
+ [Effort.High]: `${id}-high`,
283
+ },
284
+ thinking: {
285
+ mode: "google-level",
286
+ efforts: GEMINI_3_FLASH_FAMILY_EFFORTS,
287
+ requiresEffort: true,
288
+ },
289
+ };
290
+ }
291
+
292
+ const GEMINI_36_FLASH_FAMILY = geminiLevelFlashFamily("3.6", "gemini-3.6-flash-tiered");
293
+ const GEMINI_37_FLASH_FAMILY = geminiLevelFlashFamily("3.7");
284
294
 
285
295
  function geminiProFamily(mode: "budget" | "google-level"): EffortVariantFamily {
286
296
  const budget = mode === "budget";
@@ -364,13 +374,20 @@ const SHARED_CCA_FAMILIES: readonly EffortVariantFamily[] = [
364
374
 
365
375
  /** `google-antigravity` Gemini families, using each generation's native transport. */
366
376
  export const ANTIGRAVITY_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
367
- families: [GEMINI_36_FLASH_FAMILY, geminiFlashFamily("budget"), geminiProFamily("budget"), ...SHARED_CCA_FAMILIES],
377
+ families: [
378
+ GEMINI_36_FLASH_FAMILY,
379
+ GEMINI_37_FLASH_FAMILY,
380
+ geminiFlashFamily("budget"),
381
+ geminiProFamily("budget"),
382
+ ...SHARED_CCA_FAMILIES,
383
+ ],
368
384
  };
369
385
 
370
386
  /** `google-gemini-cli` Gemini families on the official CLI's level transport. */
371
387
  export const GEMINI_CLI_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
372
388
  families: [
373
389
  GEMINI_36_FLASH_FAMILY,
390
+ GEMINI_37_FLASH_FAMILY,
374
391
  geminiFlashFamily("google-level"),
375
392
  geminiProFamily("google-level"),
376
393
  ...SHARED_CCA_FAMILIES,
@@ -1,3 +1,5 @@
1
+ import type { FetchImpl } from "@oh-my-pi/pi-utils";
2
+
1
3
  /**
2
4
  * Build a User-Agent string that identifies as Gemini CLI to unlock higher rate limits.
3
5
  * Uses the same format as the official Gemini CLI (v0.35+):
@@ -15,30 +17,89 @@ export const getGeminiCliHeaders = (modelId?: string) => ({
15
17
  "Client-Metadata": "ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI",
16
18
  });
17
19
 
18
- export const ANTIGRAVITY_SYSTEM_INSTRUCTION =
19
- "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding." +
20
- "You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question." +
21
- "**Absolute paths only**" +
22
- "**Proactiveness**";
23
20
  /**
24
21
  * Antigravity / Cloud Code Assist user agent. Lives in its own file so discovery
25
22
  * and usage code can read it without pulling the heavy google-gemini-cli provider
26
23
  * (and its @google/genai → google-auth-library dependency chain) into the startup
27
24
  * parse graph.
25
+ *
26
+ * Format captured from the real 2.8.0 `antigravity/hub` client:
27
+ * `antigravity/hub/2.8.0 (aidev_client; os_type=darwin; arch=arm64; cl=963137146)`.
28
+ * The backend gates newer models (e.g. gemini-3.7-flash) on the client version,
29
+ * so the version tracks the latest Antigravity release via the update manifest
30
+ * (see {@link ensureAntigravityVersion}) with `DEFAULT_ANTIGRAVITY_VERSION` as
31
+ * the offline fallback. os_type/arch are pinned to the darwin/arm64 reference
32
+ * client the version and manifest are captured from, independent of the host
33
+ * platform. Overrides: PI_AI_ANTIGRAVITY_VERSION / _CL / _OS / _ARCH.
28
34
  */
29
- export let getAntigravityUserAgent = () => {
30
- const DEFAULT_ANTIGRAVITY_VERSION = "2.1.4";
31
- const version = process.env.PI_AI_ANTIGRAVITY_VERSION || DEFAULT_ANTIGRAVITY_VERSION;
32
- // Map Node.js platform/arch to Antigravity's expected format.
33
- // Verified against Antigravity source: _qn() and wqn() in main.js.
34
- // process.platform: win32→windows, others pass through (darwin, linux)
35
- // process.arch: x64→amd64, ia32→386, others pass through (arm64)
36
- const os = process.platform === "win32" ? "windows" : process.platform;
37
- const arch = process.arch === "x64" ? "amd64" : process.arch === "ia32" ? "386" : process.arch;
38
- const userAgent = `antigravity/hub/${version} ${os}/${arch}`;
39
- getAntigravityUserAgent = () => userAgent;
40
- return userAgent;
41
- };
35
+ export const DEFAULT_ANTIGRAVITY_VERSION = "2.8.0";
36
+
37
+ const ANTIGRAVITY_VERSION_MANIFEST_URL =
38
+ "https://antigravity-hub-auto-updater-974169037036.us-central1.run.app/manifest/latest-arm64-mac.yml";
39
+ const ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS = 5_000;
40
+
41
+ let discoveredAntigravityVersion: string | null = null;
42
+ let antigravityVersionFetch: Promise<void> | null = null;
43
+
44
+ /** Current Antigravity client version: env override → manifest-discovered → pinned fallback. */
45
+ export function getAntigravityVersion(): string {
46
+ return process.env.PI_AI_ANTIGRAVITY_VERSION || discoveredAntigravityVersion || DEFAULT_ANTIGRAVITY_VERSION;
47
+ }
48
+
49
+ /**
50
+ * Extracts the client version from an electron-builder update manifest.
51
+ * Returns null when no well-formed `version:` line is present.
52
+ */
53
+ export function parseAntigravityManifestVersion(yamlText: string): string | null {
54
+ for (const line of yamlText.split(/\r?\n/)) {
55
+ const match = /^\s*version\s*:\s*(?:"([^"]*)"|'([^']*)'|([^\s#]+))\s*(?:#.*)?$/.exec(line);
56
+ if (!match) continue;
57
+ const version = (match[1] ?? match[2] ?? match[3] ?? "").trim();
58
+ return /^\d+\.\d+\.\d+$/.test(version) ? version : null;
59
+ }
60
+ return null;
61
+ }
62
+
63
+ /**
64
+ * Resolves the latest Antigravity release from the official update manifest.
65
+ * Success is cached for the process lifetime; failures are silent (the pinned
66
+ * fallback stays valid) and clear the in-flight cache so a later call retries.
67
+ * Skipped entirely when PI_AI_ANTIGRAVITY_VERSION is set.
68
+ */
69
+ export function ensureAntigravityVersion(fetcher: FetchImpl = fetch, signal?: AbortSignal): Promise<void> {
70
+ if (process.env.PI_AI_ANTIGRAVITY_VERSION || discoveredAntigravityVersion) return Promise.resolve();
71
+ if (antigravityVersionFetch) return antigravityVersionFetch;
72
+
73
+ antigravityVersionFetch = (async () => {
74
+ try {
75
+ const timeoutSignal = AbortSignal.timeout(ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS);
76
+ const response = await fetcher(ANTIGRAVITY_VERSION_MANIFEST_URL, {
77
+ headers: { "Cache-Control": "no-cache", "User-Agent": "electron-builder" },
78
+ signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal,
79
+ });
80
+ if (response.ok) {
81
+ discoveredAntigravityVersion = parseAntigravityManifestVersion(await response.text());
82
+ }
83
+ } catch {
84
+ // Silent: the pinned fallback remains valid when version discovery fails.
85
+ } finally {
86
+ if (!discoveredAntigravityVersion) antigravityVersionFetch = null;
87
+ }
88
+ })();
89
+ return antigravityVersionFetch;
90
+ }
91
+
92
+ /** Antigravity `User-Agent` header value; rebuilt when the discovered version changes. */
93
+ export function getAntigravityUserAgent(): string {
94
+ const version = getAntigravityVersion();
95
+ // The backend does not validate `cl` (verified live: stale, zero, and absent
96
+ // cl all pass model gating on daily-cloudcode-pa; only the version gates).
97
+ // The update manifest carries no changelist, so the captured value stays.
98
+ const cl = process.env.PI_AI_ANTIGRAVITY_CL || "963137146";
99
+ const os = process.env.PI_AI_ANTIGRAVITY_OS || "darwin";
100
+ const arch = process.env.PI_AI_ANTIGRAVITY_ARCH || "arm64";
101
+ return `antigravity/hub/${version} (aidev_client; os_type=${os}; arch=${arch}; cl=${cl})`;
102
+ }
42
103
 
43
104
  /**
44
105
  * Per-wire-id Antigravity Cloud Code Assist request constants, captured from the