@cortexkit/opencode-antigravity-auth 3.0.1 → 3.0.3

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 (149) hide show
  1. package/dist/cli.js.map +2 -2
  2. package/dist/cli.meta.json +5 -5
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +2877 -2851
  5. package/dist/index.js.map +4 -4
  6. package/dist/index.meta.json +120 -33
  7. package/dist/server.js +475 -427
  8. package/dist/server.js.map +4 -4
  9. package/dist/server.meta.json +1 -7313
  10. package/dist/src/cli.d.ts +1 -1
  11. package/dist/src/constants.d.ts +1 -1
  12. package/dist/src/ga/rpc/protocol.d.ts +1 -1
  13. package/dist/src/ga/server/index.d.ts +6 -6
  14. package/dist/src/ga/server/index.d.ts.map +1 -1
  15. package/dist/src/ga/server/index.js +29 -1
  16. package/dist/src/ga/server/index.js.map +1 -1
  17. package/dist/src/ga/tui/host-ga.d.ts +2 -2
  18. package/dist/src/hooks/auto-update-checker/checker.d.ts +1 -1
  19. package/dist/src/hooks/auto-update-checker/index.d.ts +4 -4
  20. package/dist/src/plugin/account-access.d.ts +6 -6
  21. package/dist/src/plugin/account-command-oauth.d.ts +2 -2
  22. package/dist/src/plugin/accounts.d.ts +3 -3
  23. package/dist/src/plugin/auth-doctor.d.ts +2 -2
  24. package/dist/src/plugin/auth-drift.d.ts +2 -2
  25. package/dist/src/plugin/auth-loader.d.ts +8 -8
  26. package/dist/src/plugin/auth-loader.d.ts.map +1 -1
  27. package/dist/src/plugin/auth-loader.js +1 -0
  28. package/dist/src/plugin/auth-loader.js.map +1 -1
  29. package/dist/src/plugin/background-quota-refresh.d.ts +3 -3
  30. package/dist/src/plugin/background-vault-quota-refresh.d.ts +43 -0
  31. package/dist/src/plugin/background-vault-quota-refresh.d.ts.map +1 -0
  32. package/dist/src/plugin/background-vault-quota-refresh.js +155 -0
  33. package/dist/src/plugin/background-vault-quota-refresh.js.map +1 -0
  34. package/dist/src/plugin/cache/index.d.ts +1 -1
  35. package/dist/src/plugin/cache/signature-cache.d.ts +2 -2
  36. package/dist/src/plugin/cache.d.ts +6 -6
  37. package/dist/src/plugin/cli.d.ts +6 -6
  38. package/dist/src/plugin/command-apply.d.ts +1 -1
  39. package/dist/src/plugin/command-data.d.ts +2 -246
  40. package/dist/src/plugin/command-data.d.ts.map +1 -1
  41. package/dist/src/plugin/command-data.js +4 -418
  42. package/dist/src/plugin/command-data.js.map +1 -1
  43. package/dist/src/plugin/commands.d.ts +4 -4
  44. package/dist/src/plugin/config/index.d.ts +2 -2
  45. package/dist/src/plugin/config/loader.d.ts +2 -2
  46. package/dist/src/plugin/config/models.d.ts +2 -2
  47. package/dist/src/plugin/config/writer.d.ts +2 -2
  48. package/dist/src/plugin/core/streaming/index.d.ts +2 -2
  49. package/dist/src/plugin/core/streaming/transformer.d.ts +1 -1
  50. package/dist/src/plugin/debug.d.ts +1 -1
  51. package/dist/src/plugin/dependencies.d.ts +3 -3
  52. package/dist/src/plugin/event-handler.d.ts +3 -3
  53. package/dist/src/plugin/fetch-interceptor.d.ts +10 -10
  54. package/dist/src/plugin/fetch-routing.d.ts +3 -3
  55. package/dist/src/plugin/ga-location-services.d.ts +10 -10
  56. package/dist/src/plugin/gemini-dump.d.ts +0 -22
  57. package/dist/src/plugin/gemini-dump.d.ts.map +1 -1
  58. package/dist/src/plugin/gemini-dump.js +0 -39
  59. package/dist/src/plugin/gemini-dump.js.map +1 -1
  60. package/dist/src/plugin/google-search-tool.d.ts +1 -1
  61. package/dist/src/plugin/index.d.ts +8 -6
  62. package/dist/src/plugin/index.d.ts.map +1 -1
  63. package/dist/src/plugin/index.js +41 -18
  64. package/dist/src/plugin/index.js.map +1 -1
  65. package/dist/src/plugin/killswitch.d.ts +1 -1
  66. package/dist/src/plugin/lifecycle.d.ts +2 -2
  67. package/dist/src/plugin/logger.d.ts +2 -2
  68. package/dist/src/plugin/oauth-login.d.ts +1 -1
  69. package/dist/src/plugin/oauth-methods.d.ts +9 -9
  70. package/dist/src/plugin/operator-settings.d.ts +3 -3
  71. package/dist/src/plugin/persist-account-pool.d.ts +1 -1
  72. package/dist/src/plugin/quota.d.ts +5 -4
  73. package/dist/src/plugin/quota.d.ts.map +1 -1
  74. package/dist/src/plugin/quota.js +1 -0
  75. package/dist/src/plugin/quota.js.map +1 -1
  76. package/dist/src/plugin/recovery/index.d.ts +3 -3
  77. package/dist/src/plugin/recovery/storage.d.ts +1 -1
  78. package/dist/src/plugin/recovery.d.ts +3 -3
  79. package/dist/src/plugin/refresh-queue.d.ts +3 -3
  80. package/dist/src/plugin/request-helpers.d.ts +1 -1
  81. package/dist/src/plugin/request-helpers.d.ts.map +1 -1
  82. package/dist/src/plugin/request-helpers.js +10 -417
  83. package/dist/src/plugin/request-helpers.js.map +1 -1
  84. package/dist/src/plugin/request.d.ts +9 -9
  85. package/dist/src/plugin/request.js +4 -4
  86. package/dist/src/plugin/session-context.d.ts +1 -1
  87. package/dist/src/plugin/shared/request-services.d.ts +9 -9
  88. package/dist/src/plugin/shared/runtime.d.ts +11 -11
  89. package/dist/src/plugin/shared/source-sidebar.d.ts +1 -1
  90. package/dist/src/plugin/shared/vault-menu.d.ts +1 -1
  91. package/dist/src/plugin/shared/vault-request-credentials.d.ts +3 -1
  92. package/dist/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
  93. package/dist/src/plugin/shared/vault-request-credentials.js +1 -1
  94. package/dist/src/plugin/shared/vault-request-credentials.js.map +1 -1
  95. package/dist/src/plugin/stores/signature-store.d.ts +1 -1
  96. package/dist/src/plugin/token.d.ts +1 -1
  97. package/dist/src/plugin/ui/auth-menu.d.ts +4 -4
  98. package/dist/src/plugin/ui/model-status.d.ts +3 -3
  99. package/dist/src/plugin/ui/quota-status.d.ts +2 -2
  100. package/dist/src/plugin/vault-activation.d.ts +1 -1
  101. package/dist/src/plugin/vault-quota-refresh.d.ts +7 -0
  102. package/dist/src/plugin/vault-quota-refresh.d.ts.map +1 -0
  103. package/dist/src/plugin/vault-quota-refresh.js +12 -0
  104. package/dist/src/plugin/vault-quota-refresh.js.map +1 -0
  105. package/dist/src/plugin/vault-sidebar-projection.d.ts +27 -0
  106. package/dist/src/plugin/vault-sidebar-projection.d.ts.map +1 -0
  107. package/dist/src/plugin/vault-sidebar-projection.js +34 -0
  108. package/dist/src/plugin/vault-sidebar-projection.js.map +1 -0
  109. package/dist/src/rpc/notifications.d.ts +1 -1
  110. package/dist/src/rpc/rpc-server.d.ts +1 -1
  111. package/dist/src/server.d.ts +3 -3
  112. package/dist/src/sidebar-state.d.ts +20 -13
  113. package/dist/src/sidebar-state.d.ts.map +1 -1
  114. package/dist/src/sidebar-state.js +20 -10
  115. package/dist/src/sidebar-state.js.map +1 -1
  116. package/dist/src/tui/command-dialogs.d.ts +1 -1
  117. package/dist/src/tui/host-v1.d.ts +3 -3
  118. package/dist/src/tui.d.ts +3 -3
  119. package/dist/src/tui.js +1 -1
  120. package/dist/tui-build-map.json +6 -6
  121. package/dist/types/src/ga/server/index.d.ts.map +1 -1
  122. package/dist/types/src/plugin/auth-loader.d.ts.map +1 -1
  123. package/dist/types/src/plugin/background-vault-quota-refresh.d.ts +43 -0
  124. package/dist/types/src/plugin/background-vault-quota-refresh.d.ts.map +1 -0
  125. package/dist/types/src/plugin/command-data.d.ts +2 -246
  126. package/dist/types/src/plugin/command-data.d.ts.map +1 -1
  127. package/dist/types/src/plugin/gemini-dump.d.ts +0 -22
  128. package/dist/types/src/plugin/gemini-dump.d.ts.map +1 -1
  129. package/dist/types/src/plugin/index.d.ts +2 -0
  130. package/dist/types/src/plugin/index.d.ts.map +1 -1
  131. package/dist/types/src/plugin/quota.d.ts +1 -0
  132. package/dist/types/src/plugin/quota.d.ts.map +1 -1
  133. package/dist/types/src/plugin/request-helpers.d.ts.map +1 -1
  134. package/dist/types/src/plugin/shared/vault-request-credentials.d.ts +2 -0
  135. package/dist/types/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
  136. package/dist/types/src/plugin/vault-quota-refresh.d.ts +7 -0
  137. package/dist/types/src/plugin/vault-quota-refresh.d.ts.map +1 -0
  138. package/dist/types/src/plugin/vault-sidebar-projection.d.ts +27 -0
  139. package/dist/types/src/plugin/vault-sidebar-projection.d.ts.map +1 -0
  140. package/dist/types/src/sidebar-state.d.ts +20 -13
  141. package/dist/types/src/sidebar-state.d.ts.map +1 -1
  142. package/package.json +2 -2
  143. package/src/plugin/command-data.ts +6 -712
  144. package/src/sidebar-state.ts +34 -15
  145. package/src/tui-compiled/sidebar-state.js +12 -5
  146. package/src/tui-compiled/tui.js +1 -1
  147. package/src/tui-raw/sidebar-state.js +12 -5
  148. package/src/tui-raw/tui.tsx +1 -1
  149. package/src/tui.tsx +1 -1
