Spaces:
Paused
Paused
Mirrowel commited on
Commit ·
1ec1463
1
Parent(s): 740e192
refactor(antigravity): 🔨 improve additionalProperties handling in schema cleaning
Browse filesFor Claude schema cleaning:
- Preserve permissive `additionalProperties` (true or {}) for pass-through objects
- Normalize permissive values to `true` for consistency
- Pass through explicit `false` values unchanged
- Skip complex schema definitions that aren't supported
For Gemini enforcement:
- Only add `additionalProperties: false` when not already set
- Respect explicit `additionalProperties` values (true or false)
- Avoid enforcing strictness on pass-through objects with empty `properties
src/rotator_library/providers/antigravity_provider.py
CHANGED
|
@@ -403,6 +403,7 @@ def _clean_claude_schema(schema: Any) -> Any:
|
|
| 403 |
- Removes unsupported validation keywords at schema-definition level
|
| 404 |
- Preserves property NAMES even if they match validation keyword names
|
| 405 |
(e.g., a tool parameter named "pattern" is preserved)
|
|
|
|
| 406 |
- Converts 'const' to 'enum' with single value (supported equivalent)
|
| 407 |
- Converts 'anyOf'/'oneOf' to the first option (Claude doesn't support these)
|
| 408 |
"""
|
|
@@ -417,7 +418,7 @@ def _clean_claude_schema(schema: Any) -> Any:
|
|
| 417 |
"$ref",
|
| 418 |
"$defs",
|
| 419 |
"definitions",
|
| 420 |
-
|
| 421 |
}
|
| 422 |
|
| 423 |
# Validation keywords - only remove at schema-definition level,
|
|
@@ -477,6 +478,18 @@ def _clean_claude_schema(schema: Any) -> Any:
|
|
| 477 |
if key in meta_keywords or key == "const":
|
| 478 |
continue
|
| 479 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
# Skip validation keywords at schema level (these are constraints, not data)
|
| 481 |
if key in validation_keywords:
|
| 482 |
continue
|
|
@@ -2528,8 +2541,12 @@ class AntigravityProvider(
|
|
| 2528 |
"""
|
| 2529 |
Enforce strict JSON schema for Gemini 3 to prevent hallucinated parameters.
|
| 2530 |
|
| 2531 |
-
Adds 'additionalProperties: false'
|
| 2532 |
which tells the model it CANNOT add properties not in the schema.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2533 |
"""
|
| 2534 |
if not tools:
|
| 2535 |
return tools
|
|
@@ -2550,9 +2567,17 @@ class AntigravityProvider(
|
|
| 2550 |
else:
|
| 2551 |
result[key] = value
|
| 2552 |
|
| 2553 |
-
# Add additionalProperties: false to object schemas
|
|
|
|
|
|
|
| 2554 |
if result.get("type") == "object" and "properties" in result:
|
| 2555 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2556 |
|
| 2557 |
return result
|
| 2558 |
|
|
|
|
| 403 |
- Removes unsupported validation keywords at schema-definition level
|
| 404 |
- Preserves property NAMES even if they match validation keyword names
|
| 405 |
(e.g., a tool parameter named "pattern" is preserved)
|
| 406 |
+
- Preserves additionalProperties when permissive (true or {}) for pass-through objects
|
| 407 |
- Converts 'const' to 'enum' with single value (supported equivalent)
|
| 408 |
- Converts 'anyOf'/'oneOf' to the first option (Claude doesn't support these)
|
| 409 |
"""
|
|
|
|
| 418 |
"$ref",
|
| 419 |
"$defs",
|
| 420 |
"definitions",
|
| 421 |
+
# Note: additionalProperties is handled specially below - preserved when permissive
|
| 422 |
}
|
| 423 |
|
| 424 |
# Validation keywords - only remove at schema-definition level,
|
|
|
|
| 478 |
if key in meta_keywords or key == "const":
|
| 479 |
continue
|
| 480 |
|
| 481 |
+
# Special handling for additionalProperties:
|
| 482 |
+
# - Normalize permissive values ({} or true) to true
|
| 483 |
+
# - Pass through false as-is
|
| 484 |
+
# - Skip complex schema values (not supported by Antigravity's proto-based API)
|
| 485 |
+
if key == "additionalProperties":
|
| 486 |
+
if value is True or value == {} or (isinstance(value, dict) and not value):
|
| 487 |
+
cleaned["additionalProperties"] = True # Normalize {} to true
|
| 488 |
+
elif value is False:
|
| 489 |
+
cleaned["additionalProperties"] = False # Pass through explicit false
|
| 490 |
+
# Skip complex schema values (e.g., {"type": "string"})
|
| 491 |
+
continue
|
| 492 |
+
|
| 493 |
# Skip validation keywords at schema level (these are constraints, not data)
|
| 494 |
if key in validation_keywords:
|
| 495 |
continue
|
|
|
|
| 2541 |
"""
|
| 2542 |
Enforce strict JSON schema for Gemini 3 to prevent hallucinated parameters.
|
| 2543 |
|
| 2544 |
+
Adds 'additionalProperties: false' to object schemas that don't already have it set,
|
| 2545 |
which tells the model it CANNOT add properties not in the schema.
|
| 2546 |
+
|
| 2547 |
+
Exceptions (leaves schema unchanged):
|
| 2548 |
+
- Objects that already have 'additionalProperties' set (true or false)
|
| 2549 |
+
- Objects with empty 'properties: {}' (pass-through objects like batch tool's parameters)
|
| 2550 |
"""
|
| 2551 |
if not tools:
|
| 2552 |
return tools
|
|
|
|
| 2567 |
else:
|
| 2568 |
result[key] = value
|
| 2569 |
|
| 2570 |
+
# Add additionalProperties: false to object schemas, with exceptions:
|
| 2571 |
+
# 1. Skip if already set (respect explicit true or false from client)
|
| 2572 |
+
# 2. Skip if properties is empty {} (dynamic/pass-through object)
|
| 2573 |
if result.get("type") == "object" and "properties" in result:
|
| 2574 |
+
if "additionalProperties" in result:
|
| 2575 |
+
pass # Already set - respect client's choice
|
| 2576 |
+
elif not result.get("properties"):
|
| 2577 |
+
pass # Empty properties - leave permissive for dynamic objects
|
| 2578 |
+
else:
|
| 2579 |
+
# Has defined properties and no explicit setting - enforce strict
|
| 2580 |
+
result["additionalProperties"] = False
|
| 2581 |
|
| 2582 |
return result
|
| 2583 |
|