| """Helpers for translating OpenAI-style tool schemas to Gemini's schema subset.""" |
|
|
| from __future__ import annotations |
|
|
| from typing import Any, Dict, List |
|
|
| |
| |
| |
| _GEMINI_SCHEMA_ALLOWED_KEYS = { |
| "type", |
| "format", |
| "title", |
| "description", |
| "nullable", |
| "enum", |
| "maxItems", |
| "minItems", |
| "properties", |
| "required", |
| "minProperties", |
| "maxProperties", |
| "minLength", |
| "maxLength", |
| "pattern", |
| "example", |
| "anyOf", |
| "propertyOrdering", |
| "default", |
| "items", |
| "minimum", |
| "maximum", |
| } |
|
|
|
|
| def sanitize_gemini_schema(schema: Any) -> Dict[str, Any]: |
| """Return a Gemini-compatible copy of a tool parameter schema. |
| |
| Hermes tool schemas are OpenAI-flavored JSON Schema and may contain keys |
| such as ``$schema`` or ``additionalProperties`` that Google's Gemini |
| ``Schema`` object rejects. This helper preserves the documented Gemini |
| subset and recursively sanitizes nested ``properties`` / ``items`` / |
| ``anyOf`` definitions. |
| """ |
|
|
| if not isinstance(schema, dict): |
| return {} |
|
|
| cleaned: Dict[str, Any] = {} |
| for key, value in schema.items(): |
| if key not in _GEMINI_SCHEMA_ALLOWED_KEYS: |
| continue |
| if key == "properties": |
| if not isinstance(value, dict): |
| continue |
| props: Dict[str, Any] = {} |
| for prop_name, prop_schema in value.items(): |
| if not isinstance(prop_name, str): |
| continue |
| props[prop_name] = sanitize_gemini_schema(prop_schema) |
| cleaned[key] = props |
| continue |
| if key == "items": |
| cleaned[key] = sanitize_gemini_schema(value) |
| continue |
| if key == "anyOf": |
| if not isinstance(value, list): |
| continue |
| cleaned[key] = [ |
| sanitize_gemini_schema(item) |
| for item in value |
| if isinstance(item, dict) |
| ] |
| continue |
| cleaned[key] = value |
| return cleaned |
|
|
|
|
| def sanitize_gemini_tool_parameters(parameters: Any) -> Dict[str, Any]: |
| """Normalize tool parameters to a valid Gemini object schema.""" |
|
|
| cleaned = sanitize_gemini_schema(parameters) |
| if not cleaned: |
| return {"type": "object", "properties": {}} |
| return cleaned |
|
|