[PR #234] [CLOSED] Add Tool Registry Feature #426

Closed
opened 2026-02-15 16:30:22 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/ollama/ollama-python/pull/234
Author: @synacktraa
Created: 7/26/2024
Status: Closed

Base: mainHead: main


📝 Commits (3)

  • dc2acd6 Add tool registry for tool-calling automation
  • e9b8aab remove ipykernel dev dependency
  • 637f9a9 remove pydantic dependency

📊 Changes

9 files changed (+951 additions, -53 deletions)

View changed files

📝 README.md (+95 -0)
📝 examples/tools/main.py (+54 -43)
📝 ollama/__init__.py (+5 -0)
📝 ollama/_types.py (+4 -4)
ollama/tool_calling/__init__.py (+171 -0)
ollama/tool_calling/_utils.py (+461 -0)
📝 poetry.lock (+16 -5)
📝 pyproject.toml (+1 -0)
📝 tests/test_client.py (+144 -1)

📄 Description

Description

This PR introduces a new ToolRegistry class to the Ollama library. The Tool Registry is designed to manage various tools, including functions (both synchronous and asynchronous), pydantic.BaseModel, typing.TypedDict, and typing.NamedTuple. It provides functionality to generate schemas for these tools, which are essential for LLM tool-calling, and allows for the invocation of tools using their metadata.

Features

  • Create and manage a registry of tools
  • Support for multiple tool types: functions, pydantic models, TypedDict, and NamedTuple
  • Generate schemas for registered tools
  • Invoke tools using their metadata (name & raw arguments) -- Handles almost all edge cases
  • Option to override existing tools with the same name

Changes I've made:

  • Added a new directory tool_calling which stores all functionality of tool registry.
  • Added unit tests to cover all major functionality of the ToolRegistry class. (All tests passed)
  • Updated _types.py
  • Updated tools example in examples directory

How to use this functionality?

Creating a tool registry

import ollama

registry = ollama.ToolRegistry()

Adding tools to the registry instance

import json
import asyncio
from typing import Literal, TypedDict

registry = ollama.ToolRegistry()

@registry.register
def get_flight_times(departure: str, arrival: str) -> str:
  """
  Get flight times.
  :param departure: Departure location code
  :param arrival: Arrival location code
  """
  flights = {
    'NYC-LAX': {'departure': '08:00 AM', 'arrival': '11:30 AM', 'duration': '5h 30m'},
    'LAX-NYC': {'departure': '02:00 PM', 'arrival': '10:30 PM', 'duration': '5h 30m'},
    'LHR-JFK': {'departure': '10:00 AM', 'arrival': '01:00 PM', 'duration': '8h 00m'},
    'JFK-LHR': {'departure': '09:00 PM', 'arrival': '09:00 AM', 'duration': '7h 00m'},
    'CDG-DXB': {'departure': '11:00 AM', 'arrival': '08:00 PM', 'duration': '6h 00m'},
    'DXB-CDG': {'departure': '03:00 AM', 'arrival': '07:30 AM', 'duration': '7h 30m'},
  }

  key = f'{departure}-{arrival}'.upper()
  return json.dumps(flights.get(key, {'error': 'Flight not found'}))

@registry.register
class User(TypedDict): # It can also be `pydantic.BaseModel`, or `typing.NamedTuple`.
    """
    User Information
    :param name: Name of the user
    :param role: Role assigned to the user 
    """
    name: str
    role: Literal['admin', 'developer', 'tester']

"""
# Tools can also be registered using:
registry.register(get_flight_times)
registry.register(User)

# OR

registry.register_multiple(get_flight_times, User)
"""

Get tool schema list

tools = registry.tools
print(json.dumps(tools, indent=3))

Invoking the tool

res = ollama.chat(
    model='llama3-groq-tool-use:latest',
    tools=tools,
    messages=[{
        'role': 'user',
        'content': "What is the flight time from New York (NYC) to Los Angeles (LAX)?"
    }]
)
tool_call = res['message']['tool_calls'][0]['function']
print(f"{tool_call=}")
tool_output = registry.invoke(**tool_call)
print(f"{tool_output=}")
tool_call={'name': 'get_flight_times', 'arguments': {'arrival': 'LAX', 'departure': 'NYC'}}
tool_output='{"departure": "08:00 AM", "arrival": "11:30 AM", "duration": "5h 30m"}'

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/ollama/ollama-python/pull/234 **Author:** [@synacktraa](https://github.com/synacktraa) **Created:** 7/26/2024 **Status:** ❌ Closed **Base:** `main` ← **Head:** `main` --- ### 📝 Commits (3) - [`dc2acd6`](https://github.com/ollama/ollama-python/commit/dc2acd691b9f29ba4531ed3fb0f8896c2803e9ee) Add tool registry for tool-calling automation - [`e9b8aab`](https://github.com/ollama/ollama-python/commit/e9b8aab07d5249b85424a329bd22334cfdd5d32b) remove ipykernel dev dependency - [`637f9a9`](https://github.com/ollama/ollama-python/commit/637f9a9b702f279e4ea3a62363ec269f2714aa6c) remove pydantic dependency ### 📊 Changes **9 files changed** (+951 additions, -53 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+95 -0) 📝 `examples/tools/main.py` (+54 -43) 📝 `ollama/__init__.py` (+5 -0) 📝 `ollama/_types.py` (+4 -4) ➕ `ollama/tool_calling/__init__.py` (+171 -0) ➕ `ollama/tool_calling/_utils.py` (+461 -0) 📝 `poetry.lock` (+16 -5) 📝 `pyproject.toml` (+1 -0) 📝 `tests/test_client.py` (+144 -1) </details> ### 📄 Description ## Description This PR introduces a new `ToolRegistry` class to the Ollama library. The Tool Registry is designed to manage various tools, including functions (both synchronous and asynchronous), `pydantic.BaseModel`, `typing.TypedDict`, and `typing.NamedTuple`. It provides functionality to generate schemas for these tools, which are essential for LLM tool-calling, and allows for the invocation of tools using their metadata. ## Features - Create and manage a registry of tools - Support for multiple tool types: functions, pydantic models, TypedDict, and NamedTuple - Generate schemas for registered tools - Invoke tools using their metadata (name & raw arguments) -- Handles almost all edge cases - Option to override existing tools with the same name ## Changes I've made: - Added a new directory `tool_calling` which stores all functionality of tool registry. - Added unit tests to cover all major functionality of the `ToolRegistry` class. (All tests passed) - Updated _types.py - Updated tools example in examples directory ## How to use this functionality? ### Creating a tool registry ```python import ollama registry = ollama.ToolRegistry() ``` ### Adding tools to the registry instance ```python import json import asyncio from typing import Literal, TypedDict registry = ollama.ToolRegistry() @registry.register def get_flight_times(departure: str, arrival: str) -> str: """ Get flight times. :param departure: Departure location code :param arrival: Arrival location code """ flights = { 'NYC-LAX': {'departure': '08:00 AM', 'arrival': '11:30 AM', 'duration': '5h 30m'}, 'LAX-NYC': {'departure': '02:00 PM', 'arrival': '10:30 PM', 'duration': '5h 30m'}, 'LHR-JFK': {'departure': '10:00 AM', 'arrival': '01:00 PM', 'duration': '8h 00m'}, 'JFK-LHR': {'departure': '09:00 PM', 'arrival': '09:00 AM', 'duration': '7h 00m'}, 'CDG-DXB': {'departure': '11:00 AM', 'arrival': '08:00 PM', 'duration': '6h 00m'}, 'DXB-CDG': {'departure': '03:00 AM', 'arrival': '07:30 AM', 'duration': '7h 30m'}, } key = f'{departure}-{arrival}'.upper() return json.dumps(flights.get(key, {'error': 'Flight not found'})) @registry.register class User(TypedDict): # It can also be `pydantic.BaseModel`, or `typing.NamedTuple`. """ User Information :param name: Name of the user :param role: Role assigned to the user """ name: str role: Literal['admin', 'developer', 'tester'] """ # Tools can also be registered using: registry.register(get_flight_times) registry.register(User) # OR registry.register_multiple(get_flight_times, User) """ ``` ### Get tool schema list ```python tools = registry.tools print(json.dumps(tools, indent=3)) ``` ### Invoking the tool ```python res = ollama.chat( model='llama3-groq-tool-use:latest', tools=tools, messages=[{ 'role': 'user', 'content': "What is the flight time from New York (NYC) to Los Angeles (LAX)?" }] ) tool_call = res['message']['tool_calls'][0]['function'] print(f"{tool_call=}") tool_output = registry.invoke(**tool_call) print(f"{tool_output=}") ``` ``` tool_call={'name': 'get_flight_times', 'arguments': {'arrival': 'LAX', 'departure': 'NYC'}} tool_output='{"departure": "08:00 AM", "arrival": "11:30 AM", "duration": "5h 30m"}' ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 16:30:22 -05:00
yindo closed this issue 2026-02-15 16:30:22 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ollama/ollama-python#426