# elelem-ollama

> Connects elelem to a running Ollama server through its native /api/chat endpoint, with streaming, tool calls, and thinking output.

Maturity: ready. Install: `gem install elelem-ollama`. Source: https://src.mokhan.ca/elelem/ollama/


`elelem-ollama` connects elelem to [Ollama](https://ollama.com). It
registers the `ollama` provider, which talks to Ollama's own `/api/chat`
endpoint. Use it to run open models on your machine, or on another machine
on your network, with Ollama managing downloads and GPU memory.

## Install

```bash
gem install elelem elelem-builtins elelem-ollama
```

`elelem-builtins` is optional but gives the agent its default tools.
Requires Ruby 4.0. Install Ollama separately and pull a model that
supports tool calls:

```bash
ollama pull gpt-oss
```

## Configure

With Ollama on `localhost:11434` and `gpt-oss:latest` pulled, there is
nothing to set. Otherwise:

```bash
export OLLAMA_HOST=gpu-box.local:11434
export OLLAMA_MODEL=qwen3:32b
```

`OLLAMA_HOST` may include a scheme, so `https://ollama.example.com` works.
`--model` overrides `OLLAMA_MODEL`.

`OLLAMA_THINK` and `OLLAMA_KEEP_ALIVE` are passed to Ollama as strings,
unchanged. Ollama decides what values it accepts; for `think`, models such
as gpt-oss take `low`, `medium`, or `high`.

## Use

```bash
elelem -p ollama
elelem -p ollama --model qwen3:32b
OLLAMA_THINK=high elelem -p ollama
```

The gem also installs `elelem-ollama`, which is `elelem` with `ollama` as
the default provider:

```bash
elelem-ollama chat
```

Unlike `elelem`, `elelem-ollama` does not load `elelem-builtins`, so the
agent has no tools unless a plugin file in `~/.agents/plugins` adds them.

## How it works

Each turn is one `POST` to `/api/chat` with `stream: true`, made with
`Net::HTTP`. The read timeout is 3600 seconds and the open timeout is 10.
Empty or unset fields (`tools`, `think`, `keep_alive`, `options`) are left
out of the request, so with defaults the body holds only `model`,
`messages`, and `stream`.

Ollama identifies tool results by tool name rather than call ID. The
provider rewrites the history to match: assistant tool calls become
`{function: {name, arguments}}`, and each tool result gets the matching
`tool_name` in place of `tool_call_id`.

Ollama streams newline-delimited JSON. Each line's `message.content` adds
to the reply and `message.thinking` is printed as thinking. Tool calls
arrive whole, with arguments already parsed. elelem prints thinking as it
arrives and the reply once the turn is done.

## Limitations

- The provider accepts `options` (such as `temperature` or `num_ctx`) and
  extra request fields in Ruby, but nothing sets them from the command
  line or environment. Configure those in the Ollama model instead.
- Any non-2xx response raises `HTTP CODE: BODY`. There are no retries.
- Tool calls depend on the model. Pick one that Ollama lists with tool
  support.

## Development

```bash
git clone https://git.mokhan.ca/elelem/ollama.git
cd ollama
bin/setup
bin/test
bin/lint
```

The spec injects a fake HTTP adapter, so the tests make no network calls.


## Environment

| Variable | Default | Description |
|---|---|---|
| `OLLAMA_HOST` | `localhost:11434` | Ollama server address. http:// is added when no scheme is given. |
| `OLLAMA_MODEL` | `gpt-oss:latest` | Model to use when --model is not given. |
| `OLLAMA_THINK` | none | Sent as the think field when set. Unset means the field is omitted. |
| `OLLAMA_KEEP_ALIVE` | none | Sent as the keep_alive field when set, for example 10m. Unset means the field is omitted. |

Canonical: https://elelem.sh/plugins/ollama/

