mirror of
https://github.com/ollama/ollama-python.git
synced 2026-06-11 18:54:47 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dd1d7cb02 | |||
| d3afa37b11 | |||
| cfbb0cef7b | |||
| 80279e95ab | |||
| 0ecfb1f6cf | |||
| 404672570f | |||
| 15ec61dbcb | |||
| 799ae1f07c | |||
| ae333084b9 | |||
| 1c6afe4316 | |||
| b9d435fad5 | |||
| 10955d52ee | |||
| 67f19a33e2 | |||
| 4d83af13d8 |
+12
-56
@@ -1,124 +1,80 @@
|
||||
# Running Examples
|
||||
|
||||
Run the examples in this directory with:
|
||||
|
||||
```sh
|
||||
# Run example
|
||||
python3 examples/<example>.py
|
||||
|
||||
# or with uv
|
||||
uv run examples/<example>.py
|
||||
```
|
||||
|
||||
See [ollama/docs/api.md](https://github.com/ollama/ollama/blob/main/docs/api.md) for full API documentation
|
||||
|
||||
### Chat - Chat with a model
|
||||
|
||||
- [chat.py](chat.py)
|
||||
- [async-chat.py](async-chat.py)
|
||||
- [chat-stream.py](chat-stream.py) - Streamed outputs
|
||||
- [chat-with-history.py](chat-with-history.py) - Chat with model and maintain history of the conversation
|
||||
|
||||
### Generate - Generate text with a model
|
||||
|
||||
### Generate - Generate text with a model
|
||||
- [generate.py](generate.py)
|
||||
- [async-generate.py](async-generate.py)
|
||||
- [generate-stream.py](generate-stream.py) - Streamed outputs
|
||||
- [fill-in-middle.py](fill-in-middle.py) - Given a prefix and suffix, fill in the middle
|
||||
|
||||
### Tools/Function Calling - Call a function with a model
|
||||
|
||||
### Tools/Function Calling - Call a function with a model
|
||||
- [tools.py](tools.py) - Simple example of Tools/Function Calling
|
||||
- [async-tools.py](async-tools.py)
|
||||
- [multi-tool.py](multi-tool.py) - Using multiple tools, with thinking enabled
|
||||
|
||||
#### gpt-oss
|
||||
|
||||
#### gpt-oss
|
||||
- [gpt-oss-tools.py](gpt-oss-tools.py)
|
||||
- [gpt-oss-tools-stream.py](gpt-oss-tools-stream.py)
|
||||
- [gpt-oss-tools-stream.py](gpt-oss-tools-stream.py)
|
||||
- [gpt-oss-tools-browser.py](gpt-oss-tools-browser.py) - Using browser research tools with gpt-oss
|
||||
- [gpt-oss-tools-browser-stream.py](gpt-oss-tools-browser-stream.py) - Using browser research tools with gpt-oss, with streaming enabled
|
||||
|
||||
### Web search
|
||||
|
||||
An API key from Ollama's cloud service is required. You can create one [here](https://ollama.com/settings/keys).
|
||||
|
||||
```shell
|
||||
export OLLAMA_API_KEY="your_api_key_here"
|
||||
```
|
||||
|
||||
- [web-search.py](web-search.py)
|
||||
|
||||
#### MCP server
|
||||
|
||||
The MCP server can be used with an MCP client like Cursor, Cline, Codex, Open WebUI, Goose, and more.
|
||||
|
||||
```sh
|
||||
uv run examples/web-search-mcp.py
|
||||
```
|
||||
|
||||
Configuration to use with an MCP client:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"web_search": {
|
||||
"type": "stdio",
|
||||
"command": "uv",
|
||||
"args": ["run", "path/to/ollama-python/examples/web-search-mcp.py"],
|
||||
"env": { "OLLAMA_API_KEY": "your_api_key_here" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [web-search-mcp.py](web-search-mcp.py)
|
||||
|
||||
### Multimodal with Images - Chat with a multimodal (image chat) model
|
||||
|
||||
- [multimodal-chat.py](multimodal-chat.py)
|
||||
- [multimodal-generate.py](multimodal-generate.py)
|
||||
|
||||
### Structured Outputs - Generate structured outputs with a model
|
||||
|
||||
### Structured Outputs - Generate structured outputs with a model
|
||||
- [structured-outputs.py](structured-outputs.py)
|
||||
- [async-structured-outputs.py](async-structured-outputs.py)
|
||||
- [structured-outputs-image.py](structured-outputs-image.py)
|
||||
|
||||
### Ollama List - List all downloaded models and their properties
|
||||
|
||||
### Ollama List - List all downloaded models and their properties
|
||||
- [list.py](list.py)
|
||||
|
||||
### Ollama Show - Display model properties and capabilities
|
||||
|
||||
### Ollama Show - Display model properties and capabilities
|
||||
- [show.py](show.py)
|
||||
|
||||
### Ollama ps - Show model status with CPU/GPU usage
|
||||
|
||||
### Ollama ps - Show model status with CPU/GPU usage
|
||||
- [ps.py](ps.py)
|
||||
|
||||
|
||||
### Ollama Pull - Pull a model from Ollama
|
||||
|
||||
Requirement: `pip install tqdm`
|
||||
- [pull.py](pull.py)
|
||||
|
||||
- [pull.py](pull.py)
|
||||
|
||||
### Ollama Create - Create a model from a Modelfile
|
||||
- [create.py](create.py)
|
||||
|
||||
- [create.py](create.py)
|
||||
|
||||
### Ollama Embed - Generate embeddings with a model
|
||||
|
||||
- [embed.py](embed.py)
|
||||
|
||||
### Thinking - Enable thinking mode for a model
|
||||
|
||||
### Thinking - Enable thinking mode for a model
|
||||
- [thinking.py](thinking.py)
|
||||
|
||||
### Thinking (generate) - Enable thinking mode for a model
|
||||
|
||||
- [thinking-generate.py](thinking-generate.py)
|
||||
|
||||
### Thinking (levels) - Choose the thinking level
|
||||
|
||||
- [thinking-levels.py](thinking-levels.py)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from gpt_oss_browser_tool_helper import Browser
|
||||
|
||||
from ollama import Client
|
||||
|
||||
|
||||
def main() -> None:
|
||||
client = Client()
|
||||
browser = Browser(initial_state=None, client=client)
|
||||
|
||||
browser_search_schema = {
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'browser.search',
|
||||
'parameters': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'query': {'type': 'string'},
|
||||
'topn': {'type': 'integer'},
|
||||
},
|
||||
'required': ['query'],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
browser_open_schema = {
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'browser.open',
|
||||
'parameters': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {'anyOf': [{'type': 'integer'}, {'type': 'string'}]},
|
||||
'cursor': {'type': 'integer'},
|
||||
'loc': {'type': 'integer'},
|
||||
'num_lines': {'type': 'integer'},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
browser_find_schema = {
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'browser.find',
|
||||
'parameters': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'pattern': {'type': 'string'},
|
||||
'cursor': {'type': 'integer'},
|
||||
},
|
||||
'required': ['pattern'],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
def browser_search(query: str, topn: int = 10) -> str:
|
||||
return browser.search(query=query, topn=topn)['pageText']
|
||||
|
||||
def browser_open(id: int | str | None = None, cursor: int = -1, loc: int = -1, num_lines: int = -1) -> str:
|
||||
return browser.open(id=id, cursor=cursor, loc=loc, num_lines=num_lines)['pageText']
|
||||
|
||||
def browser_find(pattern: str, cursor: int = -1, **_: Any) -> str:
|
||||
return browser.find(pattern=pattern, cursor=cursor)['pageText']
|
||||
|
||||
available_tools = {
|
||||
'browser.search': browser_search,
|
||||
'browser.open': browser_open,
|
||||
'browser.find': browser_find,
|
||||
}
|
||||
query = 'What is Ollama.com?'
|
||||
print('Prompt:', query, '\n')
|
||||
|
||||
messages: List[Dict[str, Any]] = [{'role': 'user', 'content': query}]
|
||||
|
||||
while True:
|
||||
resp = client.chat(
|
||||
model='gpt-oss',
|
||||
messages=messages,
|
||||
tools=[browser_search_schema, browser_open_schema, browser_find_schema],
|
||||
think=True,
|
||||
)
|
||||
|
||||
if resp.message.thinking:
|
||||
print('Thinking:\n========\n')
|
||||
print(resp.message.thinking + '\n')
|
||||
|
||||
if resp.message.content:
|
||||
print('Response:\n========\n')
|
||||
print(resp.message.content + '\n')
|
||||
|
||||
messages.append(resp.message)
|
||||
|
||||
if not resp.message.tool_calls:
|
||||
break
|
||||
|
||||
for tc in resp.message.tool_calls:
|
||||
tool_name = tc.function.name
|
||||
args = tc.function.arguments or {}
|
||||
fn = available_tools.get(tool_name)
|
||||
if not fn:
|
||||
messages.append({'role': 'tool', 'content': f'Tool {tool_name} not found', 'tool_name': tool_name})
|
||||
continue
|
||||
|
||||
try:
|
||||
result_text = fn(**args)
|
||||
except Exception as e:
|
||||
result_text = f'Error from {tool_name}: {e}'
|
||||
|
||||
messages.append({'role': 'tool', 'content': result_text, 'tool_name': tool_name})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,116 +0,0 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = [
|
||||
# "mcp",
|
||||
# "rich",
|
||||
# "ollama",
|
||||
# ]
|
||||
# ///
|
||||
"""
|
||||
MCP stdio server exposing Ollama web_search and web_fetch as tools.
|
||||
|
||||
Environment:
|
||||
- OLLAMA_API_KEY (required): if set, will be used as Authorization header.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import Any, Dict
|
||||
|
||||
from ollama import Client
|
||||
|
||||
try:
|
||||
# Preferred high-level API (if available)
|
||||
from mcp.server.fastmcp import FastMCP # type: ignore
|
||||
|
||||
_FASTMCP_AVAILABLE = True
|
||||
except Exception:
|
||||
_FASTMCP_AVAILABLE = False
|
||||
|
||||
if not _FASTMCP_AVAILABLE:
|
||||
# Fallback to the low-level stdio server API
|
||||
from mcp.server import Server # type: ignore
|
||||
from mcp.server.stdio import stdio_server # type: ignore
|
||||
|
||||
|
||||
client = Client()
|
||||
|
||||
|
||||
def _web_search_impl(query: str, max_results: int = 3) -> Dict[str, Any]:
|
||||
res = client.web_search(query=query, max_results=max_results)
|
||||
return res.model_dump()
|
||||
|
||||
|
||||
def _web_fetch_impl(url: str) -> Dict[str, Any]:
|
||||
res = client.web_fetch(url=url)
|
||||
return res.model_dump()
|
||||
|
||||
|
||||
if _FASTMCP_AVAILABLE:
|
||||
app = FastMCP('ollama-search-fetch')
|
||||
|
||||
@app.tool()
|
||||
def web_search(query: str, max_results: int = 3) -> Dict[str, Any]:
|
||||
"""
|
||||
Perform a web search using Ollama's hosted search API.
|
||||
|
||||
Args:
|
||||
query: The search query to run.
|
||||
max_results: Maximum results to return (default: 3).
|
||||
|
||||
Returns:
|
||||
JSON-serializable dict matching ollama.WebSearchResponse.model_dump()
|
||||
"""
|
||||
|
||||
return _web_search_impl(query=query, max_results=max_results)
|
||||
|
||||
@app.tool()
|
||||
def web_fetch(url: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Fetch the content of a web page for the provided URL.
|
||||
|
||||
Args:
|
||||
url: The absolute URL to fetch.
|
||||
|
||||
Returns:
|
||||
JSON-serializable dict matching ollama.WebFetchResponse.model_dump()
|
||||
"""
|
||||
|
||||
return _web_fetch_impl(url=url)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
|
||||
else:
|
||||
server = Server('ollama-search-fetch') # type: ignore[name-defined]
|
||||
|
||||
@server.tool() # type: ignore[attr-defined]
|
||||
async def web_search(query: str, max_results: int = 3) -> Dict[str, Any]:
|
||||
"""
|
||||
Perform a web search using Ollama's hosted search API.
|
||||
|
||||
Args:
|
||||
query: The search query to run.
|
||||
max_results: Maximum results to return (default: 3).
|
||||
"""
|
||||
|
||||
return await asyncio.to_thread(_web_search_impl, query, max_results)
|
||||
|
||||
@server.tool() # type: ignore[attr-defined]
|
||||
async def web_fetch(url: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Fetch the content of a web page for the provided URL.
|
||||
|
||||
Args:
|
||||
url: The absolute URL to fetch.
|
||||
"""
|
||||
|
||||
return await asyncio.to_thread(_web_fetch_impl, url)
|
||||
|
||||
async def _main() -> None:
|
||||
async with stdio_server() as (read, write): # type: ignore[name-defined]
|
||||
await server.run(read, write) # type: ignore[attr-defined]
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(_main())
|
||||
Reference in New Issue
Block a user