mixdog 0.9.166 → 0.9.167

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 (221) hide show
  1. package/package.json +1 -1
  2. package/scripts/audit-usage-ledger.mjs +86 -0
  3. package/scripts/generate-voice-runtime-manifest.mjs +22 -17
  4. package/scripts/memory-chunk-quality.mjs +128 -0
  5. package/scripts/memory-layer2-check.mjs +133 -0
  6. package/scripts/model-catalog-audit.mjs +6 -0
  7. package/scripts/native-tool-download.mjs +14 -0
  8. package/scripts/prepare-native-assets.mjs +2 -7
  9. package/scripts/tool-failures.mjs +7 -2
  10. package/scripts/verify-release-assets.mjs +48 -90
  11. package/src/defaults/skills/browser-use/SKILL.md +33 -18
  12. package/src/defaults/skills/computer-use/SKILL.md +16 -8
  13. package/src/lib/keychain-cjs.cjs +0 -1
  14. package/src/lib/rules-builder.cjs +4 -1
  15. package/src/rules/agent/40-cycle1-agent.md +21 -13
  16. package/src/rules/lead/01-general.md +8 -3
  17. package/src/rules/shared/10-tool-workflow.md +20 -11
  18. package/src/rules/shared/30-exploration.md +11 -4
  19. package/src/rules/shared/40-editing.md +2 -3
  20. package/src/rules/shared/50-execution.md +6 -3
  21. package/src/rules/shared/60-verification.md +3 -2
  22. package/src/rules/shared/70-delivery.md +0 -4
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +51 -45
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +3 -4
  25. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +44 -7
  26. package/src/runtime/agent/orchestrator/agent-trace.mjs +9 -0
  27. package/src/runtime/agent/orchestrator/config.mjs +9 -4
  28. package/src/runtime/agent/orchestrator/context/collect.mjs +25 -1055
  29. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +272 -0
  30. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +296 -0
  31. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +523 -0
  32. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +7 -2
  33. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +13 -14
  34. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +214 -0
  35. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +220 -116
  36. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +74 -44
  37. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +191 -29
  38. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +13 -12
  39. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +1 -9
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +5 -2
  41. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +48 -25
  42. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +28 -2
  43. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +3 -1
  44. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +1 -8
  45. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +32 -0
  46. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +21 -6
  47. package/src/runtime/agent/orchestrator/providers/lib/grok-tool-schema.mjs +61 -13
  48. package/src/runtime/agent/orchestrator/providers/model-catalog-projection.mjs +6 -1
  49. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +123 -118
  50. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +54 -0
  51. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +5 -2
  52. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +34 -3
  53. package/src/runtime/agent/orchestrator/providers/openai-codex-endpoints.mjs +21 -0
  54. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +154 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +2 -1
  56. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +322 -0
  57. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +243 -702
  58. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +2 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-startup-prewarm.mjs +221 -0
  60. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +3 -2
  61. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +19 -0
  63. package/src/runtime/agent/orchestrator/providers/provider-model-identities.mjs +40 -0
  64. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +120 -710
  65. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +36 -15
  66. package/src/runtime/agent/orchestrator/session/cache/util.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +17 -4
  68. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +36 -31
  69. package/src/runtime/agent/orchestrator/session/compact.mjs +4 -5
  70. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +6 -5
  71. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -6
  72. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +121 -0
  73. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -3
  74. package/src/runtime/agent/orchestrator/session/loop/diagnostics.mjs +74 -0
  75. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +44 -17
  76. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +266 -0
  77. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +111 -0
  78. package/src/runtime/agent/orchestrator/session/loop/request-projection.mjs +99 -0
  79. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +91 -0
  80. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +36 -0
  81. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +3 -3
  82. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  83. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +20 -11
  84. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +3 -5
  85. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +9 -3
  86. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +39 -0
  87. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +3 -2
  88. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +21 -3
  89. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -3
  91. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +25 -25
  92. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +62 -10
  93. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +17 -0
  94. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +61 -4
  95. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +13 -9
  96. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +12 -2
  97. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +3 -2
  98. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +8 -3
  99. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +69 -6
  100. package/src/runtime/agent/orchestrator/tools/builtin.mjs +14 -17
  101. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  102. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  104. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +1 -1
  105. package/src/runtime/bridge-discovery.mjs +8 -0
  106. package/src/runtime/browser-bridge/action-schema.mjs +37 -43
  107. package/src/runtime/browser-bridge/client.mjs +111 -99
  108. package/src/runtime/browser-bridge/input-fields.mjs +187 -0
  109. package/src/runtime/browser-bridge/tool-defs.mjs +12 -227
  110. package/src/runtime/computer-bridge/action-schema.mjs +2 -46
  111. package/src/runtime/computer-bridge/client.mjs +69 -77
  112. package/src/runtime/computer-bridge/core-actions.mjs +7 -5
  113. package/src/runtime/computer-bridge/error-recovery.mjs +41 -37
  114. package/src/runtime/computer-bridge/tool-defs.mjs +1 -1
  115. package/src/runtime/github/commands.mjs +4 -1
  116. package/src/runtime/github/contract.mjs +1 -1
  117. package/src/runtime/github/tool.mjs +2 -2
  118. package/src/runtime/media/adapters/antigravity-image.mjs +72 -0
  119. package/src/runtime/media/adapters/gemini-image.mjs +20 -11
  120. package/src/runtime/media/auth.mjs +12 -0
  121. package/src/runtime/media/catalog.mjs +30 -10
  122. package/src/runtime/media/jobs.mjs +4 -0
  123. package/src/runtime/media/lanes.mjs +40 -31
  124. package/src/runtime/memory/index.mjs +2 -9
  125. package/src/runtime/memory/lib/compact-handoff.mjs +26 -18
  126. package/src/runtime/memory/lib/memory-chunk-audit.mjs +41 -0
  127. package/src/runtime/memory/lib/memory-chunk-quality.mjs +388 -0
  128. package/src/runtime/memory/lib/memory-cycle1.mjs +95 -394
  129. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +29 -4
  130. package/src/runtime/memory/lib/memory-recall-store.mjs +8 -12
  131. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -11
  132. package/src/runtime/memory/lib/memory.mjs +2 -0
  133. package/src/runtime/memory/lib/query-handlers.mjs +98 -144
  134. package/src/runtime/memory/lib/query-ranking.mjs +23 -9
  135. package/src/runtime/memory/lib/recall-format.mjs +37 -27
  136. package/src/runtime/memory/lib/session-ingest-runtime.mjs +14 -8
  137. package/src/runtime/memory/lib/session-ingest.mjs +45 -84
  138. package/src/runtime/memory/lib/transcript-ingest.mjs +19 -21
  139. package/src/runtime/memory/tool-defs.mjs +2 -2
  140. package/src/runtime/office/authoring/pptx-author-session.mjs +3 -7
  141. package/src/runtime/office/core/office-actions-batch.mjs +2 -8
  142. package/src/runtime/office/core/office-actions-open.mjs +124 -0
  143. package/src/runtime/office/core/office-actions-read.mjs +127 -0
  144. package/src/runtime/office/core/office-core.mjs +80 -1
  145. package/src/runtime/office/core/office-sessions.mjs +116 -138
  146. package/src/runtime/office/index.mjs +18 -271
  147. package/src/runtime/office/pdf/pdf-analysis.mjs +2 -2
  148. package/src/runtime/office/pdf/pdf-limits.mjs +2 -0
  149. package/src/runtime/office/tool-defs.mjs +7 -6
  150. package/src/runtime/shared/agent-route-config.mjs +8 -8
  151. package/src/runtime/shared/child-spawn-gate.mjs +10 -13
  152. package/src/runtime/shared/config.mjs +2 -7
  153. package/src/runtime/shared/env.mjs +3 -3
  154. package/src/runtime/shared/err-text.mjs +1 -1
  155. package/src/runtime/shared/extension-scopes.mjs +3 -2
  156. package/src/runtime/shared/heap-cap.mjs +10 -6
  157. package/src/runtime/shared/llm/cost.mjs +35 -10
  158. package/src/runtime/shared/llm/usage-accounting.mjs +11 -1
  159. package/src/runtime/shared/llm/usage-context.mjs +6 -0
  160. package/src/runtime/shared/llm/usage-ledger-import.mjs +5 -0
  161. package/src/runtime/shared/llm/usage-ledger-repair.mjs +109 -0
  162. package/src/runtime/shared/llm/usage-ledger.mjs +59 -20
  163. package/src/runtime/shared/llm/usage-pricing-refresh.mjs +26 -0
  164. package/src/runtime/shared/llm/usage-rollup.mjs +17 -15
  165. package/src/runtime/shared/native-asset.mjs +3 -4
  166. package/src/runtime/shared/object.mjs +4 -0
  167. package/src/runtime/shared/pg-schema-db.mjs +21 -0
  168. package/src/runtime/shared/plugin-metadata.mjs +3 -1
  169. package/src/runtime/shared/resource-admission.mjs +1 -6
  170. package/src/runtime/shared/schedules-db.mjs +8 -24
  171. package/src/runtime/shared/schema-value-error.d.mts +2 -0
  172. package/src/runtime/shared/schema-value-error.mjs +68 -0
  173. package/src/runtime/shared/singleton-owner.mjs +11 -24
  174. package/src/runtime/shared/staged-update.mjs +1 -10
  175. package/src/runtime/shared/tool-card-model.mjs +8 -5
  176. package/src/runtime/shared/tool-execution-contract.mjs +1 -1
  177. package/src/runtime/shared/tool-surface.mjs +1 -5
  178. package/src/runtime/shared/user-data-guard.mjs +1 -4
  179. package/src/runtime/shared/webhooks-db.mjs +8 -24
  180. package/src/runtime/web-search/index.mjs +32 -8
  181. package/src/runtime/web-search/tool-defs.mjs +4 -4
  182. package/src/session-runtime/config-lifecycle.mjs +34 -0
  183. package/src/session-runtime/context-status.mjs +19 -0
  184. package/src/session-runtime/cwd-plugins.mjs +12 -29
  185. package/src/session-runtime/goal-tasks.mjs +2 -2
  186. package/src/session-runtime/goal-tool-defs.mjs +3 -2
  187. package/src/session-runtime/internal-tool-executor.mjs +7 -0
  188. package/src/session-runtime/lifecycle-api.mjs +5 -11
  189. package/src/session-runtime/notification-bus.mjs +41 -0
  190. package/src/session-runtime/prewarm.mjs +22 -0
  191. package/src/session-runtime/runtime-bootstrap.mjs +90 -0
  192. package/src/session-runtime/runtime-core.mjs +88 -202
  193. package/src/session-runtime/runtime-feature-gates.mjs +37 -0
  194. package/src/session-runtime/session-lifecycle.mjs +5 -5
  195. package/src/session-runtime/session-turn-api.mjs +1 -12
  196. package/src/session-runtime/setup-tool/executor.mjs +13 -5
  197. package/src/session-runtime/setup-tool/tool-defs.mjs +52 -46
  198. package/src/session-runtime/tool-defs.mjs +73 -4
  199. package/src/session-runtime/usage-stats-api.mjs +4 -1
  200. package/src/session-runtime/warmup-schedulers.mjs +8 -2
  201. package/src/session-runtime/workflow.mjs +14 -0
  202. package/src/standalone/channel-session-router.mjs +3 -1
  203. package/src/standalone/channel-worker.mjs +18 -9
  204. package/src/standalone/daemon-crash-capture.mjs +534 -0
  205. package/src/standalone/daemon-telemetry.mjs +175 -0
  206. package/src/standalone/daemon.mjs +31 -21
  207. package/src/standalone/session-client.mjs +31 -23
  208. package/src/standalone/usage-dashboard-model.mjs +2 -0
  209. package/src/standalone/usage-stats-hours.mjs +18 -11
  210. package/src/standalone/usage-stats-model.mjs +39 -28
  211. package/src/standalone/usage-stats-period.mjs +43 -45
  212. package/src/tui/app/use-transcript-window.mjs +1 -1
  213. package/src/tui/components/StatusLine.jsx +13 -42
  214. package/src/tui/dist/index.mjs +256 -239
  215. package/src/tui/session/session-api-ext.mjs +44 -41
  216. package/src/tui/session/session-api.mjs +4 -0
  217. package/src/tui/session/tool-card-results.mjs +25 -78
  218. package/src/tui/session/tool-result-status.mjs +94 -1
  219. package/src/tui/session/turn-aggregate-cards.mjs +17 -54
  220. package/src/ui/statusline-format.mjs +6 -26
  221. package/src/workflows/default/WORKFLOW.md +5 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Antigravity model catalog and quota.
