mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-19 11:41:04 +02:00
fix: support Gemini JSON schema tools (#463)
* fix: support Gemini JSON schema tools * fix: harden Dograh Gemini adapter wiring * fix: route Gemini Live tool schemas through parameters_json_schema Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Abhishek Kumar <abhishek@a6k.me> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
978fb9c262
commit
d817d50056
5 changed files with 225 additions and 4 deletions
160
api/tests/test_gemini_json_schema_adapter.py
Normal file
160
api/tests/test_gemini_json_schema_adapter.py
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
from google.genai.types import GenerateContentConfig, LiveConnectConfig
|
||||
from pipecat.adapters.schemas.function_schema import FunctionSchema
|
||||
from pipecat.adapters.schemas.tools_schema import ToolsSchema
|
||||
|
||||
from api.services.configuration.registry import ServiceProviders
|
||||
from api.services.pipecat.gemini_json_schema_adapter import (
|
||||
DograhGeminiJSONSchemaAdapter,
|
||||
)
|
||||
from api.services.pipecat.realtime.gemini_live import DograhGeminiLiveLLMService
|
||||
from api.services.pipecat.realtime.gemini_live_vertex import (
|
||||
DograhGeminiLiveVertexLLMService,
|
||||
)
|
||||
from api.services.pipecat.service_factory import (
|
||||
DograhGoogleLLMService,
|
||||
DograhGoogleVertexLLMService,
|
||||
create_llm_service_from_provider,
|
||||
)
|
||||
|
||||
|
||||
def test_gemini_tools_use_json_schema_parameters_for_external_schemas():
|
||||
function_schema = FunctionSchema(
|
||||
name="customer_lookup",
|
||||
description="Look up a customer by email.",
|
||||
properties={
|
||||
"customerEmail": {
|
||||
"description": "Customer email address",
|
||||
"anyOf": [
|
||||
{"anyOf": [{"not": {}}]},
|
||||
{"const": ""},
|
||||
],
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "string"},
|
||||
},
|
||||
},
|
||||
required=["customerEmail"],
|
||||
)
|
||||
|
||||
tools = DograhGeminiJSONSchemaAdapter().to_provider_tools_format(
|
||||
ToolsSchema(standard_tools=[function_schema])
|
||||
)
|
||||
|
||||
declaration = tools[0]["function_declarations"][0]
|
||||
assert "parameters" not in declaration
|
||||
assert (
|
||||
declaration["parameters_json_schema"]["properties"]["customerEmail"]["anyOf"][
|
||||
0
|
||||
]["anyOf"][0]["not"]
|
||||
== {}
|
||||
)
|
||||
assert (
|
||||
declaration["parameters_json_schema"]["properties"]["customerEmail"]["anyOf"][
|
||||
1
|
||||
]["const"]
|
||||
== ""
|
||||
)
|
||||
assert declaration["parameters_json_schema"]["properties"]["metadata"][
|
||||
"additionalProperties"
|
||||
] == {"type": "string"}
|
||||
|
||||
GenerateContentConfig(tools=tools)
|
||||
|
||||
|
||||
def test_gemini_tools_use_json_schema_parameters_for_no_argument_tools():
|
||||
function_schema = FunctionSchema(
|
||||
name="refresh_context",
|
||||
description="Refresh the current context.",
|
||||
properties={},
|
||||
required=[],
|
||||
)
|
||||
|
||||
tools = DograhGeminiJSONSchemaAdapter().to_provider_tools_format(
|
||||
ToolsSchema(standard_tools=[function_schema])
|
||||
)
|
||||
|
||||
declaration = tools[0]["function_declarations"][0]
|
||||
assert "parameters" not in declaration
|
||||
assert declaration["parameters_json_schema"] == {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
}
|
||||
|
||||
GenerateContentConfig(tools=tools)
|
||||
|
||||
|
||||
def test_google_service_classes_use_dograh_gemini_adapter_class():
|
||||
assert DograhGoogleLLMService.adapter_class is DograhGeminiJSONSchemaAdapter
|
||||
assert DograhGoogleVertexLLMService.adapter_class is DograhGeminiJSONSchemaAdapter
|
||||
|
||||
|
||||
def test_google_llm_service_factory_uses_dograh_service_class():
|
||||
with patch(
|
||||
"api.services.pipecat.service_factory.DograhGoogleLLMService",
|
||||
) as mock_service:
|
||||
result = create_llm_service_from_provider(
|
||||
provider=ServiceProviders.GOOGLE.value,
|
||||
model="gemini-2.5-flash",
|
||||
api_key="test-api-key",
|
||||
)
|
||||
|
||||
assert result is mock_service.return_value
|
||||
assert mock_service.call_args.kwargs["api_key"] == "test-api-key"
|
||||
assert mock_service.call_args.kwargs["settings"].model == "gemini-2.5-flash"
|
||||
|
||||
|
||||
def test_google_vertex_llm_service_factory_uses_dograh_service_class():
|
||||
with patch(
|
||||
"api.services.pipecat.service_factory.DograhGoogleVertexLLMService",
|
||||
) as mock_service:
|
||||
result = create_llm_service_from_provider(
|
||||
provider=ServiceProviders.GOOGLE_VERTEX.value,
|
||||
model="gemini-2.5-pro",
|
||||
api_key=None,
|
||||
project_id="demo-project",
|
||||
location="us-central1",
|
||||
credentials='{"type":"service_account"}',
|
||||
)
|
||||
|
||||
assert result is mock_service.return_value
|
||||
assert mock_service.call_args.kwargs["project_id"] == "demo-project"
|
||||
assert mock_service.call_args.kwargs["location"] == "us-central1"
|
||||
assert mock_service.call_args.kwargs["settings"].model == "gemini-2.5-pro"
|
||||
|
||||
|
||||
def test_gemini_live_service_classes_use_dograh_gemini_adapter_class():
|
||||
assert DograhGeminiLiveLLMService.adapter_class is DograhGeminiJSONSchemaAdapter
|
||||
# Vertex Live inherits adapter_class from DograhGeminiLiveLLMService via MRO.
|
||||
assert (
|
||||
DograhGeminiLiveVertexLLMService.adapter_class is DograhGeminiJSONSchemaAdapter
|
||||
)
|
||||
|
||||
|
||||
def test_gemini_live_config_accepts_json_schema_tools():
|
||||
function_schema = FunctionSchema(
|
||||
name="customer_lookup",
|
||||
description="Look up a customer by email.",
|
||||
properties={
|
||||
"customerEmail": {
|
||||
"description": "Customer email address",
|
||||
"anyOf": [{"not": {}}, {"const": ""}],
|
||||
},
|
||||
},
|
||||
required=["customerEmail"],
|
||||
)
|
||||
|
||||
tools = DograhGeminiJSONSchemaAdapter().to_provider_tools_format(
|
||||
ToolsSchema(standard_tools=[function_schema])
|
||||
)
|
||||
|
||||
declaration = tools[0]["function_declarations"][0]
|
||||
assert "parameters" not in declaration
|
||||
assert "parameters_json_schema" in declaration
|
||||
|
||||
# Gemini Live validates tools through LiveConnectConfig rather than
|
||||
# GenerateContentConfig; it must also accept the raw JSON Schema payload.
|
||||
LiveConnectConfig(tools=tools)
|
||||
|
|
@ -34,7 +34,7 @@ class TestGoogleVertexLLMConfiguration:
|
|||
class TestGoogleVertexLLMServiceFactory:
|
||||
def test_create_llm_service_from_provider_uses_vertex_service(self):
|
||||
with patch(
|
||||
"api.services.pipecat.service_factory.GoogleVertexLLMService"
|
||||
"api.services.pipecat.service_factory.DograhGoogleVertexLLMService"
|
||||
) as mock_service:
|
||||
create_llm_service_from_provider(
|
||||
provider=ServiceProviders.GOOGLE_VERTEX.value,
|
||||
|
|
@ -65,7 +65,7 @@ class TestGoogleVertexLLMServiceFactory:
|
|||
)
|
||||
|
||||
with patch(
|
||||
"api.services.pipecat.service_factory.GoogleVertexLLMService"
|
||||
"api.services.pipecat.service_factory.DograhGoogleVertexLLMService"
|
||||
) as mock_service:
|
||||
create_llm_service(user_config)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue