Mirrowel commited on
Commit
1ec1463
·
1 Parent(s): 740e192

refactor(antigravity): 🔨 improve additionalProperties handling in schema cleaning

Browse files

For 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
- "additionalProperties",
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' recursively to all object schemas,
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
- result["additionalProperties"] = False
 
 
 
 
 
 
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