# Ollama-Think Library
A thin wrapper around the [ollama-python](https://github.com/ollama/ollama-python) library with the addition of caching, increased `think` model compatibility and a little syntax sugar.
## Features
- **Caching**: Automatically caches responses to significantly speed up repeated requests.
- **Thinking**: Enables some officially unsupported models to use thinking mode. [Why hack?](why_hack.md)
- **Streaming and Non-streaming**: Separates the underlying streaming and non-streaming interface to provide clean type hints.
- **Syntax Sugar**: Less boiler-plate, so that you can maintain your flow.
## Quickstart
Get up and running in less than a minute.
**1. Install the library:**
```bash
pip install ollama-think
```
**2. Use:**
```python
from ollama_think import Client
# Initialize the client
client = Client(host="http://localhost:11434", cache_dir=".ollama_cache", clear_cache=False)
# unpack the response into thinking and content
thinking, content = client.call(
model="qwen3", # or any other model
prompt="Why is the sky blue?", # shortcut for messages=[{'role': 'user', 'content': 'Why is the sky blue?'}]
think=True # Set to True to see the model's thinking process
)
print(f"Thinking: {thinking}, Content: {content}")
```
## Detailed Usage
### Non-streaming
The `call` method provides strongly typed access to the underlying `Chat` method in non-streaming mode. It returns a `ThinkResponse` object which is a subclass of `ollama.ChatResponse` and adds some convenience properties. You can use `prompt` or `messages` as you prefer.
```python
from ollama_think import Client
client = Client()
# Make a non-streaming call
response: ThinkResponse = client.call(
model="qwen3", # The model to use
prompt="Hello, world!" # A single user message
messages = None, # or a list of messages
tools = None, # A list of tools available
think = True, # Enable thinking mode
format = None, # The format to return a response in: None | 'json' | your_obj.model_json_schema()
options = None, # Additional model parameter dict, such as {'temperature': 0.1, 'num_ctx': 8192}
keep_alive = None, # Controls how long the model will stay loaded in memory following the request.
use_cache = True) # If True, attempts to retrieve the response from cache.
# The response object contains all the original data from the Ollama ChatResponse
print(response)
# ThinkResponse(
# model='qwen3',
# created_at='2025-07-03T14:16:05.8452406Z',
# done=True,
# done_reason='stop',
# total_duration=2461619200,
# load_duration=2111438400,
# prompt_eval_count=20,
# prompt_eval_duration=78409600,
# eval_count=16,
# eval_duration=271104600,
# message=Message(role='assistant', content='Hello, world! How can I assist you today?', thinking='...',
# images=None, tool_calls=None))
# For convenience, you can access the content and thinking as properties
print(response.thinking)
# '...'
print(response.content)
# 'Hello, world! ...'
# The response object can be used as a string which will show just the 'content'
print(f"The model said: {response}") # same as response.content
# The model said: Hello, world! ...
# or unpack the response into thinking and content for single line access
thinking, content = response
print(f"Thinking: {thinking}, Content: {content}")
```
### Streaming
The `stream` method provides a strongly typed access to the underlying `Chat` method in streaming mode. It returns a an iterator of `ThinkResponse` chunks
```python
from ollama_think import Client
client = Client()
stream = client.stream(model="qwen3", prompt="Tell me a short story about italian chimpanzees and bananas", think=True)
for thinking, content in stream:
print(thinking, end="")
print(content, end="") # empty until thinking is finished for most models
```
### Thinking Mode
The `think` parameter tells ollama to enable thinking for models that support this. For other models that use non-standard ways of enabling thinking we do the neccesary. [Why hack?](why_hack.md) Default config: [src/ollama_think/config.yaml](src/ollama_think/config.yaml) Results: [model_capabilities.md](model_capabilities.md)
Some models will think, even without 'enabling' thinking. This output is separated out of the `content` into `thinking`
Note: Not all models officially or unofficially support thinking. They will throw a `400` error if you try to enable thinking.
### Caching
The client automatically caches responses using the light-weight `DiskCache` library to avoid re-generating them for the same request. You can disable this behavior by setting `use_cache=False`.
```python
# This call will be cached
response1 = client.call(model="qwen3", prompt="Hello, world!") # 0.31 seconds
# This call will use the cached response
response2 = client.call(model="qwen3", prompt="Hello, world!") # 0.0001 seconds
# This call will not attempt to get from the cache and will not store the result
response3 = client.call(model="qwen3", prompt="Hello, world!", use_cache=False)
```
You can clear the cache by passing `clear_cache=True` when initializing the client:
```python
client = Client(clear_cache=True)
```
### Options
The `options` parameter of the underlying `chat` method can be used to change how the model
responds. The most commonly used parameters are
- `temperature` Low values keep the model deterministic, Higher values for more creativity Typically 0.1 -> 1.0
- `num_ctx` Ollama has a default context length of 2048, which can be increased if you have enough VRAM. If you send in more
than `num_ctx` tokens, ollama will silently truncate your message, which can lead to lost instructions.
```python
from ollama_think import Client
client = Client()
prompt="Describe the earth to an alien who has just arrived."
options={'num_ctx': 8192, 'temperature': 0.9}
print("Using prompt:", prompt)
print("Using options:", options)
thinking, content = client.call(model="qwen3", prompt=prompt, think=True, options=options)
print(f"Thinking: {thinking}, Content: {content}")
```
See [examples/options_example.py](examples/options_example.py) for a full list of options
### Tool Calling
Before, and underneath the concept of MCP servers are the humble tool_calls. By telling the model that you have a tool available,
the model can choose to reply with a special format that indicates that it wants to call a tool. Typically, this call is
intercepted, the tool is excecuted and the result sent back to the model. The model's second response can then be shown to a user.
See [examples/tool_calling_example.py](examples/tool_calling_example.py)
### Response Formats
Forcing JSON format can encourage some models to behave. It is usualy a good idea to mention JSON in the prompt.
```python
from ollama_think import Client
import json
client = Client()
text_json = client.call(
model="qwen3",
prompt="Design a json representation of a spiral galaxy",
format="json",
).content
my_object = json.loads(text_json) # might explode if invalid json was returned
```
You can use pydantic models to describe more exactly the format you want.
```python
from ollama_think import Client
from pydantic import BaseModel, Field
client = Client()
class Heat(BaseModel):
"""A specially crafted response object to capture an iterpretation of heat"""
reaoning: str = Field(..., description="your reasoning for the response")
average_temperature: float = Field(..., description="average temperature")
text_obj = client.call(model="qwen3", prompt="How hot is the world?",
format=Heat.model_json_schema()).content
my_obj = Heat.model_validate_json(text_obj) # might explode it the format is invalid
```
See [examples/response_format_example.py](examples/response_format_example.py)
### Access to the underlying ollama client
Since the `ollama_think` is a thin wrapper around the `ollama.client`, you can still access the all the underlying ollama client methods.
```python
from ollama_think import Client
from ollama import ChatResponse
client = Client()
response: ChatResponse = client.chat(model='llama3.2', messages=[
{
'role': 'user',
'content': 'Why is the sky blue?',
},
])
print(response['message']['content'])
```
### Prompts and Messages
```python
from ollama_think import Client
client = Client()
# the prompt parameter in `call` and `stream` is just a shortcut for
prompt = 'Why is the sky blue?'
message = {'role': 'user', 'content': prompt}
client.call(model='llama3.2', messages=[message]) # shortcut
client.call(model='llama3.2', prompt=prompt) # same thing
```
## Credit to
- ollama [https://ollama.com/](https://ollama.com/)
- ollama-python [https://github.com/ollama/ollama-python](https://github.com/ollama/ollama-python)
- diskcache [https://github.com/grantjenks/python-diskcache/](https://github.com/grantjenks/python-diskcache/)
- pydantic [https://pydantic-docs.helpmanual.io/](https://pydantic-docs.helpmanual.io/)
## Reference docs
- Ollama Thinking - [https://ollama.com/blog/thinking](https://ollama.com/blog/thinking)
- Ollama Tool support - [https://ollama.com/blog/tool-support](https://ollama.com/blog/tool-support)
- Ollama Structured Outputs - [https://ollama.com/blog/structured-outputs](https://ollama.com/blog/structured-outputs)
- Ollama Options - [https://github.com/ollama/ollama-python/blob/main/ollama/_types.py](https://github.com/ollama/ollama-python/blob/main/ollama/_types.py)
## Contributing
Contributions are welcome! Please open an issue or submit a pull request.
### Development Setup
This project uses `uv` for package management and `hatch` for task running.
1. **Clone the repository:**
```bash
git clone https://github.com/your-username/ollama-think.git
cd ollama-think
```
2. **Create a virtual environment and install dependencies:**
This command creates a virtual environment in `.venv` and installs all dependencies, including development tools.
```bash
uv sync --extra dev
```
### Running Checks
- **Linting and Formatting:**
To automatically format and lint the code, run:
```bash
uv run ruff format .
uv run ruff check . --fix
```
- **Running Tests:**
- To run the default (fast) unit tests:
```bash
uv run hatch test
# or more simply
uv run pytest
```
- To run the full test suite, including `slow` integration tests that require a running Ollama instance:
```bash
uv run hatch test:run -m "slow or not slow"
```
- To pass a custom host to the integration tests:
```bash
uv run hatch test:run -m "slow or not slow" --host http://localhost:11434
```
- **Testing new models:**
```python
# edit /src/ollama_think/config.yaml
# check the output from non-streaming and streaming
uv run ./tests/test_hacks.py --host http://localhost:11434 --model "model_name"
# check that this makes a difference
uv run pytest ./tests/test_model_capabilities.py --host http://localhost:11434 -m "slow" --model "model_name"
# re-generate doc
uv run tests/generate_model_capabilities_report.py
# submit a PR
```
## License
This project is licensed under the MIT License.
Raw data
{
"_id": null,
"home_page": null,
"name": "ollama-think",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "AI, LLM, cogito, compatibility, granite, ollama, phi4-mini-reasoning, phi4-reasoning, think",
"author": null,
"author_email": "Chris Kilner <chris@rhiza.fr>",
"download_url": "https://files.pythonhosted.org/packages/1b/41/3e9912eedc811673ae607666a8ea7e71db934e3c1617977e690b7aaa6692/ollama_think-0.1.4.tar.gz",
"platform": null,
"description": "# Ollama-Think Library\n\nA thin wrapper around the [ollama-python](https://github.com/ollama/ollama-python) library with the addition of caching, increased `think` model compatibility and a little syntax sugar.\n\n\n## Features\n\n- **Caching**: Automatically caches responses to significantly speed up repeated requests.\n- **Thinking**: Enables some officially unsupported models to use thinking mode. [Why hack?](why_hack.md)\n- **Streaming and Non-streaming**: Separates the underlying streaming and non-streaming interface to provide clean type hints.\n- **Syntax Sugar**: Less boiler-plate, so that you can maintain your flow.\n\n## Quickstart\n\nGet up and running in less than a minute.\n\n**1. Install the library:**\n\n```bash\npip install ollama-think\n```\n\n**2. Use:**\n\n```python\nfrom ollama_think import Client\n\n# Initialize the client\nclient = Client(host=\"http://localhost:11434\", cache_dir=\".ollama_cache\", clear_cache=False)\n\n# unpack the response into thinking and content\nthinking, content = client.call(\n model=\"qwen3\", # or any other model\n prompt=\"Why is the sky blue?\", # shortcut for messages=[{'role': 'user', 'content': 'Why is the sky blue?'}]\n think=True # Set to True to see the model's thinking process\n)\n\nprint(f\"Thinking: {thinking}, Content: {content}\")\n```\n\n## Detailed Usage\n\n\n### Non-streaming\n\nThe `call` method provides strongly typed access to the underlying `Chat` method in non-streaming mode. It returns a `ThinkResponse` object which is a subclass of `ollama.ChatResponse` and adds some convenience properties. You can use `prompt` or `messages` as you prefer.\n\n```python\nfrom ollama_think import Client\nclient = Client()\n\n# Make a non-streaming call\nresponse: ThinkResponse = client.call(\n model=\"qwen3\", # The model to use\n prompt=\"Hello, world!\" # A single user message\n messages = None, # or a list of messages\n tools = None, # A list of tools available\n think = True, # Enable thinking mode\n format = None, # The format to return a response in: None | 'json' | your_obj.model_json_schema()\n options = None, # Additional model parameter dict, such as {'temperature': 0.1, 'num_ctx': 8192}\n keep_alive = None, # Controls how long the model will stay loaded in memory following the request.\n use_cache = True) # If True, attempts to retrieve the response from cache.\n\n# The response object contains all the original data from the Ollama ChatResponse\nprint(response)\n# ThinkResponse(\n# model='qwen3',\n# created_at='2025-07-03T14:16:05.8452406Z',\n# done=True,\n# done_reason='stop',\n# total_duration=2461619200,\n# load_duration=2111438400,\n# prompt_eval_count=20,\n# prompt_eval_duration=78409600,\n# eval_count=16,\n# eval_duration=271104600,\n# message=Message(role='assistant', content='Hello, world! How can I assist you today?', thinking='...',\n# images=None, tool_calls=None))\n\n# For convenience, you can access the content and thinking as properties\nprint(response.thinking)\n# '...'\nprint(response.content)\n# 'Hello, world! ...'\n\n# The response object can be used as a string which will show just the 'content'\nprint(f\"The model said: {response}\") # same as response.content\n# The model said: Hello, world! ...\n\n# or unpack the response into thinking and content for single line access\nthinking, content = response\nprint(f\"Thinking: {thinking}, Content: {content}\")\n```\n\n### Streaming\n\nThe `stream` method provides a strongly typed access to the underlying `Chat` method in streaming mode. It returns a an iterator of `ThinkResponse` chunks\n\n```python\nfrom ollama_think import Client\nclient = Client()\n\nstream = client.stream(model=\"qwen3\", prompt=\"Tell me a short story about italian chimpanzees and bananas\", think=True)\nfor thinking, content in stream:\n print(thinking, end=\"\")\n print(content, end=\"\") # empty until thinking is finished for most models\n```\n\n### Thinking Mode\n\nThe `think` parameter tells ollama to enable thinking for models that support this. For other models that use non-standard ways of enabling thinking we do the neccesary. [Why hack?](why_hack.md) Default config: [src/ollama_think/config.yaml](src/ollama_think/config.yaml) Results: [model_capabilities.md](model_capabilities.md)\n\nSome models will think, even without 'enabling' thinking. This output is separated out of the `content` into `thinking`\n\nNote: Not all models officially or unofficially support thinking. They will throw a `400` error if you try to enable thinking.\n\n\n### Caching\n\nThe client automatically caches responses using the light-weight `DiskCache` library to avoid re-generating them for the same request. You can disable this behavior by setting `use_cache=False`.\n\n```python\n# This call will be cached\nresponse1 = client.call(model=\"qwen3\", prompt=\"Hello, world!\") # 0.31 seconds\n\n# This call will use the cached response\nresponse2 = client.call(model=\"qwen3\", prompt=\"Hello, world!\") # 0.0001 seconds\n\n# This call will not attempt to get from the cache and will not store the result\nresponse3 = client.call(model=\"qwen3\", prompt=\"Hello, world!\", use_cache=False)\n```\n\nYou can clear the cache by passing `clear_cache=True` when initializing the client:\n\n```python\nclient = Client(clear_cache=True)\n```\n\n### Options\n\nThe `options` parameter of the underlying `chat` method can be used to change how the model\nresponds. The most commonly used parameters are\n\n- `temperature` Low values keep the model deterministic, Higher values for more creativity Typically 0.1 -> 1.0\n- `num_ctx` Ollama has a default context length of 2048, which can be increased if you have enough VRAM. If you send in more\nthan `num_ctx` tokens, ollama will silently truncate your message, which can lead to lost instructions.\n\n```python\nfrom ollama_think import Client\nclient = Client()\n\nprompt=\"Describe the earth to an alien who has just arrived.\"\noptions={'num_ctx': 8192, 'temperature': 0.9}\n\nprint(\"Using prompt:\", prompt)\nprint(\"Using options:\", options)\n\nthinking, content = client.call(model=\"qwen3\", prompt=prompt, think=True, options=options)\nprint(f\"Thinking: {thinking}, Content: {content}\")\n```\n\nSee [examples/options_example.py](examples/options_example.py) for a full list of options\n\n### Tool Calling\n\nBefore, and underneath the concept of MCP servers are the humble tool_calls. By telling the model that you have a tool available,\nthe model can choose to reply with a special format that indicates that it wants to call a tool. Typically, this call is\nintercepted, the tool is excecuted and the result sent back to the model. The model's second response can then be shown to a user.\n\nSee [examples/tool_calling_example.py](examples/tool_calling_example.py)\n\n### Response Formats\n\nForcing JSON format can encourage some models to behave. It is usualy a good idea to mention JSON in the prompt.\n\n```python\nfrom ollama_think import Client\nimport json\n\nclient = Client()\n\ntext_json = client.call(\n model=\"qwen3\",\n prompt=\"Design a json representation of a spiral galaxy\",\n format=\"json\",\n).content\n\nmy_object = json.loads(text_json) # might explode if invalid json was returned\n```\n\nYou can use pydantic models to describe more exactly the format you want.\n\n```python\nfrom ollama_think import Client\nfrom pydantic import BaseModel, Field\nclient = Client()\n\nclass Heat(BaseModel):\n \"\"\"A specially crafted response object to capture an iterpretation of heat\"\"\"\n reaoning: str = Field(..., description=\"your reasoning for the response\")\n average_temperature: float = Field(..., description=\"average temperature\")\n\ntext_obj = client.call(model=\"qwen3\", prompt=\"How hot is the world?\",\n format=Heat.model_json_schema()).content\n\nmy_obj = Heat.model_validate_json(text_obj) # might explode it the format is invalid\n```\n\nSee [examples/response_format_example.py](examples/response_format_example.py)\n\n### Access to the underlying ollama client\n\nSince the `ollama_think` is a thin wrapper around the `ollama.client`, you can still access the all the underlying ollama client methods.\n\n```python\nfrom ollama_think import Client\nfrom ollama import ChatResponse\n\nclient = Client()\nresponse: ChatResponse = client.chat(model='llama3.2', messages=[\n {\n 'role': 'user',\n 'content': 'Why is the sky blue?',\n },\n])\nprint(response['message']['content'])\n```\n\n### Prompts and Messages\n\n```python\nfrom ollama_think import Client\n\nclient = Client()\n# the prompt parameter in `call` and `stream` is just a shortcut for\nprompt = 'Why is the sky blue?'\nmessage = {'role': 'user', 'content': prompt}\nclient.call(model='llama3.2', messages=[message]) # shortcut\nclient.call(model='llama3.2', prompt=prompt) # same thing\n```\n\n## Credit to\n\n- ollama [https://ollama.com/](https://ollama.com/)\n- ollama-python [https://github.com/ollama/ollama-python](https://github.com/ollama/ollama-python)\n- diskcache [https://github.com/grantjenks/python-diskcache/](https://github.com/grantjenks/python-diskcache/)\n- pydantic [https://pydantic-docs.helpmanual.io/](https://pydantic-docs.helpmanual.io/)\n\n## Reference docs\n\n- Ollama Thinking - [https://ollama.com/blog/thinking](https://ollama.com/blog/thinking)\n- Ollama Tool support - [https://ollama.com/blog/tool-support](https://ollama.com/blog/tool-support)\n- Ollama Structured Outputs - [https://ollama.com/blog/structured-outputs](https://ollama.com/blog/structured-outputs)\n- Ollama Options - [https://github.com/ollama/ollama-python/blob/main/ollama/_types.py](https://github.com/ollama/ollama-python/blob/main/ollama/_types.py)\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n### Development Setup\n\nThis project uses `uv` for package management and `hatch` for task running.\n\n1. **Clone the repository:**\n ```bash\n git clone https://github.com/your-username/ollama-think.git\n cd ollama-think\n ```\n\n2. **Create a virtual environment and install dependencies:**\n This command creates a virtual environment in `.venv` and installs all dependencies, including development tools.\n ```bash\n uv sync --extra dev\n ```\n\n### Running Checks\n\n- **Linting and Formatting:**\n To automatically format and lint the code, run:\n ```bash\n uv run ruff format .\n uv run ruff check . --fix\n ```\n\n- **Running Tests:**\n - To run the default (fast) unit tests:\n ```bash\n uv run hatch test\n # or more simply\n uv run pytest\n ```\n - To run the full test suite, including `slow` integration tests that require a running Ollama instance:\n ```bash\n uv run hatch test:run -m \"slow or not slow\"\n ```\n - To pass a custom host to the integration tests:\n ```bash\n uv run hatch test:run -m \"slow or not slow\" --host http://localhost:11434\n ```\n\n\n- **Testing new models:**\n\n ```python\n # edit /src/ollama_think/config.yaml\n # check the output from non-streaming and streaming\n uv run ./tests/test_hacks.py --host http://localhost:11434 --model \"model_name\"\n\n # check that this makes a difference\n uv run pytest ./tests/test_model_capabilities.py --host http://localhost:11434 -m \"slow\" --model \"model_name\"\n\n # re-generate doc\n uv run tests/generate_model_capabilities_report.py\n\n # submit a PR\n ```\n \n## License\n\nThis project is licensed under the MIT License.\n",
"bugtrack_url": null,
"license": null,
"summary": "A light wrapper around ollama-python that introduces caching, syntax sugar and increased `think` compatibility",
"version": "0.1.4",
"project_urls": {
"Bug Tracker": "https://github.com/rhiza-fr/ollama-think/issues",
"Homepage": "https://github.com/rhiza-fr/ollama-think"
},
"split_keywords": [
"ai",
" llm",
" cogito",
" compatibility",
" granite",
" ollama",
" phi4-mini-reasoning",
" phi4-reasoning",
" think"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "693ad29a3a273bffb0b86cbbb24f2a77272e27b034fc8ebc074c18c82863bc69",
"md5": "e0736ac591a40d7aad3ec29fc9279426",
"sha256": "610cfd15c27ec54f19f717035f0ec67885537b575566c2bcfe4785f4995fc241"
},
"downloads": -1,
"filename": "ollama_think-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e0736ac591a40d7aad3ec29fc9279426",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 18907,
"upload_time": "2025-07-09T08:26:51",
"upload_time_iso_8601": "2025-07-09T08:26:51.586071Z",
"url": "https://files.pythonhosted.org/packages/69/3a/d29a3a273bffb0b86cbbb24f2a77272e27b034fc8ebc074c18c82863bc69/ollama_think-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1b413e9912eedc811673ae607666a8ea7e71db934e3c1617977e690b7aaa6692",
"md5": "dac3e80d4fda3264b132301fc318359f",
"sha256": "e19ff01aaba4035008b626d17d040b3c720f06e099acb247ef25f71f032d8858"
},
"downloads": -1,
"filename": "ollama_think-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "dac3e80d4fda3264b132301fc318359f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 98676,
"upload_time": "2025-07-09T08:26:53",
"upload_time_iso_8601": "2025-07-09T08:26:53.231445Z",
"url": "https://files.pythonhosted.org/packages/1b/41/3e9912eedc811673ae607666a8ea7e71db934e3c1617977e690b7aaa6692/ollama_think-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-09 08:26:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rhiza-fr",
"github_project": "ollama-think",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "annotated-types",
"specs": [
[
"==",
"0.7.0"
]
]
},
{
"name": "anyio",
"specs": [
[
"==",
"4.9.0"
]
]
},
{
"name": "certifi",
"specs": [
[
"==",
"2025.6.15"
]
]
},
{
"name": "click",
"specs": [
[
"==",
"8.2.1"
]
]
},
{
"name": "colorama",
"specs": [
[
"==",
"0.4.6"
]
]
},
{
"name": "coverage",
"specs": [
[
"==",
"7.9.2"
]
]
},
{
"name": "diskcache",
"specs": [
[
"==",
"5.6.3"
]
]
},
{
"name": "h11",
"specs": [
[
"==",
"0.16.0"
]
]
},
{
"name": "httpcore",
"specs": [
[
"==",
"1.0.9"
]
]
},
{
"name": "httpx",
"specs": [
[
"==",
"0.28.1"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.10"
]
]
},
{
"name": "iniconfig",
"specs": [
[
"==",
"2.1.0"
]
]
},
{
"name": "markdown-it-py",
"specs": [
[
"==",
"3.0.0"
]
]
},
{
"name": "mdurl",
"specs": [
[
"==",
"0.1.2"
]
]
},
{
"name": "ollama",
"specs": [
[
"==",
"0.5.1"
]
]
},
{
"name": "packaging",
"specs": [
[
"==",
"25.0"
]
]
},
{
"name": "pluggy",
"specs": [
[
"==",
"1.6.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
"==",
"2.11.7"
]
]
},
{
"name": "pydantic-core",
"specs": [
[
"==",
"2.33.2"
]
]
},
{
"name": "pygments",
"specs": [
[
"==",
"2.19.2"
]
]
},
{
"name": "pytest",
"specs": [
[
"==",
"8.4.1"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
"==",
"6.2.1"
]
]
},
{
"name": "pytest-mock",
"specs": [
[
"==",
"3.14.1"
]
]
},
{
"name": "pyyaml",
"specs": [
[
"==",
"6.0.2"
]
]
},
{
"name": "rich",
"specs": [
[
"==",
"14.0.0"
]
]
},
{
"name": "ruff",
"specs": [
[
"==",
"0.12.2"
]
]
},
{
"name": "shellingham",
"specs": [
[
"==",
"1.5.4"
]
]
},
{
"name": "sniffio",
"specs": [
[
"==",
"1.3.1"
]
]
},
{
"name": "typer",
"specs": [
[
"==",
"0.16.0"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
"==",
"4.14.1"
]
]
},
{
"name": "typing-inspection",
"specs": [
[
"==",
"0.4.1"
]
]
}
],
"lcname": "ollama-think"
}