@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.
- package/dist/cli.js.map +2 -2
- package/dist/cli.meta.json +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2877 -2851
- package/dist/index.js.map +4 -4
- package/dist/index.meta.json +120 -33
- package/dist/server.js +475 -427
- package/dist/server.js.map +4 -4
- package/dist/server.meta.json +1 -7313
- package/dist/src/cli.d.ts +1 -1
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/ga/rpc/protocol.d.ts +1 -1
- package/dist/src/ga/server/index.d.ts +6 -6
- package/dist/src/ga/server/index.d.ts.map +1 -1
- package/dist/src/ga/server/index.js +29 -1
- package/dist/src/ga/server/index.js.map +1 -1
- package/dist/src/ga/tui/host-ga.d.ts +2 -2
- package/dist/src/hooks/auto-update-checker/checker.d.ts +1 -1
- package/dist/src/hooks/auto-update-checker/index.d.ts +4 -4
- package/dist/src/plugin/account-access.d.ts +6 -6
- package/dist/src/plugin/account-command-oauth.d.ts +2 -2
- package/dist/src/plugin/accounts.d.ts +3 -3
- package/dist/src/plugin/auth-doctor.d.ts +2 -2
- package/dist/src/plugin/auth-drift.d.ts +2 -2
- package/dist/src/plugin/auth-loader.d.ts +8 -8
- package/dist/src/plugin/auth-loader.d.ts.map +1 -1
- package/dist/src/plugin/auth-loader.js +1 -0
- package/dist/src/plugin/auth-loader.js.map +1 -1
- package/dist/src/plugin/background-quota-refresh.d.ts +3 -3
- package/dist/src/plugin/background-vault-quota-refresh.d.ts +43 -0
- package/dist/src/plugin/background-vault-quota-refresh.d.ts.map +1 -0
- package/dist/src/plugin/background-vault-quota-refresh.js +155 -0
- package/dist/src/plugin/background-vault-quota-refresh.js.map +1 -0
- package/dist/src/plugin/cache/index.d.ts +1 -1
- package/dist/src/plugin/cache/signature-cache.d.ts +2 -2
- package/dist/src/plugin/cache.d.ts +6 -6
- package/dist/src/plugin/cli.d.ts +6 -6
- package/dist/src/plugin/command-apply.d.ts +1 -1
- package/dist/src/plugin/command-data.d.ts +2 -246
- package/dist/src/plugin/command-data.d.ts.map +1 -1
- package/dist/src/plugin/command-data.js +4 -418
- package/dist/src/plugin/command-data.js.map +1 -1
- package/dist/src/plugin/commands.d.ts +4 -4
- package/dist/src/plugin/config/index.d.ts +2 -2
- package/dist/src/plugin/config/loader.d.ts +2 -2
- package/dist/src/plugin/config/models.d.ts +2 -2
- package/dist/src/plugin/config/writer.d.ts +2 -2
- package/dist/src/plugin/core/streaming/index.d.ts +2 -2
- package/dist/src/plugin/core/streaming/transformer.d.ts +1 -1
- package/dist/src/plugin/debug.d.ts +1 -1
- package/dist/src/plugin/dependencies.d.ts +3 -3
- package/dist/src/plugin/event-handler.d.ts +3 -3
- package/dist/src/plugin/fetch-interceptor.d.ts +10 -10
- package/dist/src/plugin/fetch-routing.d.ts +3 -3
- package/dist/src/plugin/ga-location-services.d.ts +10 -10
- package/dist/src/plugin/gemini-dump.d.ts +0 -22
- package/dist/src/plugin/gemini-dump.d.ts.map +1 -1
- package/dist/src/plugin/gemini-dump.js +0 -39
- package/dist/src/plugin/gemini-dump.js.map +1 -1
- package/dist/src/plugin/google-search-tool.d.ts +1 -1
- package/dist/src/plugin/index.d.ts +8 -6
- package/dist/src/plugin/index.d.ts.map +1 -1
- package/dist/src/plugin/index.js +41 -18
- package/dist/src/plugin/index.js.map +1 -1
- package/dist/src/plugin/killswitch.d.ts +1 -1
- package/dist/src/plugin/lifecycle.d.ts +2 -2
- package/dist/src/plugin/logger.d.ts +2 -2
- package/dist/src/plugin/oauth-login.d.ts +1 -1
- package/dist/src/plugin/oauth-methods.d.ts +9 -9
- package/dist/src/plugin/operator-settings.d.ts +3 -3
- package/dist/src/plugin/persist-account-pool.d.ts +1 -1
- package/dist/src/plugin/quota.d.ts +5 -4
- package/dist/src/plugin/quota.d.ts.map +1 -1
- package/dist/src/plugin/quota.js +1 -0
- package/dist/src/plugin/quota.js.map +1 -1
- package/dist/src/plugin/recovery/index.d.ts +3 -3
- package/dist/src/plugin/recovery/storage.d.ts +1 -1
- package/dist/src/plugin/recovery.d.ts +3 -3
- package/dist/src/plugin/refresh-queue.d.ts +3 -3
- package/dist/src/plugin/request-helpers.d.ts +1 -1
- package/dist/src/plugin/request-helpers.d.ts.map +1 -1
- package/dist/src/plugin/request-helpers.js +10 -417
- package/dist/src/plugin/request-helpers.js.map +1 -1
- package/dist/src/plugin/request.d.ts +9 -9
- package/dist/src/plugin/request.js +4 -4
- package/dist/src/plugin/session-context.d.ts +1 -1
- package/dist/src/plugin/shared/request-services.d.ts +9 -9
- package/dist/src/plugin/shared/runtime.d.ts +11 -11
- package/dist/src/plugin/shared/source-sidebar.d.ts +1 -1
- package/dist/src/plugin/shared/vault-menu.d.ts +1 -1
- package/dist/src/plugin/shared/vault-request-credentials.d.ts +3 -1
- package/dist/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
- package/dist/src/plugin/shared/vault-request-credentials.js +1 -1
- package/dist/src/plugin/shared/vault-request-credentials.js.map +1 -1
- package/dist/src/plugin/stores/signature-store.d.ts +1 -1
- package/dist/src/plugin/token.d.ts +1 -1
- package/dist/src/plugin/ui/auth-menu.d.ts +4 -4
- package/dist/src/plugin/ui/model-status.d.ts +3 -3
- package/dist/src/plugin/ui/quota-status.d.ts +2 -2
- package/dist/src/plugin/vault-activation.d.ts +1 -1
- package/dist/src/plugin/vault-quota-refresh.d.ts +7 -0
- package/dist/src/plugin/vault-quota-refresh.d.ts.map +1 -0
- package/dist/src/plugin/vault-quota-refresh.js +12 -0
- package/dist/src/plugin/vault-quota-refresh.js.map +1 -0
- package/dist/src/plugin/vault-sidebar-projection.d.ts +27 -0
- package/dist/src/plugin/vault-sidebar-projection.d.ts.map +1 -0
- package/dist/src/plugin/vault-sidebar-projection.js +34 -0
- package/dist/src/plugin/vault-sidebar-projection.js.map +1 -0
- package/dist/src/rpc/notifications.d.ts +1 -1
- package/dist/src/rpc/rpc-server.d.ts +1 -1
- package/dist/src/server.d.ts +3 -3
- package/dist/src/sidebar-state.d.ts +20 -13
- package/dist/src/sidebar-state.d.ts.map +1 -1
- package/dist/src/sidebar-state.js +20 -10
- package/dist/src/sidebar-state.js.map +1 -1
- package/dist/src/tui/command-dialogs.d.ts +1 -1
- package/dist/src/tui/host-v1.d.ts +3 -3
- package/dist/src/tui.d.ts +3 -3
- package/dist/src/tui.js +1 -1
- package/dist/tui-build-map.json +6 -6
- package/dist/types/src/ga/server/index.d.ts.map +1 -1
- package/dist/types/src/plugin/auth-loader.d.ts.map +1 -1
- package/dist/types/src/plugin/background-vault-quota-refresh.d.ts +43 -0
- package/dist/types/src/plugin/background-vault-quota-refresh.d.ts.map +1 -0
- package/dist/types/src/plugin/command-data.d.ts +2 -246
- package/dist/types/src/plugin/command-data.d.ts.map +1 -1
- package/dist/types/src/plugin/gemini-dump.d.ts +0 -22
- package/dist/types/src/plugin/gemini-dump.d.ts.map +1 -1
- package/dist/types/src/plugin/index.d.ts +2 -0
- package/dist/types/src/plugin/index.d.ts.map +1 -1
- package/dist/types/src/plugin/quota.d.ts +1 -0
- package/dist/types/src/plugin/quota.d.ts.map +1 -1
- package/dist/types/src/plugin/request-helpers.d.ts.map +1 -1
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts +2 -0
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
- package/dist/types/src/plugin/vault-quota-refresh.d.ts +7 -0
- package/dist/types/src/plugin/vault-quota-refresh.d.ts.map +1 -0
- package/dist/types/src/plugin/vault-sidebar-projection.d.ts +27 -0
- package/dist/types/src/plugin/vault-sidebar-projection.d.ts.map +1 -0
- package/dist/types/src/sidebar-state.d.ts +20 -13
- package/dist/types/src/sidebar-state.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/plugin/command-data.ts +6 -712
- package/src/sidebar-state.ts +34 -15
- package/src/tui-compiled/sidebar-state.js +12 -5
- package/src/tui-compiled/tui.js +1 -1
- package/src/tui-raw/sidebar-state.js +12 -5
- package/src/tui-raw/tui.tsx +1 -1
- 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
|
-
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
|
|
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
|