adk-python
adk-python copied to clipboard
Native Ollama LLM Integration + Example Project + Full Unit Tests
π PR: Native Ollama LLM Integration + Example Project + Full Unit Tests
Includes: Critical Fix for Ollama Cloud Tool-Calling + Comparison Test with LiteLLM
π Link to Issue or Description of Change
No existing issue.
Submitting this as a major feature contribution that fills a critical gap in ADKβs LLM provider ecosystem.
β Problem
Google ADK currently relies on LiteLLM for Ollama usage (ollama_chat/...).
However, LiteLLM still fails with Ollama when using cloud models such as:
glm-4.6:cloudgpt-oss:20b-cloud
The failures include:
β LiteLLM + Ollama Cloud β Broken Tool Calling
- Tool calls not executed
- Arguments lost or malformed
- Function-call loops
- Context resets
- Multi-part messages break
- Streaming tool-calls fail
- Models stall in endless βtool useβ mode
- Developer cannot build agent workflows on top of it
In short:
LiteLLM cannot currently be used for production agentic tool-calling with Ollama Cloud models.
This makes ADK incomplete for:
- Enterprise cloud inference
- Hybrid local+cloud Ollama deployments
- Students and researchers using GGUF + cloud backup
- Any agent workflow that needs tools
π₯ Why This Feature Is Critical
β This PR provides the first working, reliable tool-calling path for Ollama Cloud models inside ADK.
Native Ollama backend β Stable.
LiteLLM backend β Broken for cloud models.
The ADK ecosystem must support Ollama Cloud + tools β and this PR provides exactly that.
β Solution β Full Native Ollama Support
This PR adds:
- A first-class, native Ollama backend (ollama_llm.py)
- Complete tool-calling implementation
- Local + cloud support
- Proper ADK message conversion
- Proper ADK β Ollama function-call bridging
- Full unit test suite
- Full example project
β 1. New Native Backend β ollama_llm.py
Implements BaseLlm with robust support for:
π§© Core Features
- Native HTTP
POST /api/chat - Correct role mapping (system/user/assistant/tool)
- Clean tool-calling path
- Argument parsing + JSON extraction
- Inline tool-call parsing
- Multi-message accumulation
- Generation parameter handling
- Error propagation
- Logging under
google_adk.xxx
π Model Routing
Supports all of these:
Ollama(model="llama3.2")
Ollama(model="gpt-oss:20b-cloud")
Agent(model="ollama/mistral")
Agent(model="ollama/llama3.1")
No LiteLLM required.
β 2. New Example Project β contributing/hello_world_ollama_native/
Shows:
β’ Native Ollama usage
β’ Tool calling
β’ Running via adk web
β’ Full minimal starter project
β 3. Full Unit Test Suite β test_ollama.py
Covers:
β’ Payload construction
β’ Tool schema mapping
β’ Inline JSON tool-call extraction
β’ Accumulating multi-chunk tool calls
β’ Empty chunk filtering
β’ Finish reason mapping
β’ Error handling
β’ LlmResponse construction
π¬ Additional Validation: Native Ollama vs LiteLLM (Cloud Models)
To help reviewers, I included side-by-side native vs LiteLLM comparison code.
This demonstrates that:
β Native Ollama works fully
β LiteLLM breaks on cloud models (tool calling fails)
Testing Code:
from google.adk.agents import Agent
from google.adk.models.ollama_llm import Ollama # Native backend (by Ayman)
from google.adk.models.lite_llm import LiteLlm # Existing LiteLLM backend
model = "glm-4.6:cloud"
ollama_model = Ollama(model=model)
lite_llm_model = LiteLlm(model=f"ollama_chat/{model}")
def add_numbers(x: int, y: int) -> int:
"""adds two numbers"""
return x + y
root_agent = Agent(
model=lite_llm_model,
name='root_agent',
description='A helpful assistant for user questions.',
instruction='Answer user questions and use add_numbers when needed.',
tools=[add_numbers]
)
Result:
β’ Ollama(model="glm-4.6:cloud") β β tool calling works properly
β’ LiteLlm(model="ollama_chat/glm-4.6:cloud") β β tool calling fails
This comparison proved essential for ensuring correctness of the new backend.
βΈ»
π§ͺ Testing Plan
β Unit Tests
β’ All pass
β’ All ADK tests untouched
β’ Added new test_ollama.py
β Manual E2E Tests
Tested with:
β’ llama3.2
β’ gpt-oss:20b-cloud
β’ glm-4.6:cloud
β’ qwen3:.6b
Validated:
β’ Tool calls
β’ Multi-round dialogs
β’ System instructions
β’ JSON argument passing
β’ No infinite loops
β’ Correct finish reason
β’ Context preserved
π Additional Context
This PR brings ADK to parity with other agentic frameworks by adding:
β’ Local model support
β’ Cloud + tool-calling compatibility
β’ Offline + privacy-first development
β’ GGUF ecosystem integration
Native Ollama support unlocks a huge community and makes ADK dramatically more accessible.
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).
View this failed invocation of the CLA check for more information.
For the most up to date status, view the checks section at the bottom of the pull request.
Summary of Changes
Hello @ayman3000, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly enhances ADK's LLM provider ecosystem by introducing a native Ollama integration. This new backend directly addresses and fixes critical tool-calling failures that previously affected cloud-based Ollama models when used via LiteLLM. By providing robust and reliable tool support, this change makes ADK fully compatible with enterprise cloud inference, hybrid local and cloud deployments, and advanced agent workflows that depend on accurate function calling, thereby broadening ADK's accessibility and utility.
Highlights
- Native Ollama LLM Integration: Introduces a first-class, native Ollama backend (
ollama_llm.py) to ADK, enabling direct communication with Ollama servers without relying on LiteLLM. - Critical Tool-Calling Fix for Cloud Models: Resolves significant issues with tool calling for Ollama Cloud models (e.g.,
glm-4.6:cloud,gpt-oss:20b-cloud) that were previously broken or unreliable when using LiteLLM, ensuring stable and correct execution of tool calls. - Comprehensive Tooling Support: Implements complete tool-calling functionality, including proper ADK message conversion, function-call bridging, argument parsing, JSON extraction, and multi-message accumulation for both local and cloud Ollama deployments.
- New Example Project: Adds a new example project (
contributing/hello_world_ollama_native/) demonstrating native Ollama usage with tool calling, including a sample agent withroll_dieandcheck_primefunctions. - Full Unit Test Suite: Includes a comprehensive unit test suite (
test_ollama.py) covering various aspects of the native Ollama integration, such as payload construction, tool schema mapping, inline JSON tool-call extraction, and error handling. - Validation and Comparison: Features side-by-side comparison code demonstrating the native Ollama backend's successful tool-calling capabilities with cloud models, contrasting it with LiteLLM's failures in the same scenarios.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in pull request comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
[^1]: Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.
Response from ADK Triaging Agent
Hello @ayman3000, thank you for this significant contribution!
Before we can proceed with the review, could you please sign the Contributor License Agreement (CLA)? It seems the cla/google check has failed. You can find instructions on how to sign it at https://cla.developers.google.com/.
This will help us to move forward with your PR. Thanks!
Thanks for the review!
Iβve applied all requested fixes, updated the Ollama integration, and updated the unit tests accordingly.
All tests pass locally and the CLA is now signed.
Please let me know if you would like any additional adjustments.
Happy to iterate!
Hi @ayman3000, Thank you for your work on this pull request. We appreciate the effort you've invested. Can you please fix the failing unit tests and lint errors before we can proceed with the review.
i found a issue: Object of type Content is not JSON serializable
at ollama_llm.py line 135
# System instruction β first system message.
if llm_request.config.system_instruction:
messages.append(
{
"role": "system",
"content": llm_request.config.system_instruction,
}
)
changed to:
# System instruction β first system message.
if llm_request.config.system_instruction:
messages.append(
{
"role": "system",
"content": self._content_to_text(llm_request.config.system_instruction),
}
)
All checks are now passing βοΈ
The issue with Content not JSON serializable is fixed.
Code is formatted and imports sorted.
Waiting for workflow approval and code review approval from the maintainers.
Thanks β hope the ADK team accepts it!
Hi @ayman3000 , pls fix the failing tests
Hi, could someone please approve the pending workflow runs so that the tests run? I need the results to fix the failing unit tests. Thank you!