discordbot/print_vertex_schema.py
2025-06-05 21:31:06 -06:00

95 lines
3.7 KiB
Python

import copy
import json
from typing import Dict, Any
# --- Schema Preprocessing Helper ---
# Copied from discordbot/gurt/api.py
def _preprocess_schema_for_vertex(schema: Dict[str, Any]) -> Dict[str, Any]:
"""
Recursively preprocesses a JSON schema dictionary to replace list types
(like ["string", "null"]) with the first non-null type, making it
compatible with Vertex AI's GenerationConfig schema requirements.
Args:
schema: The JSON schema dictionary to preprocess.
Returns:
A new, preprocessed schema dictionary.
"""
if not isinstance(schema, dict):
return schema # Return non-dict elements as is
processed_schema = copy.deepcopy(schema) # Work on a copy
for key, value in processed_schema.items():
if key == "type" and isinstance(value, list):
# Find the first non-"null" type in the list
first_valid_type = next(
(t for t in value if isinstance(t, str) and t.lower() != "null"), None
)
if first_valid_type:
processed_schema[key] = first_valid_type
else:
# Fallback if only "null" or invalid types are present (shouldn't happen in valid schemas)
processed_schema[key] = "object" # Or handle as error
print(
f"Warning: Schema preprocessing found list type '{value}' with no valid non-null string type. Falling back to 'object'."
)
elif isinstance(value, dict):
processed_schema[key] = _preprocess_schema_for_vertex(
value
) # Recurse for nested objects
elif isinstance(value, list):
# Recurse for items within arrays (e.g., in 'properties' of array items)
processed_schema[key] = [
_preprocess_schema_for_vertex(item) if isinstance(item, dict) else item
for item in value
]
# Handle 'properties' specifically
elif key == "properties" and isinstance(value, dict):
processed_schema[key] = {
prop_key: _preprocess_schema_for_vertex(prop_value)
for prop_key, prop_value in value.items()
}
# Handle 'items' specifically if it's a schema object
elif key == "items" and isinstance(value, dict):
processed_schema[key] = _preprocess_schema_for_vertex(value)
return processed_schema
# --- Response Schema ---
# Copied from discordbot/gurt/config.py
RESPONSE_SCHEMA = {
"name": "gurt_response",
"description": "The structured response from Gurt.",
"schema": {
"type": "object",
"properties": {
"should_respond": {
"type": "boolean",
"description": "Whether the bot should send a text message in response.",
},
"content": {
"type": "string",
"description": "The text content of the bot's response. Can be empty if only reacting.",
},
"react_with_emoji": {
"type": ["string", "null"],
"description": "Optional: A standard Discord emoji to react with, or null/empty if no reaction.",
},
"reply_to_message_id": {
"type": ["string", "null"],
"description": "Optional: The ID of the message this response should reply to. Null or omit for a regular message.",
},
# Note: tool_requests is handled by Vertex AI's function calling mechanism
},
"required": ["should_respond", "content"],
},
}
if __name__ == "__main__":
processed = _preprocess_schema_for_vertex(RESPONSE_SCHEMA["schema"])
print(json.dumps(processed, indent=2))