Description
I have an LLMAgent using the openAPIToolset to interface with a Rundeck server via its API.
When asking to run functions, most of the time it just prints [user] prompt again in CLI, or in adk web it doesn't return anything at all after showing the "thinking" dots that then disappear. It logs a MALFORMED_FUNCTION_CALL finish_reason.
Sometimes (5% of the time I would say) it will actually work, but mostly it is failing, and providing no output at all other than the trace logs.
Example of error from logs below - Note I have pruned down the Rundeck OpenAPI spec file to only provide limited function set to try and troubleshoot this, otherwise the function list would be big and not relevant. I have tried many different functions and simple tasks and it can happen on any of them:
{"parts":[{"text":"get status of execution id 1234"}],"role":"user"}
-----------------------------------------------------------
Functions:
api_execution: {'id': {'description': 'Execution ID', 'type': <Type.STRING: 'STRING'>}} -> None
api_jobs_listv2: {'project': {'description': 'Project Name', 'type': <Type.STRING: 'STRING'>}, ... (trunc)
-----------------------------------------------------------
2025-06-05 16:39:09,252 - INFO - models.py:7447 - AFC is enabled with max remote calls: 10.
2025-06-05 16:39:13,076 - INFO - _client.py:1740 - HTTP Request: POST https://us-central1-aiplatform.googleapis.com/v1beta1/projects/XXXXXXX/locations/us-central1/publishers/google/models/gemini-2.5-pro-preview-05-06:generateContent "HTTP/1.1 200 OK"
2025-06-05 16:39:13,077 - INFO - google_llm.py:151 -
LLM Response:
-----------------------------------------------------------
Text:
None
-----------------------------------------------------------
Function calls:
-----------------------------------------------------------
Raw response:
{"candidates":[{"content":{},"finish_message":"Malformed function call: print(default_api.api_jobs_listv2(_auth_prefix_vaf_X-Rundeck-Auth-Token = \"XXXXXXXXX\", project=\"My_Project\"))\nprint(default_api.api_execution(_auth_prefix_vaf_X-Rundeck-Auth-Token = \"XXXXXXXX\", id=\"1234\"))","finish_reason":"MALFORMED_FUNCTION_CALL"}],"create_time":"2025-06-05T16:39:09.903350Z","response_id":"ZZZZZZ","model_version":"gemini-2.5-pro-preview-05-06","usage_metadata":{"prompt_token_count":1737,"prompt_tokens_details":[{"modality":"TEXT","token_count":1737}],"total_token_count":1737,"traffic_type":"ON_DEMAND"},"automatic_function_calling_history":[]}
-----------------------------------------------------------
2025-06-05 16:39:13,077 - INFO - fast_api.py:705 - Generated event in agent run streaming: {"errorCode":"MALFORMED_FUNCTION_CALL","errorMessage":"Malformed function call: print(default_api.api_jobs_listv2(_auth_prefix_vaf_X-Rundeck-Auth-Token = \"XXXXXXXX\", project=\"My_Project\"))\nprint(default_api.api_execution(_auth_prefix_vaf_X-Rundeck-Auth-Token = \"XXXXXXXX\", id=\"1234\"))","usageMetadata":{"promptTokenCount":1737,"promptTokensDetails":[{"modality":"TEXT","tokenCount":1737}],"totalTokenCount":1737,"trafficType":"ON_DEMAND"},"invocationId":"YYYY","author":"rundeck_agent","actions":{"stateDelta":{},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"ZZZZZ","timestamp":1749141549.24444}
Expected behavior:
When it actually works in the log I do see the function call with all the args. When it fails it does not
{"parts":[{"text":"get status of job 1234"}],"role":"user"}
{"parts":[{"function_call":{"args":{ ...
{"parts":[{"function_response":{"name": ...
The agent.py code:
# Read from API_FILE location
openapi_spec_string = open(f"{API_FILE}", "r").read()
auth_scheme, auth_credential = token_to_scheme_credential(
"apikey", "header", "X-Rundeck-Auth-Token", f"{RUNDECK_API_TOKEN}"
)
# --- Create OpenAPIToolset ---
rundeck_toolset = OpenAPIToolset(
spec_str=openapi_spec_string,
spec_str_type='yaml',
auth_scheme=auth_scheme,
auth_credential=auth_credential
)
# --- Agent Definition ---
root_agent = LlmAgent(
name=AGENT_NAME_OPENAPI,
model=GEMINI_MODEL,
tools=[rundeck_toolset],
instruction="""
You are an assistant that can execute and retrieve information about jobs from Rundeck.
Only use the tools provided to interact with Rundeck.
""",
description="Manage Rundeck Jobs using tools generated from an OpenAPI spec.",
)
To reproduce you would need a rundeck server...
- OS: [e.g. iOS] RHEL8
- Python version(python -V): 3.12.8
- ADK version(pip show google-adk): 1.1.1
Additional context
I have tried this on Flash 2.0, Flash 2.5, and Pro 2.5 with same result.
I added a before_tool_callback to log args to see if that would help, but when this occurrs, it doesn't reach that part before the MALFORMED_FUNCTION_CALL and no response