@@ -1,3 +1,4 @@
1
+ import { toGeminiSchema } from '@cortexkit/antigravity-auth-core';
1
2
  import { EMPTY_SCHEMA_PLACEHOLDER_DESCRIPTION, EMPTY_SCHEMA_PLACEHOLDER_NAME, } from '../constants';
2
3
  import { getKeepThinking } from './config';
3
4
  import { processImageData } from './image-saver';
@@ -8,38 +9,6 @@ const ANTIGRAVITY_PREVIEW_LINK = 'https://goo.gle/enable-preview-features'; // T
8
9
  // JSON SCHEMA CLEANING FOR ANTIGRAVITY API
9
10
  // Ported from CLIProxyAPI's CleanJSONSchemaForAntigravity (gemini_schema.go)
10
11
  // ============================================================================
11
- /**
12
- * Unsupported constraint keywords that should be moved to description hints.
13
- * Claude/Gemini reject these in VALIDATED mode.
14
- */
15
- const UNSUPPORTED_CONSTRAINTS = [
16
- 'minLength',
17
- 'maxLength',
18
- 'exclusiveMinimum',
19
- 'exclusiveMaximum',
20
- 'pattern',
21
- 'minItems',
22
- 'maxItems',
23
- 'format',
24
- 'default',
25
- 'examples',
26
- ];
27
- /**
28
- * Keywords that should be removed after hint extraction.
29
- */
30
- const UNSUPPORTED_KEYWORDS = [
31
- ...UNSUPPORTED_CONSTRAINTS,
32
- '$schema',
33
- '$defs',
34
- 'definitions',
35
- 'const',
36
- '$ref',
37
- 'additionalProperties',
38
- 'propertyNames',
39
- 'title',
40
- '$id',
41
- '$comment',
42
- ];
43
12
  /**
44
13
  * Appends a hint to a schema's description field.
45
14
  */
@@ -78,28 +47,6 @@ function convertRefsToHints(schema) {
78
47
  }
79
48
  return result;
80
49
  }
81
- /**
82
- * Phase 1b: Converts const to enum.
83
- * { const: "foo" } → { enum: ["foo"] }
84
- */
85
- function convertConstToEnum(schema) {
86
- if (!schema || typeof schema !== 'object') {
87
- return schema;
88
- }
89
- if (Array.isArray(schema)) {
90
- return schema.map((item) => convertConstToEnum(item));
91
- }
92
- const result = {};
93
- for (const [key, value] of Object.entries(schema)) {
94
- if (key === 'const' && !schema.enum) {
95
- result.enum = [value];
96
- }
97
- else {
98
- result[key] = convertConstToEnum(value);
99
- }
100
- }
101
- return result;
102
- }
103
50
  /**
104
51
  * Phase 1c: Adds enum hints to description.
105
52
  * { enum: ["a", "b", "c"] } → adds "(Allowed: a, b, c)" to description
@@ -114,6 +61,7 @@ function addEnumHints(schema) {
114
61
  let result = { ...schema };
115
62
  // Add enum hint if enum has 2-10 items
116
63
  if (Array.isArray(result.enum) &&
64
+ result.enum.every((value) => typeof value === 'string') &&
117
65
  result.enum.length > 1 &&
118
66
  result.enum.length <= 10) {
119
67
  const vals = result.enum.map((v) => String(v)).join(', ');
@@ -127,289 +75,6 @@ function addEnumHints(schema) {
127
75
  }
128
76
  return result;
129
77
  }
130
- /**
131
- * Phase 1d: Adds additionalProperties hints.
132
- * { additionalProperties: false } → adds "(No extra properties allowed)" to description
133
- */
134
- function addAdditionalPropertiesHints(schema) {
135
- if (!schema || typeof schema !== 'object') {
136
- return schema;
137
- }
138
- if (Array.isArray(schema)) {
139
- return schema.map((item) => addAdditionalPropertiesHints(item));
140
- }
141
- let result = { ...schema };
142
- if (result.additionalProperties === false) {
143
- result = appendDescriptionHint(result, 'No extra properties allowed');
144
- }
145
- // Recursively process nested objects
146
- for (const [key, value] of Object.entries(result)) {
147
- if (key !== 'additionalProperties' &&
148
- typeof value === 'object' &&
149
- value !== null) {
150
- result[key] = addAdditionalPropertiesHints(value);
151
- }
152
- }
153
- return result;
154
- }
155
- /**
156
- * Phase 1e: Moves unsupported constraints to description hints.
157
- * { minLength: 1, maxLength: 100 } → adds "(minLength: 1) (maxLength: 100)" to description
158
- */
159
- function moveConstraintsToDescription(schema) {
160
- if (!schema || typeof schema !== 'object') {
161
- return schema;
162
- }
163
- if (Array.isArray(schema)) {
164
- return schema.map((item) => moveConstraintsToDescription(item));
165
- }
166
- let result = { ...schema };
167
- // Move constraint values to description
168
- for (const constraint of UNSUPPORTED_CONSTRAINTS) {
169
- if (result[constraint] !== undefined &&
170
- typeof result[constraint] !== 'object') {
171
- result = appendDescriptionHint(result, `${constraint}: ${result[constraint]}`);
172
- }
173
- }
174
- // Recursively process nested objects
175
- for (const [key, value] of Object.entries(result)) {
176
- if (typeof value === 'object' && value !== null) {
177
- result[key] = moveConstraintsToDescription(value);
178
- }
179
- }
180
- return result;
181
- }
182
- /**
183
- * Phase 2a: Merges allOf schemas into a single object.
184
- * { allOf: [{ properties: { a: ... } }, { properties: { b: ... } }] }
185
- * → { properties: { a: ..., b: ... } }
186
- */
187
- function mergeAllOf(schema) {
188
- if (!schema || typeof schema !== 'object') {
189
- return schema;
190
- }
191
- if (Array.isArray(schema)) {
192
- return schema.map((item) => mergeAllOf(item));
193
- }
194
- const result = { ...schema };
195
- // If this object has allOf, merge its contents
196
- if (Array.isArray(result.allOf)) {
197
- const merged = {};
198
- const mergedRequired = [];
199
- for (const item of result.allOf) {
200
- if (!item || typeof item !== 'object')
201
- continue;
202
- // Merge properties
203
- if (item.properties && typeof item.properties === 'object') {
204
- merged.properties = { ...merged.properties, ...item.properties };
205
- }
206
- // Merge required arrays
207
- if (Array.isArray(item.required)) {
208
- for (const req of item.required) {
209
- if (!mergedRequired.includes(req)) {
210
- mergedRequired.push(req);
211
- }
212
- }
213
- }
214
- // Copy other fields from allOf items
215
- for (const [key, value] of Object.entries(item)) {
216
- if (key !== 'properties' &&
217
- key !== 'required' &&
218
- merged[key] === undefined) {
219
- merged[key] = value;
220
- }
221
- }
222
- }
223
- // Apply merged content to result
224
- if (merged.properties) {
225
- result.properties = { ...result.properties, ...merged.properties };
226
- }
227
- if (mergedRequired.length > 0) {
228
- const existingRequired = Array.isArray(result.required)
229
- ? result.required
230
- : [];
231
- result.required = Array.from(new Set([...existingRequired, ...mergedRequired]));
232
- }
233
- // Copy other merged fields
234
- for (const [key, value] of Object.entries(merged)) {
235
- if (key !== 'properties' &&
236
- key !== 'required' &&
237
- result[key] === undefined) {
238
- result[key] = value;
239
- }
240
- }
241
- delete result.allOf;
242
- }
243
- // Recursively process nested objects
244
- for (const [key, value] of Object.entries(result)) {
245
- if (typeof value === 'object' && value !== null) {
246
- result[key] = mergeAllOf(value);
247
- }
248
- }
249
- return result;
250
- }
251
- /**
252
- * Scores a schema option for selection in anyOf/oneOf flattening.
253
- * Higher score = more preferred.
254
- */
255
- function scoreSchemaOption(schema) {
256
- if (!schema || typeof schema !== 'object') {
257
- return { score: 0, typeName: 'unknown' };
258
- }
259
- const type = schema.type;
260
- // Object or has properties = highest priority
261
- if (type === 'object' || schema.properties) {
262
- return { score: 3, typeName: 'object' };
263
- }
264
- // Array or has items = second priority
265
- if (type === 'array' || schema.items) {
266
- return { score: 2, typeName: 'array' };
267
- }
268
- // Any other non-null type
269
- if (type && type !== 'null') {
270
- return { score: 1, typeName: type };
271
- }
272
- // Null or no type
273
- return { score: 0, typeName: type || 'null' };
274
- }
275
- /**
276
- * Checks if an anyOf/oneOf array represents enum choices.
277
- * Returns the merged enum values if so, otherwise null.
278
- *
279
- * Handles patterns like:
280
- * - anyOf: [{ const: "a" }, { const: "b" }]
281
- * - anyOf: [{ enum: ["a"] }, { enum: ["b"] }]
282
- * - anyOf: [{ type: "string", const: "a" }, { type: "string", const: "b" }]
283
- */
284
- function tryMergeEnumFromUnion(options) {
285
- if (!Array.isArray(options) || options.length === 0) {
286
- return null;
287
- }
288
- const enumValues = [];
289
- for (const option of options) {
290
- if (!option || typeof option !== 'object') {
291
- return null;
292
- }
293
- // Check for const value
294
- if (option.const !== undefined) {
295
- enumValues.push(String(option.const));
296
- continue;
297
- }
298
- // Check for single-value enum
299
- if (Array.isArray(option.enum) && option.enum.length === 1) {
300
- enumValues.push(String(option.enum[0]));
301
- continue;
302
- }
303
- // Check for multi-value enum (merge all values)
304
- if (Array.isArray(option.enum) && option.enum.length > 0) {
305
- for (const val of option.enum) {
306
- enumValues.push(String(val));
307
- }
308
- continue;
309
- }
310
- // If option has complex structure (properties, items, etc.), it's not a simple enum
311
- if (option.properties ||
312
- option.items ||
313
- option.anyOf ||
314
- option.oneOf ||
315
- option.allOf) {
316
- return null;
317
- }
318
- // If option has only type (no const/enum), it's not an enum pattern
319
- if (option.type && !option.const && !option.enum) {
320
- return null;
321
- }
322
- }
323
- // Only return if we found actual enum values
324
- return enumValues.length > 0 ? enumValues : null;
325
- }
326
- /**
327
- * Phase 2b: Flattens anyOf/oneOf to the best option with type hints.
328
- * { anyOf: [{ type: "string" }, { type: "number" }] }
329
- * → { type: "string", description: "(Accepts: string | number)" }
330
- *
331
- * Special handling for enum patterns:
332
- * { anyOf: [{ const: "a" }, { const: "b" }] }
333
- * → { type: "string", enum: ["a", "b"] }
334
- */
335
- function flattenAnyOfOneOf(schema) {
336
- if (!schema || typeof schema !== 'object') {
337
- return schema;
338
- }
339
- if (Array.isArray(schema)) {
340
- return schema.map((item) => flattenAnyOfOneOf(item));
341
- }
342
- let result = { ...schema };
343
- // Process anyOf or oneOf
344
- for (const unionKey of ['anyOf', 'oneOf']) {
345
- if (Array.isArray(result[unionKey]) && result[unionKey].length > 0) {
346
- const options = result[unionKey];
347
- const parentDesc = typeof result.description === 'string' ? result.description : '';
348
- // First, check if this is an enum pattern (anyOf with const/enum values)
349
- // This is crucial for tools like WebFetch where format: anyOf[{const:"text"},{const:"markdown"},{const:"html"}]
350
- const mergedEnum = tryMergeEnumFromUnion(options);
351
- if (mergedEnum !== null) {
352
- // This is an enum pattern - merge all values into a single enum
353
- const { [unionKey]: _, ...rest } = result;
354
- result = {
355
- ...rest,
356
- type: 'string',
357
- enum: mergedEnum,
358
- };
359
- // Preserve parent description
360
- if (parentDesc) {
361
- result.description = parentDesc;
362
- }
363
- continue;
364
- }
365
- // Not an enum pattern - use standard flattening logic
366
- // Score each option and find the best
367
- let bestIdx = 0;
368
- let bestScore = -1;
369
- const allTypes = [];
370
- for (let i = 0; i < options.length; i++) {
371
- const { score, typeName } = scoreSchemaOption(options[i]);
372
- if (typeName) {
373
- allTypes.push(typeName);
374
- }
375
- if (score > bestScore) {
376
- bestScore = score;
377
- bestIdx = i;
378
- }
379
- }
380
- // Select the best option and flatten it recursively
381
- let selected = flattenAnyOfOneOf(options[bestIdx]) || { type: 'string' };
382
- // Preserve parent description
383
- if (parentDesc) {
384
- const childDesc = typeof selected.description === 'string' ? selected.description : '';
385
- if (childDesc && childDesc !== parentDesc) {
386
- selected = {
387
- ...selected,
388
- description: `${parentDesc} (${childDesc})`,
389
- };
390
- }
391
- else if (!childDesc) {
392
- selected = { ...selected, description: parentDesc };
393
- }
394
- }
395
- if (allTypes.length > 1) {
396
- const uniqueTypes = Array.from(new Set(allTypes));
397
- const hint = `Accepts: ${uniqueTypes.join(' | ')}`;
398
- selected = appendDescriptionHint(selected, hint);
399
- }
400
- // Replace result with selected schema, preserving other fields
401
- const { [unionKey]: _, description: __, ...rest } = result;
402
- result = { ...rest, ...selected };
403
- }
404
- }
405
- // Recursively process nested objects
406
- for (const [key, value] of Object.entries(result)) {
407
- if (typeof value === 'object' && value !== null) {
408
- result[key] = flattenAnyOfOneOf(value);
409
- }
410
- }
411
- return result;
412
- }
413
78
  /**
414
79
  * Phase 2c: Flattens type arrays to single type with nullable hint.
415
80
  * { type: ["string", "null"] } → { type: "string", description: "(nullable)" }
@@ -481,72 +146,6 @@ function flattenTypeArrays(schema, nullableFields, currentPath) {
481
146
  }
482
147
  return result;
483
148
  }
484
- /**
485
- * Phase 3: Removes unsupported keywords after hints have been extracted.
486
- * @param insideProperties - When true, keys are property NAMES (preserve); when false, keys are JSON Schema keywords (filter).
487
- */
488
- function removeUnsupportedKeywords(schema, insideProperties = false) {
489
- if (!schema || typeof schema !== 'object') {
490
- return schema;
491
- }
492
- if (Array.isArray(schema)) {
493
- return schema.map((item) => removeUnsupportedKeywords(item, false));
494
- }
495
- const result = {};
496
- for (const [key, value] of Object.entries(schema)) {
497
- if (!insideProperties &&
498
- UNSUPPORTED_KEYWORDS.includes(key)) {
499
- continue;
500
- }
501
- if (typeof value === 'object' && value !== null) {
502
- if (key === 'properties') {
503
- const propertiesResult = {};
504
- for (const [propName, propSchema] of Object.entries(value)) {
505
- propertiesResult[propName] = removeUnsupportedKeywords(propSchema, false);
506
- }
507
- result[key] = propertiesResult;
508
- }
509
- else {
510
- result[key] = removeUnsupportedKeywords(value, false);
511
- }
512
- }
513
- else {
514
- result[key] = value;
515
- }
516
- }
517
- return result;
518
- }
519
- /**
520
- * Phase 3b: Cleans up required fields - removes entries that don't exist in properties.
521
- */
522
- function cleanupRequiredFields(schema) {
523
- if (!schema || typeof schema !== 'object') {
524
- return schema;
525
- }
526
- if (Array.isArray(schema)) {
527
- return schema.map((item) => cleanupRequiredFields(item));
528
- }
529
- const result = { ...schema };
530
- // Clean up required array if properties exist
531
- if (Array.isArray(result.required) &&
532
- result.properties &&
533
- typeof result.properties === 'object') {
534
- const validRequired = result.required.filter((req) => Object.hasOwn(result.properties, req));
535
- if (validRequired.length === 0) {
536
- delete result.required;
537
- }
538
- else if (validRequired.length !== result.required.length) {
539
- result.required = validRequired;
540
- }
541
- }
542
- // Recursively process nested objects
543
- for (const [key, value] of Object.entries(result)) {
544
- if (typeof value === 'object' && value !== null) {
545
- result[key] = cleanupRequiredFields(value);
546
- }
547
- }
548
- return result;
549
- }
550
149
  /**
551
150
  * Phase 4: Adds placeholder property for empty object schemas.
552
151
  * Claude VALIDATED mode requires at least one property.
@@ -593,23 +192,17 @@ export function cleanJSONSchemaForAntigravity(schema) {
593
192
  if (!schema || typeof schema !== 'object') {
594
193
  return schema;
595
194
  }
596
- let result = schema;
597
- // Phase 1: Convert and add hints
598
- result = convertRefsToHints(result);
599
- result = convertConstToEnum(result);
195
+ // Claude requests run with VALIDATED function calling, whose schema validation
196
+ // rejects empty object parameters, unresolved $refs and type arrays. Replace
197
+ // $refs with description hints, choose one type from each type array, and give
198
+ // empty objects a placeholder property. The shared converter's Claude option
199
+ // then flattens unions and moves scalar constraints (lengths, pattern, format,
200
+ // default) into descriptions, which this validation also refuses.
201
+ let result = convertRefsToHints(schema);
600
202
  result = addEnumHints(result);
601
- result = addAdditionalPropertiesHints(result);
602
- result = moveConstraintsToDescription(result);
603
- // Phase 2: Flatten complex structures
604
- result = mergeAllOf(result);
605
- result = flattenAnyOfOneOf(result);
606
203
  result = flattenTypeArrays(result);
607
- // Phase 3: Cleanup
608
- result = removeUnsupportedKeywords(result);
609
- result = cleanupRequiredFields(result);
610
- // Phase 4: Add placeholder for empty object schemas
611
204
  result = addEmptySchemaPlaceholder(result);
612
- return result;
205
+ return toGeminiSchema(result, { claudeValidated: true });
613
206
  }
614
207
  /**
615
208
  * Default token budget for thinking/reasoning. 16000 tokens provides sufficient