Commit 1ba3b9c

mo khan <mo@mokhan.ca>
2026-08-28 18:06:14
fix: make ollama think and keep_alive opt-in
Defaulting think to "medium" and keep_alive to "5m" and always sending them broke non-thinking models and silently overrode a server's OLLAMA_KEEP_ALIVE. Default both to nil so they are omitted unless set, and expose them via OLLAMA_THINK / OLLAMA_KEEP_ALIVE. Claude-Session: https://claude.ai/code/session_01Y7dRDoM8i3PJt6BcBcyxqo
Changed files (3)
lib
elelem
spec
elelem
lib/elelem/net/ollama.rb
@@ -6,8 +6,8 @@ module Elelem
       def initialize(
         model:,
         host: "localhost:11434",
-        think: "medium",
-        keep_alive: "5m",
+        think: nil,
+        keep_alive: nil,
         options: {},
         params: {},
         http: Elelem::Net.http
@@ -39,68 +39,8 @@ module Elelem
         "#{base}/api/chat"
       end
 
-      # POST /api/chat request body. Anything left unset uses the server or default.
-=begin
-
-  | Field              | Type                  | Notes                                                 |
-  | ---                | ---                   | ---                                                   |
-  | model              | string                │ required                                              │
-  | messages           | array                 │ see below                                             │
-  | tools              | array                 │ JSON tool schemas                                     │
-  | stream             | bool                  │ NDJSON stream when true                               │
-  | think              | bool or string        │ thinking models; "low"/"medium"/"high"                │
-  | format             | "json" or JSON schema │ structured output                                     │
-  | options            | object                │ model params, see below                               │
-  | keep_alive         | duration              │ how long model stays resident, e.g. "5m", 0 to unload │
-  | truncate           | bool                  │ truncate prompt to fit context                        │
-  | shift              | bool                  │ shift context window instead of erroring when full    │
-  | logprobs           | bool                  │ return token logprobs                                 │
-  | top_logprobs       | int                   │ how many alternatives per token                       │
-  | _debug_render_only | bool                  │ return rendered prompt without inference              │
-
-  Message object
-
-  | Field | Description |
-  | ---- | --------- |
-  | role | (system|user|assistant|tool) |
-  | content | |
-  | thinking | |
-  | images | (base64 array, multimodal) |
-  | tool_calls | |
-  | tool_name | name of the tool that produced a tool message |
-
-  Options
-
-    Sampling:
-
-    | Field | Description |
-    | ---- | ---- |
-    | seed | |
-    | temperature | |
-    | top_k | |
-    | top_p | |
-    | min_p | |
-    | typical_p | |
-    | num_predict | |
-    | num_keep | |
-    | stop (array) | |
-    | repeat_last_n | |
-    | repeat_penalty | |
-    | presence_penalty | |
-    | frequency_penalty | |
-
-    Runner:
-
-    | Field | Description |
-    | ----- | ----------- |
-    | num_ctx | |
-    | num_batch | |
-    | num_gpu | |
-    | main_gpu | |
-    | use_mmap | |
-    | num_thread | |
-    | draft_num_predict | |
-=end
+      # POST /api/chat request body. Anything left unset uses the server default.
+      # See https://github.com/ollama/ollama/blob/main/docs/api.md for all fields.
       def build_request_body(messages, tools)
         {
           model: @model,
lib/elelem/plugins/ollama.rb
@@ -1,8 +1,13 @@
 # frozen_string_literal: true
 
 Elelem::Providers.register(:ollama) do
+  # OLLAMA_THINK: "true"/"false" toggle thinking, or a level like "low"/"medium"/"high".
+  think = { "true" => true, "false" => false }.fetch(ENV["OLLAMA_THINK"], ENV["OLLAMA_THINK"])
+
   Elelem::Net::Ollama.new(
     model: ENV.fetch("OLLAMA_MODEL", "gpt-oss:latest"),
-    host: ENV.fetch("OLLAMA_HOST", "localhost:11434")
+    host: ENV.fetch("OLLAMA_HOST", "localhost:11434"),
+    think:,
+    keep_alive: ENV["OLLAMA_KEEP_ALIVE"]
   )
 end
spec/elelem/net/ollama_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe Elelem::Net::Ollama do
     it "sends only model, messages and stream by default" do
       client.fetch(messages) { }
 
-      expect(body).to eq(model: "gpt-oss:latest", messages:, stream: true, think: "medium", keep_alive: "5m")
+      expect(body).to eq(model: "gpt-oss:latest", messages:, stream: true)
     end
 
     it "sends tools when present" do