Make Gemini work, fixing issues with schema conversion

This commit is contained in:
Dominik Jain committed 2025-04-01 15:14:49 +02:00
1 parent e30d99aea0
commit b1572a9717
2 files changed
+64 -2

No files matched your search

+5 -1
View File
@@ -2,6 +2,7 @@ import os
from logging import Logger
from agno.agent import Agent
from agno.memory import AgentMemory
from agno.models.anthropic import Claude
from agno.models.google import Gemini
from agno.playground import Playground, serve_playground_app
@@ -32,9 +33,12 @@ agno_agent = Agent(
tools=[SerenaAgnoToolkit(serena_agent)], # type: ignore
show_tool_calls=False,
markdown=True,
system_message="", # Todo
system_message=serena_agent.prompt_factory.create_system_prompt(),
read_tool_call_history=False,
telemetry=False,
memory=AgentMemory(),
add_history_to_messages=True,
num_history_responses=100, # you might want to adjust this (expense vs. history awareness)
)
# The app object must be in the module scope so that the server can access it for hot reloading
+59 -1
View File
@@ -8,6 +8,64 @@ from serena.agent import SerenaAgent, Tool
log = logging.getLogger(__name__)
def _patch_gemini_schema_conversion() -> None:
"""
This fixes errors in Agno's Gemini schema conversion, which does not correctly handle
optional types (union with None)
"""
from agno.models.google import gemini
from google.genai.types import Schema
def _convert_schema(schema_dict: dict) -> Schema | None:
schema_type = schema_dict.get("type", "")
if isinstance(schema_type, list):
schema_type = schema_type[0]
schema_type = schema_type.upper()
description = schema_dict.get("description", "")
if schema_type == "OBJECT" and "properties" in schema_dict:
properties = {key: _convert_schema(prop_def) for key, prop_def in schema_dict["properties"].items()}
required = schema_dict.get("required", [])
if properties:
return Schema(
type=schema_type,
properties=properties,
required=required,
description=description,
)
else:
return None
elif schema_type == "ARRAY" and "items" in schema_dict:
items = _convert_schema(schema_dict["items"])
return Schema(type=schema_type, description=description, items=items)
elif schema_type == "":
if "anyOf" in schema_dict:
relevant_sub_schemas = []
is_optional = False
for sub_schema in schema_dict["anyOf"]:
if sub_schema.get("type") == "null":
is_optional = True # noqa: F841
continue
relevant_sub_schemas.append(sub_schema)
# TODO handle is_optional (requires handling at the outer level)
if len(relevant_sub_schemas) == 1:
return _convert_schema(relevant_sub_schemas[0])
else:
return Schema(any_of=[_convert_schema(item) for item in schema_dict["anyOf"]], description=description)
else:
raise ValueError(f"Unhandled schema: {schema_dict}")
else:
return Schema(type=schema_type, description=description)
gemini._convert_schema = _convert_schema
_patch_gemini_schema_conversion()
class SerenaAgnoToolkit(Toolkit):
def __init__(self, serena_agent: SerenaAgent):
super().__init__("Serena")
@@ -28,5 +86,5 @@ class SerenaAgnoToolkit(Toolkit):
function = Function.from_callable(tool.get_apply_fn())
function.name = tool.get_name()
function.entrypoint = entrypoint
function.show_result = True
function.skip_entrypoint_processing = True
return function