3
+ *
4
+ * Cloud Code Assist publishes the account's models through
5
+ * `fetchAvailableModels`: one wire id per thinking tier ("gemini-3.8-flash-high",
6
+ * "-medium", "-low") labelled "Gemini 3.8 Flash (High)", plus per-model quota.
7
+ * Mixdog's picker shows one model with an effort control, so the tiers of a
8
+ * family collapse into one record whose `wire` map turns the chosen effort
9
+ * back into the wire id. The list is cached on disk like the other OAuth
10
+ * catalogs; the curated list in the tokens module is the offline fallback.
11
+ */
12
+ import { makeModelCache } from './model-cache.mjs';
13
+ import {
14
+ ANTIGRAVITY_MODELS,
15
+ PROJECT_ENDPOINT,
16
+ antigravityHeaders,
17
+ _scrubTokens,
18
+ } from './antigravity-oauth-tokens.mjs';
19
+
20
+ export const ANTIGRAVITY_MODEL_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
21
+ export const ANTIGRAVITY_MODEL_CACHE_VERSION = 1;
22
+ const FETCH_MODELS_TIMEOUT_MS = 15_000;
23
+ // Tier labels the gateway puts in parentheses, in effort order.
24
+ const TIER_EFFORTS = { 'extra low': 'minimal', minimal: 'minimal', low: 'low', medium: 'medium', high: 'high' };
25
+ const EFFORT_ORDER = ['minimal', 'low', 'medium', 'high'];
26
+ // IDE-internal completion/chat models are listed without a display name.
27
+ const INTERNAL_ID = /^(?:chat|tab)_/;
28
+ // Bare Gemini 3 ids take the ordinary thinkingLevel field instead of a tier id.
29
+ const BARE_GEMINI3_LEVELS = Object.freeze(['low', 'medium', 'high']);
30
+
31
+ let _mirror = null;
32
+ export const antigravityModelCache = makeModelCache({
33
+ fileName: 'antigravity-oauth-models.json',
34
+ ttlMs: ANTIGRAVITY_MODEL_CACHE_TTL_MS,
35
+ version: ANTIGRAVITY_MODEL_CACHE_VERSION,
36
+ onSave: (models) => { _mirror = models; },
37
+ });
38
+
39
+ export async function fetchAvailableModels({ accessToken, projectId, fetchFn = fetch, signal = null }) {
40
+ const timeout = AbortSignal.timeout(FETCH_MODELS_TIMEOUT_MS);
41
+ const res = await fetchFn(`${PROJECT_ENDPOINT}/v1internal:fetchAvailableModels`, {
42
+ method: 'POST',
43
+ headers: {
44
+ Authorization: `Bearer ${accessToken}`,
45
+ 'Content-Type': 'application/json',
46
+ ...antigravityHeaders(),
47
+ },
48
+ body: JSON.stringify(projectId ? { project: projectId } : {}),
49
+ redirect: 'error',
50
+ signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
51
+ });
52
+ if (!res.ok) {
53
+ const text = await res.text().catch(() => '');
54
+ throw new Error(`[antigravity-oauth] fetchAvailableModels failed: ${res.status} ${_scrubTokens(text).slice(0, 300)}`);
55
+ }
56
+ const json = await res.json();
57
+ const models = json?.models;
58
+ if (!models || typeof models !== 'object' || Array.isArray(models)) {
59
+ throw new Error('[antigravity-oauth] fetchAvailableModels returned no models');
60
+ }
61
+ return models;
62
+ }
63
+
64
+ function splitDisplay(displayName) {
65
+ const text = String(displayName || '').trim();
66
+ const match = text.match(/^(.*?)\s*\(([^()]+)\)\s*$/);
67
+ const effort = match ? TIER_EFFORTS[match[2].trim().toLowerCase()] : undefined;
68
+ return effort ? { base: match[1].trim(), effort } : { base: text, effort: null };
69
+ }
70
+
71
+ function familyId(base) {
72
+ return base.toLowerCase().replace(/[^a-z0-9.]+/g, '-').replace(/^-+|-+$/g, '');
73
+ }
74
+
75
+ function familyKind(base) {
76
+ const text = base.toLowerCase();
77
+ if (/claude/.test(text)) return null;
78
+ if (/gemini/.test(text)) return /flash/.test(text) ? 'gemini-flash' : 'gemini-pro';
79
+ if (/gpt/.test(text)) return 'gpt-oss';
80
+ return null;
81
+ }
82
+
83
+ // Several wire ids can share one label ("Gemini 3.5 Flash Lite" is served by
84
+ // four ids): keep the one whose id carries the labelled version, then the
85
+ // shortest, so the choice is stable across responses.
86
+ function pickWire(candidates, base) {
87
+ const version = base.match(/\d+(?:\.\d+)?/)?.[0];
88
+ const rank = (id) => (version && id.includes(version) ? 0 : 1);
89
+ return [...candidates].sort((a, b) => rank(a) - rank(b) || a.length - b.length || a.localeCompare(b))[0];
90
+ }
91
+
92
+ function chatEntries(rawModels) {
93
+ const out = [];
94
+ for (const [wireId, entry] of Object.entries(rawModels || {})) {
95
+ if (!entry || typeof entry !== 'object' || INTERNAL_ID.test(wireId)) continue;
96
+ const displayName = String(entry.displayName || '').trim();
97
+ const contextWindow = Number(entry.maxTokens) || 0;
98
+ if (!displayName || contextWindow <= 0) continue;
99
+ out.push({ wireId, entry, displayName, contextWindow });
100
+ }
101
+ return out;
102
+ }
103
+
104
+ /** Collapse the gateway's per-tier wire ids into picker records. */
105
+ export function normalizeAntigravityCatalog(rawModels) {
106
+ const families = new Map();
107
+ for (const { wireId, entry, displayName, contextWindow } of chatEntries(rawModels)) {
108
+ const { base, effort } = splitDisplay(displayName);
109
+ const key = familyId(base);
110
+ let family = families.get(key);
111
+ if (!family) {
112
+ family = { base, contextWindow: 0, supportsVision: false, supportsReasoning: false, wires: new Map() };
113
+ families.set(key, family);
114
+ }
115
+ family.contextWindow = Math.max(family.contextWindow, contextWindow);
116
+ family.supportsVision ||= entry.supportsImages === true;
117
+ family.supportsReasoning ||= entry.supportsThinking === true;
118
+ const slot = effort || '';
119
+ if (!family.wires.has(slot)) family.wires.set(slot, []);
120
+ family.wires.get(slot).push(wireId);
121
+ }
122
+ const models = [];
123
+ for (const [key, family] of families) {
124
+ const efforts = EFFORT_ORDER.filter((effort) => family.wires.has(effort));
125
+ const tiered = efforts.length > 1;
126
+ const wire = tiered
127
+ ? Object.fromEntries(efforts.map((effort) => [effort, pickWire(family.wires.get(effort), family.base)]))
128
+ : pickWire(family.wires.get(efforts[0] ?? ''), family.base);
129
+ const id = tiered ? key : wire;
130
+ const bareGemini3 = !tiered && /^gemini-3(?:\.\d+)?-(?:flash|pro)$/.test(wire);
131
+ const display = tiered || !efforts.length ? family.base : `${family.base} (${efforts[0][0].toUpperCase()}${efforts[0].slice(1)})`;
132
+ const kind = familyKind(family.base);
133
+ models.push({
134
+ id,
135
+ name: display,
136
+ display,
137
+ provider: 'antigravity-oauth',
138
+ ...(kind ? { family: kind } : {}),
139
+ contextWindow: family.contextWindow,
140
+ supportsVision: family.supportsVision,
141
+ supportsReasoning: family.supportsReasoning,
142
+ supportsFunctionCalling: true,
143
+ reasoningLevels: tiered ? efforts : (bareGemini3 ? [...BARE_GEMINI3_LEVELS] : []),
144
+ wire,
145
+ });
146
+ }
147
+ return models.sort((a, b) => a.display.localeCompare(b.display));
148
+ }
149
+
150
+ /** Catalog to resolve wire ids against: in-memory mirror, disk cache, then the curated fallback. */
151
+ export function antigravityCatalogModels() {
152
+ if (!_mirror) _mirror = antigravityModelCache.loadSync();
153
+ return _mirror || ANTIGRAVITY_MODELS;
154
+ }
155
+
156
+ /**
157
+ * Turn a picker model + effort into the wire id the gateway accepts. Tiered
158
+ * families consume the effort (the id encodes it); a bare Gemini 3 id keeps it
159
+ * for thinkingLevel; every other record drops it because the model has no
160
+ * effort surface. Unknown ids pass through unchanged.
161
+ */
162
+ export function resolveAntigravityWireModel(model, effort, models = antigravityCatalogModels()) {
163
+ const id = String(model || '');
164
+ const record = models.find((entry) => entry?.id === id);
165
+ if (!record) return { model: id, effort };
166
+ if (record.wire && typeof record.wire === 'object') {
167
+ const levels = Object.keys(record.wire);
168
+ const wanted = String(effort || '').toLowerCase();
169
+ const level = levels.includes(wanted) ? wanted : (levels.includes('high') ? 'high' : levels[levels.length - 1]);
170
+ return { model: record.wire[level], effort: null };
171
+ }
172
+ const wire = typeof record.wire === 'string' && record.wire ? record.wire : id;
173
+ return { model: wire, effort: record.reasoningLevels?.length ? effort : null };
174
+ }
175
+
176
+ // Sidebar meter labels fit about four characters (5H, 7D, API ...).
177
+ function quotaGroupLabel(wireId, displayName) {
178
+ const text = `${wireId} ${displayName}`.toLowerCase();
179
+ return /flash/.test(text) ? 'FLASH' : 'PRO';
180
+ }
181
+
182
+ /** Per-family quota windows from the same response, in the OAuth usage shape. */
183
+ export function antigravityQuotaWindows(rawModels) {
184
+ const groups = new Map();
185
+ for (const { wireId, entry, displayName } of chatEntries(rawModels)) {
186
+ const text = `${wireId} ${displayName}`.toLowerCase();
187
+ // Antigravity is the Gemini provider: omit non-Gemini (Claude, GPT) endpoints.
188
+ if (/claude|gpt/.test(text)) continue;
189
+ const info = entry.quotaInfo;
190
+ if (!info || typeof info !== 'object') continue;
191
+ const remaining = Number(info.remainingFraction);
192
+ const resetAt = Date.parse(String(info.resetTime || '')) || 0;
193
+ if (!Number.isFinite(remaining) && !resetAt) continue;
194
+ // A counter that reports only a reset time is exhausted, not unknown.
195
+ const usedPct = Number.isFinite(remaining) ? Math.max(0, Math.min(100, (1 - remaining) * 100)) : 100;
196
+ const label = quotaGroupLabel(wireId, displayName);
197
+ const group = groups.get(label) || { label, usedPct: 0, resetAt: 0 };
198
+ group.usedPct = Math.max(group.usedPct, usedPct);
199
+ group.resetAt = Math.max(group.resetAt, resetAt);
200
+ groups.set(label, group);
201
+ }
202
+ const order = ['FLASH', 'PRO'];
203
+ return order
204
+ .filter((label) => groups.has(label))
205
+ .map((label) => {
206
+ const group = groups.get(label);
207
+ return {
208
+ label: group.label,
209
+ usedPct: Math.round(group.usedPct * 100) / 100,
210
+ ...(group.resetAt ? { resetAt: group.resetAt } : {}),
211
+ source: 'antigravity-models',
212
+ };
213
+ });
214
+ }